Gleiche Navigationsschublade in verschiedenen Aktivitäten


206

Ich habe eine funktionierende Navigationsschublade erstellt, wie sie im Tutorial auf der Website developer.android.com gezeigt wird . Aber jetzt möchte ich eine Navigationsschublade verwenden, die ich in der NavigationDrawer.class für mehrere Aktivitäten in meiner Anwendung erstellt habe.

Meine Frage ist, ob jemand hier ein kleines Tutorial erstellen kann, in dem erklärt wird, wie eine Navigationsschublade für mehrere Aktivitäten verwendet wird.

Ich habe es zuerst in dieser Antwort Android Navigation Drawer über mehrere Aktivitäten gelesen

aber es hat bei meinem Projekt nicht funktioniert

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 dieser Aktivität möchte ich die Navigationsschublade haben, also erweitere ich 'NavigationDrawer' und in einigen anderen Aktivitäten möchte ich dieselbe Navigationsschublade verwenden

  public class SampleActivity extends NavigationDrawer {...}

Ich weiß nicht, was ich ändern soll ...


1
Die Beispiele finden Sie hier .
Naddy

Antworten:


188

Wenn Sie eine Navigationsschublade wünschen, sollten Sie Fragmente verwenden. Ich habe dieses Tutorial letzte Woche befolgt und es funktioniert großartig:

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

Sie können auch Beispielcode aus diesem Tutorial herunterladen, um zu sehen, wie Sie dies tun können.


Ohne Fragmente:

Dies ist Ihr BaseActivity Code:

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

Alle anderen Aktivitäten, für die eine Navigationsleiste erforderlich ist, sollten diese Aktivität anstelle der Aktivität selbst erweitern. Beispiel:

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>

Bearbeiten:

Ich habe selbst einige Schwierigkeiten gehabt. Hier ist eine Lösung, wenn Sie NullPointerExceptions erhalten. Ändern Sie in BaseActivity die Funktion onCreate in protected void onCreateDrawer(). Der Rest kann gleich bleiben. Geben Sie in den Aktivitäten, die BaseActivity erweitern, den Code in der folgenden Reihenfolge ein:

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

Dies hat mir geholfen, mein Problem zu beheben, hoffe es hilft!

Auf diese Weise können Sie eine Navigationsleiste mit mehreren Aktivitäten erstellen, wenn Sie Fragen haben.


Bearbeiten 2:

Wie von @GregDan gesagt, BaseActivitykönnen Sie dort auch setContentView()onCreateDrawer überschreiben und aufrufen:

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

7
Ich möchte keine Aktivitäten über Fragmenten verwenden, sondern nur verschiedene Aktivitäten, bei denen dieselbe Navigationsleiste verwendet wird. Ich möchte Aktivität, weil ich dort verschiedene Arten von Layouts wie Wischansicht, Kartenansicht verwenden kann ...
MEX

135
Nur eine Aktivität zu haben, kann für jede recht komplexe App eine entmutigende Aufgabe sein. Durch die Verwendung von Aktivitäten erhalten Sie viele kostenlose Funktionen aus dem System. Daher ist es ein gültiger Punkt für die Verwendung mehrerer Aktivitäten. Ich kann mir keine Aktivität vorstellen, die die Kommunikation zwischen einer beliebigen Anzahl von Fragmentkombinationen handhabt - es wird einfach nicht funktionieren.
Slott

1
Es tut mir leid, dass ich so lange gebraucht habe, um zu antworten. Ich habe meine Antwort bearbeitet. Ich glaube, das ist das Tutorial, nach dem Sie gesucht haben. Hoffe das hilft.
Kevin van Mierlo

2
@ KevinVinierMierlo können Sie mir sagen, was Sie damit meinen: R.id.drawer_layout sollte in jeder Aktivität mit genau der gleichen ID enthalten sein. Weil ich genau das getan habe, was Sie hier gesagt haben, und eine NullPointerException in der onCreate () -Methode der Aktivität erhalte, die diese BaseActivity erweitert.
Loolooii

1
@ KevinvanMierlo übrigens, ich denke du hast diese 2 Zeilen vergessen? super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii

34

Ich habe die beste Implementierung gefunden. Es ist in der Google I / O 2014 App.

