19

Alle meine Fragmente werden durch ActionBarActivity (mainActivity) gesteuert, in mainActivity ist ein DrawerLayout implementiert und alle untergeordneten Fragmente werden durch den Listeneintrag clube von drawerLayout geschoben. Das Problem, mit dem ich konfrontiert bin, ist, nachdem ich ein Fragment durch die Schublade geschoben habe. Ich möchte das Schubladensymbol in das Rückensymbol von ToolBar ändern, damit der Benutzer zum vorherigen Fragment navigieren und den Rückruf von android.R.id.home innerhalb des gleichen Fragments oder innerhalb der mainActivity behandeln kann .Verwalten der Symbolleiste Navigation und Zurück-Taste aus dem Fragment in Android

Der Code, den ich benutze ist:

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); 
    } 
} 

Aus dem obigen Code, den ich nicht in der Lage bin zu erhalten der Rückruf von android.R.id.home und die Einstellung der Home-Taste funktioniert nicht jedes Mal actionBar.setDisplayHomeAsUpEnabled(true);actionBar.setHomeButtonEnabled(true);

Jede Hilfe wird sehr geschätzt.

Dank

+1

https://github.com/tekinarslan/AndroidMaterialDesignToolbar in diesem können Sie das gleiche Verhalten erhalten, das Sie wollen –

Antwort

22

Sie haben Ihre Zurück-Taste gedrückt Aktion auf Ihrer Haupt-Aktivität, weil Ihre Hauptaktivität ist Container für Ihr Fragment zu verwalten.

Fügen Sie zunächst Ihr alle Fragment zu transaction.addToBackStack (null) und jetzt Navigation zurück wird Taste Anruf auf Haupttätigkeit gehen. Ich hoffe folgenden Code wird Ihnen helfen ...

@Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
    case android.R.id.home: 
     onBackPressed(); 
     } 
    return super.onOptionsItemSelected(item); 
} 

Sie auch

können
Fragment fragment =fragmentManager.findFragmentByTag(Constant.TAG); 
if(fragment!=null) {   
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     transaction.remove(fragment).commit(); 
} 

und den Titel zu ändern, nach Fragment Namen von Fragment Sie den folgenden Code verwenden:

activity.getSupportActionBar().setTitle("Keyword Report Detail"); 
+1

Beachten Sie, dass Sie 'return true' nach' onBackPressed() 'aufrufen müssen, damit dies funktioniert. Wenn Sie nicht 'onBackPressed()' haben keine Wirkung, da der Aufruf von 'super.onOptionsItemSelected (Element) ' – hanspeide

0

OnToolBar gibt es ein Navigationssymbol auf der linken Seite

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); 

Mit diesem auf der linken Seite Navigationssymbol erscheinen und auf Navigationssymbol klicken Sie auf Eltern-Aktivität aufrufen.

und in Manifest können wir System über die Elternaktivität benachrichtigen.

<activity 
      android:name=".CategoryCloudSelectActivity" 
      android:parentActivityName=".EventSelectionActivity" 
      android:screenOrientation="portrait" /> 
+1

verbraucht wird Dies funktioniert nicht mit Fragmenten. –

3

Sie können Toolbar innerhalb des Fragments verwenden und es ist einfach zu handhaben. Erste Toolbar Layout des Fragments hinzufügen

<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> 

Innerhalb der onCreateView Methode in dem Fragment Sie die Symbolleiste wie diese verarbeiten kann.

Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); 
toolbar.setTitle("Title"); 
toolbar.setNavigationIcon(R.drawable.ic_arrow_back); 

IT wird die Symbolleiste, den Titel und den Zurück-Pfeil-Navigation auf toolbar.You setzen ein beliebiges Symbol auf setNavigationIcon Verfahren einstellen.

Wenn Sie ein Ereignis auslösen müssen, wenn Sie auf das Symbolleistensymbol klicken, können Sie dies verwenden.

Wenn Ihre Aktivität über eine Navigationsleiste verfügt, müssen Sie diese möglicherweise öffnen, wenn Sie auf die Navigationsschaltfläche Zurück klicken. Sie können diese Schublade so öffnen.

toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout); 
      drawer.openDrawer(Gravity.START); 
     } 
    }); 

Voll Code ist hier

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; 
} 
14

eine Symbolleiste auf Ihre xml hinzufügen

<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> 

Dann in Ihrem onCreateView Methode in dem 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(); 
    } 
}); 
+1

Danke für deine Antwort, die mein Problem gelöst hat. –

11

I Kopf um viele Lösungen und nein ne von ihnen funktioniert perfekt. Ich habe die Variation der verfügbaren Lösungen in meinem Projekt verwendet, das hier wie folgt ist. Bitte verwenden Sie diesen Code innerhalb der Klasse, in der Sie das Werkzeugleisten- und Schubladenlayout initialisieren.

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); 
        } 
       }); 
      } 
     } 
    }); 
+0

Nach dem Versuch, ein paar der Lösung endlich funktionierte es für mich. – Sharad

+0

Das funktioniert gut, ich habe am Ende der Show eine Zeile hinzugefügt hamburguer else ( drawer.setDrawerLockMode (DrawerLayout.LOCK_MODE_UNLOCKED);) und eine weitere am Ende der (if (getSupportFragmentManager(). GetBackStackEntryCount()> 0)) welche is (drawer.setDrawerLockMode (DrawerLayout.LOCK_MODE_LOCKED_CLOSED);) Der Benutzer kann das Fach nicht durch Ziehen öffnen, wenn der Zurück-Pfeil angezeigt wird – Setar

+0

Das ist so unklar ... was ist 'drawerFragment', was ist' mDrawerToggle'? Ereglious Beispiel für eine schlechte Antwort –

0

Wahrscheinlich ist die sauberste Lösung:

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) 
     } 
    } 
} 

Nur diese Klasse als Eltern verwenden für alle Fragmente, die Navigation unterstützen sollte.