Stesso cassetto di navigazione in diverse attività


206

Ho creato un cassetto di navigazione funzionante come mostrato nel tutorial sul sito Web developer.android.com . Ma ora, voglio usare un cassetto di navigazione, creato nel NavigationDrawer.class per più attività nella mia applicazione.

La mia domanda è, se qualcuno qui può fare un piccolo tutorial, che spiega, come utilizzare un cassetto di navigazione per più attività.

L'ho letto prima in questa risposta Android Navigation Drawer su più attività

ma non ha funzionato sul mio progetto

public class NavigationDrawer extends Activity {
public DrawerLayout drawerLayout;
public ListView drawerList;
private ActionBarDrawerToggle drawerToggle;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) {

        public void onDrawerClosed(View view) {
            getActionBar().setTitle(R.string.app_name);
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(R.string.menu);
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);

    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    layers = getResources().getStringArray(R.array.layers_array);
    drawerList = (ListView) findViewById(R.id.left_drawer);
    View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
    drawerList.addHeaderView(header, null, false);
    drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
            layers));
    View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
            R.layout.drawer_list_footer, null, false);
    drawerList.addFooterView(footerView);

    drawerList.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
            map.drawerClickEvent(pos);
        }
    });
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);

}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    drawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    drawerToggle.onConfigurationChanged(newConfig);
}
}

In questa attività voglio avere il cassetto di navigazione, quindi estendo "NavigationDrawer" e in alcune altre attività voglio utilizzare lo stesso cassetto di navigazione

  public class SampleActivity extends NavigationDrawer {...}

Non so cosa cambiare ...


1
Puoi trovare gli esempi qui .
Naddy,

Risposte:


188

Se vuoi un cassetto di navigazione, dovresti usare i frammenti. Ho seguito questo tutorial la scorsa settimana e funziona benissimo:

http://developer.android.com/training/implementing-navigation/nav-drawer.html

Puoi anche scaricare il codice di esempio da questo tutorial per vedere come puoi farlo.


Senza frammenti:

Questo è il tuo codice BaseActivity:

public class BaseActivity extends Activity
{
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    public String[] layers;
    private ActionBarDrawerToggle drawerToggle;
    private Map map;

    protected void onCreate(Bundle savedInstanceState)
    {
        // R.id.drawer_layout should be in every activity with exactly the same id.
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) 
        {
            public void onDrawerClosed(View view) 
            {
                getActionBar().setTitle(R.string.app_name);
            }

            public void onDrawerOpened(View drawerView) 
            {
                getActionBar().setTitle(R.string.menu);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
        drawerList.addHeaderView(header, null, false);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
                layers));
        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.drawer_list_footer, null, false);
        drawerList.addFooterView(footerView);

        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                map.drawerClickEvent(pos);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);

    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
}

Tutte le altre attività che devono avere un riquadro di navigazione dovrebbero estendere questa attività anziché l'attività stessa, ad esempio:

public class AnyActivity extends BaseActivity
{
    //Because this activity extends BaseActivity it automatically has the navigation drawer
    //You can just write your normal Activity code and you don't need to add anything for the navigation drawer
}

XML

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!-- Put what you want as your normal screen in here, you can also choose for a linear layout or any other layout, whatever you prefer -->
    </FrameLayout>
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

Modificare:

Ho riscontrato alcune difficoltà, quindi ecco una soluzione se ottieni NullPointerExceptions. In BaseActivity cambia la funzione onCreate in protected void onCreateDrawer(). Il resto può rimanere lo stesso. Nelle attività che estendono BaseActivity inserisci il codice in questo ordine:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    super.onCreateDrawer();

Questo mi ha aiutato a risolvere il mio problema, spero che aiuti!

Questo è il modo in cui puoi creare un cassetto di navigazione con più attività, se hai domande, sentiti libero di porre.


Modifica 2:

Come detto da @GregDan BaseActivitypuoi anche sovrascrivere setContentView()e chiamare onCreateDrawer lì:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}

7
Non voglio usare attività su frammenti, voglio solo usare diverse attività che usano lo stesso cassetto di navigazione. Voglio attività, perché lì posso usare diversi tipi di layout come la visualizzazione a scorrimento, la visualizzazione della mappa ...
MEX