Sie verfolgen den gleichen Ansatz wie Kevin. Wenn Sie sich von allen nicht benötigten Dingen in der E / A-App abstrahieren können, können Sie alles extrahieren, was Sie benötigen, und Google versichert, dass das Muster der Navigationsschublade korrekt verwendet wird. Jede Aktivität hat optional ein DrawerLayoutHauptlayout. Der interessante Teil ist, wie die Navigation zu anderen Bildschirmen erfolgt. Es wird folgendermaßen implementiert BaseActivity:

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

Dies unterscheidet sich von der üblichen Methode, das aktuelle Fragment durch eine Fragmenttransaktion zu ersetzen. Der Benutzer erkennt jedoch keinen visuellen Unterschied.


Ich kann nicht herausfinden, wie sie neue Aktivitäten starten und es funktioniert einwandfrei. Es ist eine große App zum Durcharbeiten.
hitch.united

@ hitch.united Das liegt daran, dass sie viele Fragmente und nur wenige Aktivitäten verwenden.
Joaquin Iurchuk

@ hitch.united überschreiben sie wahrscheinlich die Animation der Aktivität mit overridePendingTransitions.
EpicPandaForce

Wird das Laden von Fragmenten anstelle von Unterklassenaktivitäten durchgeführt?
Vikas Pandey

Hier ist die Datei vom Oktober 2014: github.com/google/iosched/blob/…
denvercoder9

8

Diese Antwort ist also ein paar Jahre zu spät, aber jemand kann sie zu schätzen wissen. Android hat uns ein neues Widget zur Verfügung gestellt, das die Verwendung einer Navigationsleiste mit mehreren Aktivitäten erleichtert.

android.support.design.widget.NavigationView ist modular aufgebaut und verfügt über ein eigenes Layout im Menüordner. Sie verwenden es, um XML-Layouts folgendermaßen zu verpacken:

  1. Das Stammlayout ist ein android.support.v4.widget.DrawerLayout, das zwei untergeordnete Elemente enthält: ein <include ... />Layout für das zu verpackende Layout (siehe 2) und ein 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 ist nur ein LinearLayout mit Ausrichtung = vertikal für den Header Ihres Navigationszeichens.

