Tous mes fragments sont contrôlés par ActionBarActivity
(mainActivity). Dans mainActivity, une DrawerLayout
est implémentée et tous les fragments enfants sont poussés par le clic sur l'élément de liste de tiroirLayout. Le problème auquel je suis confronté est après avoir poussé un fragment à travers tiroirLayout. Je souhaite changer l'icône du tiroir en icône arrière de ToolBar
afin que l'utilisateur puisse accéder au fragment précédent et gérer le rappel de Android.R.id.home
dans le même fragment ou dans l'activité principale .
Le code que j'utilise est:
MainActivity.Java
public class MainActivity extends ActionBarActivity {
private DrawerLayout layoutDrawer;
private ActionBarDrawerToggle drawerToggler;
private Stack<Fragment> stack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stack = new Stack<Fragment>();
layoutDrawer = (DrawerLayout) findViewById(R.id.layout_drawer);
drawerToggler = new ActionBarDrawerToggle(this, layoutDrawer, toolbar,
R.string.app_name, R.string.app_name);
layoutDrawer.setDrawerListener(drawerToggler);
setUpDrawerList();
pushFragment(new FirstFragment(), true);
Session.setContext(getApplicationContext());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggler.isDrawerIndicatorEnabled()
&& drawerToggler.onOptionsItemSelected(item))
return true;
switch (item.getItemId()) {
case Android.R.id.home:
Toast.makeText(this, "Back from activity", Toast.LENGTH_SHORT)
.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggler.syncState();
}
@Override
public void onBackPressed() {
popFragment();
}
private void setUpDrawerList() {
ListView listView = (ListView) findViewById(R.id.list_drawer);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
Android.R.layout.simple_list_item_1,
Arrays.asList(new String[] { "First Fragment",
"Second Fragment" }));
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
layoutDrawer.closeDrawers();
drawerToggler.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
pushFragment(getFragment(position), true);
}
});
}
private Fragment getFragment(int pos) {
switch (pos) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
}
return null;
}
public void pushFragment(Fragment fragment, boolean add) {
FragmentTransaction transation = getSupportFragmentManager()
.beginTransaction();
if (add)
stack.Push(fragment);
transation.replace(R.id.layout_content, fragment);
transation.commit();
}
public void popFragment() {
if (!stack.isEmpty()) {
Fragment fragment = stack.elementAt(stack.size() - 2);
stack.pop();
pushFragment(fragment, false);
} else
super.onBackPressed();
drawerToggler.setDrawerIndicatorEnabled(stack.size() == 1);
}
public void clearBackStack() {
stack.clear();
}
}
FirstFragment.Java
public class FirstFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
@Override
public void onResume() {
super.onResume();
ActionBar actionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
actionBar.setTitle("First Fragment");
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.fragment_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case Android.R.id.home:
Toast.makeText(getActivity(), "Back from fragment", Toast.LENGTH_SHORT).show();
getActivity().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}
À partir du code ci-dessus, je ne parviens pas à obtenir le rappel de Android.R.id.home
et le réglage du bouton principal ne fonctionne pas à chaque fois actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
Toute aide sera vraiment appréciée.
Merci
Vous devez gérer l'action que vous appuyez sur le bouton retour de votre activité principale car celle-ci est le conteneur de votre fragment.
Tout d’abord, ajoutez votre tout fragment à transaction.addToBackStack (null) et maintenant l’appel du bouton de navigation retour sera activé. J'espère que le code suivant vous aidera ...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
vous pouvez aussi utiliser
Fragment fragment =fragmentManager.findFragmentByTag(Constant.TAG);
if(fragment!=null) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment).commit();
}
Et pour changer le titre en fonction du nom de fragment de fragment, vous pouvez utiliser le code suivant:
activity.getSupportActionBar().setTitle("Keyword Report Detail");
Ajouter une barre d'outils à votre XML
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
Android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Fragment title"/>
</Android.support.v7.widget.Toolbar>
Ensuite, dans votre méthode onCreateView dans le fragment:
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_button);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
J'ai pas mal de solutions et aucune ne fonctionne parfaitement. J'ai utilisé diverses variantes de solutions disponibles dans mon projet, présentées ci-dessous. Veuillez utiliser ce code dans la classe où vous initialisez la disposition de la barre d’outils et des tiroirs.
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);// show back button
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
//show hamburger
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerFragment.mDrawerToggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawerFragment.mDrawerLayout.openDrawer(GravityCompat.START);
}
});
}
}
});
Vous pouvez utiliser Toolbar à l'intérieur du fragment et il est facile à manipuler. D'abord, ajoutez la barre d'outils à la mise en page du fragment
<Android.support.v7.widget.Toolbar
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/toolbar"
Android:layout_height="wrap_content"
Android:layout_width="match_parent"
Android:fitsSystemWindows="true"
Android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
Android:background="?attr/colorPrimaryDark">
</Android.support.v7.widget.Toolbar>
Dans la méthode onCreateView du fragment, vous pouvez gérer la barre d’outils comme ceci.
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
Il définira la barre d'outils, le titre et la navigation de la flèche vers l'arrière sur la barre d'outils. Vous pouvez définir n'importe quelle icône sur la méthode setNavigationIcon.
Si vous devez déclencher un événement lorsque vous cliquez sur l'icône de navigation de la barre d'outils, vous pouvez l'utiliser.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//handle any click event
});
Si votre activité comporte un tiroir de navigation, vous devrez peut-être l'ouvrir en cliquant sur le bouton de navigation arrière. vous pouvez ouvrir ce tiroir comme ça.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
Le code complet est ici
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate the layout to the fragement
view = inflater.inflate(R.layout.layout_user,container,false);
//initialize the toolbar
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//open navigation drawer when click navigation back button
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
return view;
}
Probablement la solution la plus propre:
abstract class NavigationChildFragment : Fragment() {
abstract fun onCreateChildView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View?
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true)
return onCreateChildView(inflater, container, savedInstanceState)
}
override fun onDestroyView() {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
setHasOptionsMenu(false)
super.onDestroyView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val activity = activity as? MainActivity
return when (item.itemId) {
Android.R.id.home -> {
activity?.onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
Utilisez simplement cette classe comme parent pour tous les fragments devant prendre en charge la navigation.
OnToolBar il y a une icône de navigation à gauche
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
toolbar.setTitle(getResources().getString(R.string.title_activity_select_event));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
En utilisant cette icône de navigation à gauche, cliquez sur l'icône de navigation pour appeler l'activité parent.
et dans manifest, nous pouvons informer le système de l'activité des parents.
<activity
Android:name=".CategoryCloudSelectActivity"
Android:parentActivityName=".EventSelectionActivity"
Android:screenOrientation="portrait" />