135
Avere una sola attività può essere un'attività scoraggiante per qualsiasi app abbastanza complessa. L'uso delle attività ti offre molte cose gratuite dal sistema, quindi è un punto valido su come utilizzare più attività. Non riesco a immaginare un'attività che gestisca la comunicazione tra un numero qualsiasi di combinazioni di frammenti - semplicemente non funzionerà.
Slott

1
Mi dispiace che ci sia voluto così tanto tempo per rispondere. Ho modificato la mia risposta. Credo che questo sia il tutorial che stavi cercando. Spero che questo ti aiuti.
Kevin van Mierlo,

2
@KevinvanMierlo puoi dirmi cosa intendi per: R.id.drawer_layout dovrebbe essere in ogni attività con esattamente lo stesso ID. Perché ho fatto esattamente quello che hai detto qui e ottengo una NullPointerException nel metodo onCreate () dell'Attività che estende questa BaseActivity ..
Loolooii,

1
@KevinvanMierlo a proposito, penso che hai dimenticato queste 2 righe? super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii,

34

Ho trovato la migliore implementazione. È nell'I / O di Google 2014 .

Usano lo stesso approccio di Kevin. Se riesci a sottrarti a tutte le cose non necessarie nell'app I / O, potresti estrarre tutto ciò di cui hai bisogno ed è assicurato da Google che si tratta di un uso corretto del modello di cassetto di navigazione. Ogni attività ha facoltativamente un DrawerLayoutlayout principale. La parte interessante è come viene eseguita la navigazione verso altre schermate. È implementato in BaseActivityquesto modo:

private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
            case NAVDRAWER_ITEM_MY_SCHEDULE:
                intent = new Intent(this, MyScheduleActivity.class);
                startActivity(intent);
                finish();
                break;

Ciò differisce dal modo comune di sostituire il frammento corrente con una transazione di frammenti. Ma l'utente non rileva una differenza visiva.


Questo ^ non riesco a capire come avviano nuove attività e funziona perfettamente. È una grande app su cui lavorare.
hitch.united,

@ hitch.united Questo perché usano molti frammenti e solo alcune attività.
Joaquin Iurchuk,

@ hitch.united probabilmente hanno la precedenza sull'animazione dell'attività overridePendingTransitions.
EpicPandaForce,

caricare frammenti anziché attività di sottoclasse?
Vikas Pandey,

Ecco il file di ottobre 2014: github.com/google/iosched/blob/…
denvercoder9

8

Quindi questa risposta è in ritardo di qualche anno, ma qualcuno potrebbe apprezzarla. Android ci ha fornito un nuovo widget che semplifica l'utilizzo di un cassetto di navigazione con diverse attività.

android.support.design.widget.NavigationView è modulare e ha il suo layout nella cartella dei menu. Il modo in cui lo usi è avvolgere i layout XML nel modo seguente:

  1. Root Layout è un android.support.v4.widget.DrawerLayout che contiene due elementi secondari: uno <include ... />per il layout che viene avvolto (vedi 2) e un android.support.design.widget.NavigationView.

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
    
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

nav_header_main è solo un LinearLayout con orientamento = verticale per l'intestazione del tuo Drawar di navigazione.

activity_main_drawer è un xml di menu nella directory res / menu. Può contenere elementi e gruppi di tua scelta. Se utilizzi la Galleria AndroidStudio, la procedura guidata ne farà una semplice e potrai vedere quali sono le tue opzioni.

  1. Il layout della barra delle app di solito ora è un android.support.design.widget.CoordinatorLayout e questo includerà due figli: un android.support.design.widget.AppBarLayout (che contiene un android.support.v7.widget.Toolbar) e un <include ... >for il tuo contenuto reale (vedi 3).

    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="yourpackage.MainActivity">
    
     <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    
    </android.support.design.widget.AppBarLayout>
    
    <include layout="@layout/content_main" />

  2. Il layout del contenuto può essere quello che desideri. Questo è il layout che contiene il contenuto principale dell'attività (escluso il riquadro di navigazione o la barra dell'app).

Ora, la cosa bella di tutto questo è che puoi avvolgere ogni attività in questi due layout ma avere il tuo NavigationView (vedi passaggio 1) che punta sempre a activity_main_drawer (o qualsiasi altra cosa). Ciò significa che avrai lo stesso (*) cassetto di navigazione su tutte le attività.

  • Non saranno la stessa istanza di NavigationView ma, per essere onesti, ciò non è stato possibile nemmeno con la soluzione BaseActivity descritta sopra.