activity_main_drawer ist eine Menü-XML in Ihrem res / menu-Verzeichnis. Es kann Elemente und Gruppen Ihrer Wahl enthalten. Wenn Sie die AndroidStudio-Galerie verwenden, erstellt der Assistent eine grundlegende für Sie und Sie können sehen, welche Optionen Sie haben.

  1. Das Layout der App-Leiste ist normalerweise jetzt ein android.support.design.widget.CoordinatorLayout. Dazu gehören zwei untergeordnete Elemente: ein android.support.design.widget.AppBarLayout (das eine android.support.v7.widget.Toolbar enthält) und ein <include ... >for Ihren tatsächlichen Inhalt (siehe 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. Das Inhaltslayout kann ein beliebiges Layout sein. Dies ist das Layout, das den Hauptinhalt der Aktivität enthält (ohne Navigationsleiste oder App-Leiste).

Das Coole an all dem ist, dass Sie jede Aktivität in diese beiden Layouts einbinden können, Ihre Navigationsansicht (siehe Schritt 1) ​​jedoch immer auf activity_main_drawer (oder was auch immer) zeigen muss. Dies bedeutet, dass Sie für alle Aktivitäten dieselbe (*) Navigationsleiste haben.

  • Sie werden nicht dieselbe Instanz von NavigationView sein, aber um fair zu sein, war dies selbst mit der oben beschriebenen BaseActivity-Lösung nicht möglich.

Der Stackoverflow schneidet einige der umschließenden XML-Klammern ab, aber das Wichtige ist alles da.
jwehrle

Aber wie behandeln Sie Funktionen wie Schaltflächen? Sie müssen in jeder Aktivität den gleichen Code schreiben?
Laur89

Ja, da dies separate Instanzen sind. Sie können jedoch eine Superklasse für Ihre Aktivitäten erstellen, um diesen Code zu erweitern und dort einmal abzulegen.
jwehrle

@jwehrle kannst du ein Beispiel schreiben, wie man eine Superklasse für unsere Aktivitäten macht?
CDrosos

öffentliche abstrakte Klasse MyBaseActivity erweitert AppCompatActivity implementiert NavigationView.OnNavigationItemSelectedListener {// implementiert Folgendes: Override public boolean onNavigationItemSelected (@NonNull MenuItem item) {}} öffentliche Klasse MyActivity erweitert MyBaseActivity {}
jwehrle

7

Der einfachste Weg, eine gemeinsame Navigationsleiste in einer Gruppe von Aktivitäten wiederzuverwenden

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

Können Sie ein Beispiel für eine Aktivität angeben, die diese Basisaktivität verwendet?
CDrosos

Ich kann mich an keine Details erinnern, ich denke, nur eine Erweiterung AppBaseActivity und eine setContentViewStandardmethode sollten funktionieren.
Levon Petrosyan

6

Für alle anderen, die das tun möchten, was das Originalplakat verlangt, sollten Sie Fragmente verwenden, wie Kevin es gesagt hat. Hier ist ein hervorragendes Tutorial dazu:

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

Wenn Sie stattdessen Aktivitäten anstelle von Fragmenten verwenden, tritt das Problem auf, dass die Navigationsleiste jedes Mal neu erstellt wird, wenn Sie zu einer neuen Aktivität navigieren. Dies führt jedes Mal zu einem hässlichen / langsamen Rendern der Navigationsschublade.


5

Mein Vorschlag lautet: Verwenden Sie überhaupt keine Aktivitäten, sondern Fragmente und ersetzen Sie sie in dem Container (z. B. lineares Layout), in dem Sie Ihr erstes Fragment anzeigen.

Der Code ist in Android Developer Tutorials verfügbar. Sie müssen ihn nur anpassen.

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

Es ist ratsam, dass Sie immer mehr Fragmente in Ihrer Anwendung verwenden und dass es nur vier grundlegende Aktivitäten in Ihrer Anwendung gibt, die Sie in Ihrer AndroidManifest.xml erwähnen, abgesehen von den externen (z. B. FacebookActivity):

  1. SplashActivity: Verwendet kein Fragment und das FullScreen-Design.

  2. LoginSignUpActivity: Benötigen Sie überhaupt keinen NavigationDrawer und auch keine Zurück-Schaltfläche. Verwenden Sie daher einfach die normale Symbolleiste. Es sind jedoch mindestens 3 oder 4 Fragmente erforderlich. Verwendet das No-Action-Bar-Thema

  3. HomeActivity- oder DashBoard-Aktivität: Verwendet das Thema ohne Aktionsleiste. Hier benötigen Sie eine Navigationsschublade. Alle folgenden Bildschirme sind Fragmente oder verschachtelte Fragmente bis zur Blattansicht mit der gemeinsam genutzten Schublade. Alle Einstellungen, Benutzerprofile usw. werden in dieser Aktivität als Fragmente angezeigt. Die Fragmente hier werden nicht zum hinteren Stapel hinzugefügt und über die Menüpunkte der Schublade geöffnet. Bei Fragmenten, für die anstelle der Schublade ein Zurück-Button erforderlich ist, gibt es unten eine vierte Art von Aktivität.

  4. Aktivität ohne Schublade. Diese Aktivität hat oben einen Zurück-Button und die darin enthaltenen Fragmente teilen sich dieselbe Aktionsleiste. Diese Fragmente werden dem Backstack hinzugefügt, da es einen Navigationsverlauf gibt.

[Weitere Hinweise finden Sie unter: https://stackoverflow.com/a/51100507/787399 ]

Viel Spaß beim Codieren !!


Dies ist ein älterer Beitrag. Sie können Fragmente verwenden, um sicherzustellen, dass Sie immer eine Aktivität haben. Sie ersetzen die Fragmente immer wieder in einem dafür vorgesehenen Container. Legen Sie den Backstack ein, wenn Sie eine Rückwärtsnavigation benötigen, oder fügen Sie alle Fragmente ein, wenn ein Fragment als erstes angezeigt werden soll.
Abhinav Saxena

@ Cabuxa.Mapache Bitte überprüfen Sie den angehängten Link zu meiner Antwort, um weitere Unterstützung zu erhalten. Ich habe eine gemeinsame BaseActivity verwendet, mit deren Hilfe ActionBar ToolBar und NavigatonDrawer sowie andere Komponenten in allen daran angehängten Fragmenten freigegeben werden können.
Abhinav Saxena

1

Aktualisieren Sie diesen Code in Basisaktivität. und vergessen Sie nicht, drawer_list_header in Ihre Aktivitäts-XML aufzunehmen.

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

und verwenden Sie request () nicht in Ihrer Aktivität. Trotzdem ist die Schublade beim Klicken auf das Bild nicht sichtbar. Durch Ziehen wird sie ohne Listenelemente angezeigt. Ich habe viel versucht, aber keinen Erfolg. brauche ein paar Workouts dafür ...


1

Mit der Antwort von @Kevin van Mierlo können Sie auch mehrere Schubladen implementieren. Zum Beispiel das Standardmenü auf der linken Seite (Start) und ein weiteres optionales Menü auf der rechten Seite, das nur angezeigt wird, wenn bestimmte Fragmente geladen werden.

Das habe ich geschafft.


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







    }

Verwenden Sie dies für Ihre 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>

Verwenden Sie diese Option für den Navigationsheader, wenn Sie sie verwenden möchten

<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

Ich mache es in Kotlin so:

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

Aktivitäten für die Schublade müssen dies erben BaseAppCompatActivity, super.onCreatenach dem Festlegen des Inhalts aufrufen (kann tatsächlich auf eine Init-Methode verschoben werden) und entsprechende Elemente für IDs in ihrem Layout haben


Ich wollte Ihre Lösung ausprobieren, erhalte jedoch die folgende Fehlermeldung: "Diese Aktivität verfügt bereits über eine Aktionsleiste, die vom Fensterdekor bereitgestellt wird." Ich möchte zwischen 3 Aktivitäten wechseln und jeder hat eine eigene App-Leiste. Denkst du das ist möglich?
Davoid

Ich denke, Sie müssen in diesem Fall Ihre Aktionsleiste in Fragmente verschieben. In unserer App haben wir das NoActionBar-Thema verwendet und, soweit ich mich erinnere, eine Symbolleiste zur Kompatibilität bereitgestellt.
Pavlus

@Pavlus Wie würde der Code bei der zweiten Aktivität aussehen? Klasse trackActivity: BaseAppCompatActivity () {?
Craig P

0

Meine Antwort ist nur eine konzeptionelle ohne Quellcode. Es könnte für einige Leser wie mich nützlich sein, dies zu verstehen.

Dies hängt von Ihrer anfänglichen Herangehensweise an die Architektur Ihrer App ab. Grundsätzlich gibt es zwei Ansätze.

  1. Sie erstellen eine Aktivität (Basisaktivität) und alle anderen Ansichten und Bildschirme sind Fragmente. Diese Basisaktivität enthält die Implementierung für Schubladen- und Koordinatorlayouts. Dies ist eigentlich meine bevorzugte Methode, da kleine, in sich geschlossene Fragmente die App-Entwicklung einfacher und reibungsloser machen.

  2. Wenn Sie Ihre App-Entwicklung mit Aktivitäten gestartet haben, eine für jeden Bildschirm, erstellen Sie wahrscheinlich eine Basisaktivität, und alle anderen Aktivitäten erstrecken sich davon. Die Basisaktivität enthält den Code für die Implementierung von Schubladen und Koordinatoren. Jede Aktivität, die eine Schubladenimplementierung erfordert, kann sich von der Basisaktivität erstrecken.

Ich persönlich würde es vorziehen, Fragmente und Aktivitäten zu vermeiden, die ohne Organisation gemischt werden. Das macht die Entwicklung schwieriger und bringt Sie irgendwann zum Stillstand. Wenn Sie dies getan haben, überarbeiten Sie Ihren Code.


-1

Erstellen Sie eine Navigationsleiste in Ihrer MainActivity mithilfe eines Fragments.
Initialisieren Sie die Navigationsschublade in MainActivity
jetzt in allen anderen Aktivitäten, die Sie für dieselbe Navigationsschublade verwenden möchten. Setzen Sie DrawerLayout als Basis und Fragment als Navigationsschublade. Setzen Sie einfach android: name in Ihrem Fragment, der auf Ihre Fragment-Java-Datei verweist. Sie müssen das Fragment in anderen Aktivitäten nicht initialisieren.
Sie können auf Nav Drawer zugreifen, indem Sie in anderen Aktivitäten wie in der Google Play Store-App wischen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.