I WAS WORKING BY THE EXAMPLE YOU JUST GAVE ME AS DUPLICATE, READ THE ENTIRE POST, TY
I'm making a simple app with sliding menu by using the template provided by android studio. And I have to use fragments to switch between items of the sliding menu.
What I wanna do? (check app design at the bottom)
When I click on button pass data it should set the text in the Fragment B to the text that I entered in a Fragment A but without going directly to the Fragment B. So when I press the button pass data then I wanna go to the sliding menu and select item that containts fragment B and then I wanna see the text from Fragment A. Thanks in advance.
public class MainActivity extends AppCompatActivity implements FragmentA.DataPassListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
displayFragmentA();
} else if (id == R.id.nav_gallery) {
displayFragmentB();
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void passData(String data) {
FragmentB fragmentB = new FragmentB();
Bundle args = new Bundle();
args.putString("data", data);
fragmentB.setArguments(args);
//getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragmentB).commit();
//it works with the commented part but I dont wanna go directly to the fragment when I press pass data button
}
public void displayFragmentA() {
FragmentA frag = new FragmentA();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, frag);
fragmentTransaction.commit();
}
public void displayFragmentB() {
FragmentB frag = new FragmentB();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, frag);
fragmentTransaction.commit();
}
}
Fragment A code:
public class FragmentA extends Fragment {
DataPassListener mCallback;
public interface DataPassListener {
public void passData(String data);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Make sure that container activity implement the callback interface
try {
mCallback = (DataPassListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement DataPassListener");
}
}
public FragmentA() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
final EditText input = (EditText) view.findViewById(R.id.etInputID);
Button passDataButton = (Button) view.findViewById(R.id.bPassDataID);
passDataButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallback.passData(input.getText().toString());
}
});
return view;
}
}
Fragment B code:
public class FragmentB extends Fragment {
TextView showReceivedData;
public FragmentB() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_b, container, false);
showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
Bundle args = getArguments();
if (args != null) {
showReceivedData.setText(args.getString("data"));
} else {
Toast.makeText(getActivity(), "didnt get the bundle from mainactivity", Toast.LENGTH_LONG).show();
}
return view;
}
}
Design of the app:
If these two fragments use same activity,
to set value to fragment :
getActivity().getIntent().putExtra("key", "value");
To get value from fragment :
getActivity().getIntent().getExtras().getString("key");
Related
i am using a Drawer Navigation activity to handle fragments , and i have an options menu to change Locale like this :
public class DrawerNavigationActivity extends AppCompatActivity implements NavigationView
.OnNavigationItemSelectedListener, AgendaMainFragment.OnFragmentInteractionListener,
MediaMainFragment.OnFragmentInteractionListener, VideosFragment
.OnFragmentInteractionListener, PhotosFragment.OnFragmentInteractionListener,
ThemesMainFragment.OnFragmentInteractionListener, AdresseMainFragment
.OnFragmentInteractionListener, InfoMainFragment.OnFragmentInteractionListener,
NewsMainFragment.OnFragmentInteractionListener, BlockMainFragment
.OnFragmentInteractionListener, DemosMainFragment.OnFragmentInteractionListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer_navigation);
setTitle(R.string.app_name);
//########################################################### set initial fragment
Bundle b = getIntent().getExtras();
Fragment fragment = null;
if(b.getInt("link") == 1) {
fragment = new AgendaMainFragment();
}else if(b.getInt("link") == 2){
fragment = new MediaMainFragment();
}else if(b.getInt("link") == 3){
fragment = new ThemesMainFragment();
}else if(b.getInt("link") == 4){
fragment = new AdresseMainFragment();
}else if(b.getInt("link") == 5){
fragment = new InfoMainFragment();
}else if(b.getInt("link") == 6){
fragment = new NewsMainFragment();
}else if(b.getInt("link") == 7){
fragment = new BlockMainFragment();
}else if(b.getInt("link") == 8){
fragment = new DemosMainFragment();
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.frag_drawer_container, fragment);
ft.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.drawer_navigation, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
switch (id) {
case R.id.fr:
LocaleHelper.setLocale(getBaseContext(), "fr");
LocaleHelper.updateGlobalConfig(getBaseContext());
ft.detach(getVisibleFragment()).attach(getVisibleFragment()).commit();
return true;
case R.id.ar:
LocaleHelper.setLocale(getBaseContext(), "ar");
LocaleHelper.updateGlobalConfig(getBaseContext());
ft.detach(getVisibleFragment()).attach(getVisibleFragment()).commit();
return true;
case R.id.en:
LocaleHelper.setLocale(getBaseContext(), "en");
LocaleHelper.updateGlobalConfig(getBaseContext());
ft.detach(getVisibleFragment()).attach(getVisibleFragment()).commit();
return true;
case R.id.es:
LocaleHelper.setLocale(getBaseContext(), "es");
LocaleHelper.updateGlobalConfig(getBaseContext());
ft.detach(getVisibleFragment()).attach(getVisibleFragment()).commit();
return true;
}
return super.onOptionsItemSelected(item);
}
public Fragment getVisibleFragment(){
FragmentManager fragmentManager = DrawerNavigationActivity.this.getSupportFragmentManager();
List<Fragment> fragments = fragmentManager.getFragments();
if(fragments != null){
for(Fragment fragment : fragments){
if(fragment != null && fragment.isVisible())
return fragment;
}
}
return null;
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment = null;
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
super.onBackPressed();
return true;
} else if(id == R.id.nav_agenda) {
fragment = new AgendaMainFragment();
} else if (id == R.id.nav_gallery) {
fragment = new MediaMainFragment();
} else if (id == R.id.nav_themes) {
fragment = new ThemesMainFragment();
} else if (id == R.id.nav_adresse) {
fragment = new AdresseMainFragment();
}else if (id == R.id.nav_info) {
fragment = new InfoMainFragment();
}else if (id == R.id.nav_news) {
fragment = new NewsMainFragment();
}else if (id == R.id.nav_blocs) {
fragment = new BlockMainFragment();
}else if (id == R.id.nav_demo_animation) {
fragment = new DemosMainFragment();
}else{
return true;
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.frag_drawer_container,fragment);
ft.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onAgendaFragmentInteraction(Uri uri) {
}
#Override
public void onMediaFragmentInteraction(Uri uri) {
}
#Override
public void onFragmentInteraction(Uri uri) {
}
#Override
public void onFragmentPhotoInteraction(Uri uri) {
}
for my fragments i change the bar action title like this :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_news_main, container, false);
LocaleHelper.updateGlobalConfig(getContext());
getActivity().setTitle(getResources().getString(R.string.fgmt_titre_news));
return view;
}
it's working fin except for an RTL language , when i choose and RTL locale it change the title and the content but keeps the layout orientation LTR , so if i close the application and reopen again it changes the oriontation to RTL but keeps it even for LTR fragments:
by orientation i mean the action bar and the drawer navigation.
Fragment with local Fr :
Change Local to AR (RTL)
close the App and reopen it and navigate to RTL fragment
navigate to another LTR fragment (it keeps RTL Layout Orientation)
what am i doing wrong and what is the best and clean way to achieve it ?
Hey I'm new in android development and i'm trying to develop an app with navigation drawer. So i created fragments with navigation drawer menus, and from one of those fragments I have given an intent to a new activity. But i dont know how to go back from that activity to previous fragment.
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
displaySelectedScreen(R.id.nav_bus);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void displaySelectedScreen(int itemId) {
Fragment fragment = null;
switch (itemId) {
case R.id.nav_bus:
fragment = new BusFragment();
break;
case R.id.nav_hotel:
fragment = new HotelFragment();
break;
}
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
displaySelectedScreen(item.getItemId());
return true;
}
}
From this fragment i have given intent to city.java activity
HotelFragment.java
public class HotelFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView= inflater.inflate(R.layout.fragment_hotel, container, false);
Button button = (Button) rootView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateDetail();
} });
return rootView;
}
public void updateDetail() {
Intent intent = new Intent(getActivity(), City.class);
startActivity(intent);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Hotel");
}
}
City.java
public class City extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city_list);
} }
In manifest file i have added this
<activity android:name=".City_List"
android:parentActivityName = "MainActivity"
>
<meta-data
android:name = "android.support.PARENT_ACTIVITY"
android:value = "MainActivity" />
</activity>
</application>
to be able to go back to the previous fragment should include the .addToBackStack()
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackstack(null)
ft.commit();
}
and when you click on back button in the toolbar programmatically go back to the previous fragment using following code.
if ( getFragmentManager().getBackStackEntryCount() > 0)
{
getFragmentManager().popBackStack();
return;
}
super.onBackPressed();
Add this line inside back pressed method
if(getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
}
else {
super.onBackPressed();
}
I have a navigation drawer activity with fragments within it by using a fragment container. I have three fragments within it and I need one of it named locate_login to not contain my navigation drawer.
MainActivity.java
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); //nav drawer
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Set the fragment initially
locate_login fragment = new locate_login();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
public void onSelectFragment(View v){ //ignore this
Fragment newFragment;
if(v == findViewById(R.id.trigger)){
newFragment = new locate_after();
}
else{
newFragment = new locate_before();
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
Here is my locate_login fragment
public class locate_login extends Fragment{
public locate_login () {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.locate_login, container, false);
// Inflate the layout for this fragment
return rootView;
}
}
I will highly appreciate it if the answer will be detailed since I'm a beginner on Android Studio.
Create a class for some constant parameter. Declare some constant variable like:
Let say StringConstant.java :
public static final int LOCK_DRAWER = 1;
public static final int SHOW_DRAWER = 2;
When navigating from the drawer, use an Intent object as:
If you want to show the drawer, use:
intent.putExtra("SHOW_DRAWER", StringConstant.SHOW_DRAWER);
OR
If you do not want to show the drawer, use:
intent.putExtra("SHOW_DRAWER", StringConstant.LOCK_DRAWER);
Retrieve intent from your fragment class, you say locate_login.
int status = getActivity.getIntent().getIntExtra("SHOW_DRAWER", 0);
Check status:
if (status == String.Constant.LOCK_DRAWER){
lockDrawer();
}
public void lockDrawer() {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
To unlock the drawer:
public void unlockDrawer() {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
I am loading a simple navigation drawer with 3 fragments inside. When i go to 1st fragment and click a button in that fragment then the buttons background color is changed then i am navigating to second fragment and again i am coming back to the 1st fragment i want my fragment (With color changed button) in the backstack. But it is recreated everytime. I have tried multiple ways no luck. Since i am new to fragments i am stuck with this.
public class SampleActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, Fragment1.OnFragmentInteractionListener,
Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener {
static Fragment fragment = null;
private static final String FRAGMENT1_TAG = "FRAGMENT1_TAG";
private static final String FRAGMENT2_TAG = "FRAGMENT2_TAG";
private static final String FRAGMENT3_TAG = "FRAGMENT3_TAG";
#Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.dashboard, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
navigateToFragment(id);
return true;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public void navigateToFragment(int itemId) {
// Handle navigation view item clicks here.
String FRAGMENT_TAG="";
switch (itemId) {
case R.id.nav_fragment1:
FRAGMENT_TAG = FRAGMENT1_TAG;
fragment = Fragment1.newInstance();
break;
case R.id.nav_fragment2:
FRAGMENT_TAG = FRAGMENT2_TAG;
fragment = Fragment2.newInstance();
break;
case R.id.nav_fragment3:
FRAGMENT_TAG = FRAGMENT3_TAG;
fragment = Fragment3.newInstance();
break;
default:
FRAGMENT_TAG = FRAGMENT1_TAG;
fragment = Fragment1.newInstance();
break;
}
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
Fragment inputFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG);
if (inputFragment == null) {
fragmentTransaction.replace(R.id.content_frame, fragment, FRAGMENT_TAG).addToBackStack(null).commit();
} else {
fragmentTransaction.replace(R.id.content_frame, inputFragment, FRAGMENT_TAG).addToBackStack(null).commit();
}
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.closeDrawer(GravityCompat.START);
}
}
You should add the code of Fragment2.newInstance(); to know better the behaviour.
This code probably solve your problem:
public class SampleActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, Fragment1.OnFragmentInteractionListener,
Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener {
static Fragment fragment1 = null;
static Fragment fragment2 = null;
static Fragment fragment3 = null;
private static final String FRAGMENT1_TAG = "FRAGMENT1_TAG";
private static final String FRAGMENT2_TAG = "FRAGMENT2_TAG";
private static final String FRAGMENT3_TAG = "FRAGMENT3_TAG";
#Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.dashboard, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
navigateToFragment(id);
return true;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public void navigateToFragment(int itemId) {
// Handle navigation view item clicks here.
String FRAGMENT_TAG="";
Fragment fragment = null;
switch (itemId) {
case R.id.nav_fragment2:
FRAGMENT_TAG = FRAGMENT2_TAG;
if(fragment2 == null) fragment2 = Fragment2.newInstance();
fragment = fragment2;
break;
case R.id.nav_fragment3:
FRAGMENT_TAG = FRAGMENT3_TAG;
if(fragment3 == null) fragment3 = Fragment3.newInstance();
fragment = fragment3;
break;
default:
FRAGMENT_TAG = FRAGMENT1_TAG;
if(fragment1 == null) fragment1 = Fragment1.newInstance();
fragment = fragment1;
break;
}
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
Fragment inputFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG);
if (inputFragment == null) {
fragmentTransaction.replace(R.id.content_frame, fragment, FRAGMENT_TAG).addToBackStack(null).commit();
} else {
fragmentTransaction.replace(R.id.content_frame, inputFragment, FRAGMENT_TAG).addToBackStack(null).commit();
}
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.closeDrawer(GravityCompat.START);
}
}
I recommend you to refactor a little bit your code to get a more elegant solution.
Be sure that you're using fragmentTransaction.add() to add a fragment for the first time.
Use stack to keep track on fragment.
Check below link for reference.
https://github.com/rathodchintan/Fragment-Back-Stack
1.do not use replace method if you don't want to reload your fragment.
Instead you it use add method with keeping fragment object in the stack.
if you want to use replace, than check whether fragment is their in the memory by using findFragmentByTag method, and if it's not null use it else create new fragment.
Currently Used Google Navigation Drawer, having some problem when user backpress.
When user backpress, they didn't update menu Item
Example When I click the App. The sequence are A>B>C>B>C ,if I backpress I wanted to be C>B>A. How should I code this way out ?
My code
public class MainActivity extends AppCompatActivity {
private String appTitle;
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
private TextView toolbarTitle;
private Fragment fragment;
private FragmentManager fragmentManager;
private Title title;
private MenuItem menuItem2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
toolbarTitle.setTextColor(Color.parseColor("#FFFFFF"));
setTitle("");
fragmentManager = getSupportFragmentManager();
fragment= new HomeFragment();
title = new Title(getApplicationContext());
fragmentManager.beginTransaction().replace(R.id.content_frame,fragment , title.getStrHome()).commit();
navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem2 = menuItem;
menuItem.setChecked(true);
drawerLayout.closeDrawers();
if (menuItem.getItemId() == R.id.nav_home) {
fragment = new HomeFragment();
appTitle = title.getStrHome();
} else if ((menuItem.getItemId() == R.id.nav_direction)) {
fragment = new DirectionFragment();
appTitle = title.getStrDirection();
} else if ((menuItem.getItemId() == R.id.nav_more)) {
fragment = new MoreFragment();
appTitle = title.getStrMore();
} else if((menuItem.getItemId()==R.id.nav_directory)){
fragment = new DirectoryFragment();
appTitle = title.getStrDirectory();
}
else {
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
}
replaceFragment(fragment,appTitle);
return true;
}
});
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle =
new ActionBarDrawerToggle
(this,drawerLayout,toolbar,R.string.drawer_open,R.string.drawer_close){
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
drawerLayout.setDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
}
public void onBackPressed() {
if(drawerLayout.isDrawerOpen(GravityCompat.START)){
drawerLayout.closeDrawer(GravityCompat.START);
}
else {
if (fragmentManager.getBackStackEntryCount() > 0 ){
fragmentManager.popBackStack();
toolbarTitle.setText(appTitle);
menuItem2.setChecked(true);
} else {
finish();
}
}
}
public void replaceFragment(Fragment fragment, String tag){
toolbarTitle.setText(tag);
FragmentTransaction ft = fragmentManager.beginTransaction().replace(R.id.content_frame, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
As stated on the official page on Android tasks and back stack you can see how you can accomplish your desired behaviour using the FLAG_ACTIVITY_CLEAR_TOP in your Intent flags. This picture demonstrates it very well.
Your regular back button proceeds as:
When you specify this flag, you get a behavior like you need
Edit:
The official documentation states:
FLAG_ACTIVITY_CLEAR_TOP
If the activity being started is already running in the current task, then instead of launching a new instance of that activity, all of the
other activities on top of it are destroyed
This means, there will be no duplicates of your different Activities, and you will have a clean Back Stack.
In your example A>B>C>B>C would not be possible. Instead it would be A>B>C, since B and C already exist in the stack, they will not be added, but replaced instead.
Study the Android Activity Launch Mode.
here is the clear Explanation available.
Just take a look.