stackoverflow sta tagliando alcune delle parentesi racchiuse in XML, ma le cose importanti sono tutte lì.
jwehrle,

ma come trattate la funzionalità come i pulsanti? devi scrivere lo stesso codice in ogni attività?
Laur89,

Sì, perché si tratta di istanze separate. Tuttavia, puoi creare una super classe per le tue attività da estendere e inserire quel codice lì una volta.
jwehrle

@jwehrle puoi scrivere un esempio su come creare una super classe per le nostre attività?
CDrosos,

classe astratta pubblica MyBaseActivity estende AppCompatActivity implementa NavigationView.OnNavigationItemSelectedListener {// implementa quanto segue: Sostituisci booleano pubblico suNavigationItemSelected (elemento MenuItem @NonNull) {}} classe pubblica MyActivity estende MyBaseActivity {}
jwehrle

7

Il modo più semplice per riutilizzare un cassetto di navigazione comune tra un gruppo di attività

app_base_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <FrameLayout
        android:id="@+id/view_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_test"
        />
</android.support.v4.widget.DrawerLayout>

AppBaseActivity.java

/*
* This is a simple and easy approach to reuse the same 
* navigation drawer on your other activities. Just create
* a base layout that conains a DrawerLayout, the 
* navigation drawer and a FrameLayout to hold your
* content view. All you have to do is to extend your 
* activities from this class to set that navigation 
* drawer. Happy hacking :)
* P.S: You don't need to declare this Activity in the 
* AndroidManifest.xml. This is just a base class.
*/
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class AppBaseActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
    private FrameLayout view_stub; //This is the framelayout to keep your content view
    private NavigationView navigation_view; // The new navigation view from Android Design Library. Can inflate menu resources. Easy
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Menu drawerMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.app_base_layout);// The base layout that contains your navigation drawer.
        view_stub = (FrameLayout) findViewById(R.id.view_stub);
        navigation_view = (NavigationView) findViewById(R.id.navigation_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        drawerMenu = navigation_view.getMenu();
        for(int i = 0; i < drawerMenu.size(); i++) {
          drawerMenu.getItem(i).setOnMenuItemClickListener(this);
        }
        // and so on...
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    /* Override all setContentView methods to put the content view to the FrameLayout view_stub
     * so that, we can make other activity implementations looks like normal activity subclasses.
     */
    @Override
    public void setContentView(int layoutResID) {
        if (view_stub != null) {
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            View stubView = inflater.inflate(layoutResID, view_stub, false);
            view_stub.addView(stubView, lp);
        }
    }

    @Override
    public void setContentView(View view) {
        if (view_stub != null) {
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            view_stub.addView(view, lp);
        }
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (view_stub != null) {
            view_stub.addView(view, params);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                // handle it
                break;
            case R.id.item2:
                // do whatever
                break;
            // and so on...
        }
        return false;
    }
}

Potete fornire un esempio di un'attività che utilizza questa attività di base?
CDrosos,

Non riesco davvero a ricordare alcun dettaglio su questo, penso che solo l'estensione AppBaseActivity e setContentViewil modo predefinito dovrebbero funzionare.
Levon Petrosyan,

6

Per chiunque cerchi di fare ciò che chiede il poster originale, ti preghiamo di considerare di usare i frammenti invece come ha detto Kevin. Ecco un eccellente tutorial su come farlo:

https://github.com/codepath/android_guides/wiki/Fragment-Navigation-Drawer

Se si sceglie di utilizzare invece le attività anziché i frammenti, si verificherà il problema della ricostruzione del cassetto di navigazione ogni volta che si passa a una nuova attività. Ciò si traduce in un brutto / lento rendering del cassetto di navigazione ogni volta.


5

Il mio consiglio è: non usare affatto le attività, invece usa i frammenti e sostituiscili nel contenitore (ad esempio Layout lineare) dove mostri il tuo primo frammento.

Il codice è disponibile in Tutorial per sviluppatori Android, devi solo personalizzare.

http://developer.android.com/training/implementing-navigation/nav-drawer.html

È consigliabile utilizzare sempre più frammenti nella propria applicazione e dovrebbero esserci solo quattro attività di base locali per la propria applicazione, citate nel proprio AndroidManifest.xml oltre a quelle esterne (ad esempio FacebookActivity):

  1. SplashActivity: non utilizza frammenti e utilizza il tema FullScreen.

  2. LoginSignUpActivity: non richiede affatto NavigationDrawer e nessun pulsante Indietro, quindi utilizza semplicemente la normale barra degli strumenti, ma saranno richiesti almeno 3 o 4 frammenti. Utilizza un tema senza barra delle azioni

  3. Attività HomeAttività o DashBoard: utilizza un tema senza barra delle azioni. Qui è necessario il cassetto di navigazione, inoltre tutte le schermate che seguono saranno frammenti o frammenti nidificati, fino alla vista foglia, con il cassetto condiviso. Tutte le impostazioni, il profilo utente e così via saranno qui come frammenti, in questa attività. I frammenti qui non verranno aggiunti allo stack posteriore e verranno aperti dalle voci del menu del cassetto. Nel caso di frammenti che richiedono il pulsante Indietro anziché il cassetto, di seguito è riportato un quarto tipo di attività.

  4. Attività senza cassetto. Questa attività ha un pulsante Indietro in alto e i frammenti all'interno condivideranno la stessa barra delle azioni. Questi frammenti verranno aggiunti al back-stack, poiché ci sarà una cronologia di navigazione.

[Per ulteriori indicazioni consultare: https://stackoverflow.com/a/51100507/787399 ]

Buona programmazione !!


Questo è un post più vecchio. Puoi usare i frammenti per assicurarti di avere sempre un'attività. Continui a sostituire i frammenti in un contenitore ad esso dedicato. Metti in pila quando hai bisogno di una navigazione all'indietro o fai saltare tutti i frammenti quando hai bisogno di un frammento per essere mostrato come primo.
Abhinav Saxena,

@ Cabuxa.Mapache Controlla il link allegato alla mia risposta per ottenere ulteriore assistenza. Ho preso un BaseActivity comune, che aiuta a condividere ActionBar ToolBar e NavigatonDrawer e altri componenti in tutti i frammenti ad esso collegati.
Abhinav Saxena,

1

aggiorna questo codice in base all'attività. e non dimenticare di includere drawer_list_header nella tua attività xml.

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.drawer_list_header);

e non utilizzare request () nella tua attività. ma il cassetto non è ancora visibile facendo clic sull'immagine..e trascinandolo sarà visibile senza voci di elenco. ci ho provato molto ma senza successo. bisogno di alcuni allenamenti per questo ...


1

Con la risposta di @Kevin van Mierlo, sei anche in grado di implementare diversi cassetti. Ad esempio, il menu predefinito situato sul lato sinistro (inizio) e un ulteriore menu opzionale, situato sul lato destro, che viene visualizzato solo quando vengono caricati determinati frammenti.

Sono stato in grado di farlo.


1
package xxxxxx;



import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.widget.SearchView;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;


public class loginhome extends AppCompatActivity {
    private Toolbar toolbar;
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;

    // Make sure to be using android.support.v7.app.ActionBarDrawerToggle version.
    // The android.support.v4.app.ActionBarDrawerToggle has been deprecated.
    private ActionBarDrawerToggle drawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.loginhome);

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        //Initializing NavigationView


        navigationView = (NavigationView) findViewById(R.id.nav_view);

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu

            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state
                if(menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();

                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()){


                    //Replacing the main content with ContentFragment Which is our Inbox View;
                    case R.id.nav_first_fragment:
                        Toast.makeText(getApplicationContext(),"First fragment",Toast.LENGTH_SHORT).show();
                         FirstFragment fragment = new FirstFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame,fragment);
                        fragmentTransaction.commit();
                        return true;

                    // For rest of the options we just show a toast on click
                    case R.id.nav_second_fragment:
                        Toast.makeText(getApplicationContext(),"Second fragment",Toast.LENGTH_SHORT).show();
                        SecondFragment fragment2 = new SecondFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction2 = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction2.replace(R.id.frame,fragment2);
                        fragmentTransaction2.commit();
                        return true;

                    default:
                        Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
                        return true;

                }
            }
        });

        // Initializing Drawer Layout and ActionBarToggle
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close){

            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank

                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        //calling sync state is necessay or else your hamburger icon wont show up
        actionBarDrawerToggle.syncState();







    }

usalo per la tua toolbar.xml

<?xml version="1.0" encoding="utf-8"?>

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:elevation="4dp"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark"


        >

    </android.support.v7.widget.Toolbar>

utilizzare questo per l'intestazione di navigazione se si desidera utilizzare

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/navhead"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:textColor="#ffffff"
            android:text="tanya"
            android:textSize="14sp"
            android:textStyle="bold"

            />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="5dp"
            android:text="tanya.com"
            android:textSize="14sp"
            android:textStyle="normal"

            />
    </LinearLayout>
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_below="@+id/imageView"
        android:layout_marginTop="15dp"

        android:src="@drawable/face"
        android:id="@+id/circleView"
        />



</RelativeLayout>

1

Lo faccio a Kotlin in questo modo:

open class BaseAppCompatActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

protected lateinit var drawerLayout: DrawerLayout
protected lateinit var navigationView: NavigationView
@Inject
lateinit var loginService: LoginService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("BaseAppCompatActivity", "onCreate()")
    App.getComponent().inject(this)
    drawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout

    val toolbar = findViewById(R.id.toolbar) as Toolbar
    setSupportActionBar(toolbar)

    navigationView = findViewById(R.id.nav_view) as NavigationView
    navigationView.setNavigationItemSelectedListener(this)

    val toggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)

    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()
    toggle.isDrawerIndicatorEnabled = true

    val navigationViewHeaderView = navigationView.getHeaderView(0)
    navigationViewHeaderView.login_txt.text = SharedKey.username
}
private inline fun <reified T: Activity> launch():Boolean{
    if(this is T) return closeDrawer()
    val intent = Intent(applicationContext, T::class.java)
    startActivity(intent)
    finish()
    return true
}

private fun closeDrawer(): Boolean {
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    when (id) {
        R.id.action_tasks -> {
            return launch<TasksActivity>()
        }
        R.id.action_contacts -> {
            return launch<ContactActivity>()
        }
        R.id.action_logout -> {
            createExitDialog(loginService, this)
        }
    }
    return false
}
}

Le attività per drawer devono ereditare questo BaseAppCompatActivity, chiamare super.onCreatedopo aver impostato il contenuto (in realtà, può essere spostato in un metodo init) e avere elementi corrispondenti per gli ID nel loro layout


Volevo provare la tua soluzione ma ho questo errore: "Questa attività ha già una barra delle azioni fornita dalla decorazione della finestra". Voglio passare tra 3 attività e ognuna ha la sua barra delle app. Pensi che sia possibile?
davoid

Penso che in quel caso sia necessario spostare la barra delle azioni su frammenti. Nella nostra app abbiamo usato il tema NoActionBar e fornito la barra degli strumenti per la compatibilità, per quanto ricordo.
Pavlus,

@Pavlus come sarebbe il codice nella seconda attività? class trackActivity: BaseAppCompatActivity () {?
Craig P

0

La mia risposta è solo concettuale senza alcun codice sorgente. Potrebbe essere utile per alcuni lettori come me capire.

Dipende dal tuo approccio iniziale su come architettura la tua app. Esistono fondamentalmente due approcci.

  1. Si crea un'attività (attività di base) e tutte le altre viste e schermate saranno frammenti. Tale attività di base contiene l'implementazione per i layout dei cassetti e dei coordinatori. In realtà è il mio modo preferito di fare perché avere piccoli frammenti autonomi renderà lo sviluppo di app più semplice e fluido.

  2. Se hai avviato lo sviluppo dell'app con attività, una per ogni schermata, probabilmente creerai l'attività di base e tutte le altre attività si estenderanno da essa. L'attività di base conterrà il codice per l'implementazione di drawer e coordinator. Qualsiasi attività che necessita dell'implementazione del drawer può estendersi dall'attività di base.

Personalmente preferirei evitare di usare frammenti e attività mescolati senza alcuna organizzazione. Ciò rende lo sviluppo più difficile e alla fine ti blocca. Se l'hai fatto, refatta il tuo codice.


-1

Crea il riquadro di navigazione in MainActivity usando il frammento.
Inizializza il cassetto di navigazione in MainActivity
ora in tutte le altre attività in cui vuoi usare lo stesso cassetto di navigazione e posiziona il cassetto come base e frammento come cassetto di navigazione. Basta impostare android: nome nel frammento che punta al frammento del file Java. Non sarà necessario inizializzare il frammento in altre attività.
Puoi accedere a Nav Drawer scorrendo in altre attività come nell'app Google Play Store

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.