Mesma gaveta de navegação em diferentes atividades

206

Fiz uma gaveta de navegação funcional, como mostra o tutorial no developer.android.com site . Mas agora, quero usar uma gaveta de navegação, criada no NavigationDrawer.class para várias atividades no meu aplicativo.

Minha pergunta é: se alguém aqui puder fazer um pequeno Tutorial, que explica, como usar uma gaveta de Navegação para várias Atividades.

Eu o li primeiro nesta resposta Android Navigation Drawer on multiple Activities

mas não funcionou no meu projeto

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

Nesta atividade, eu quero ter a gaveta de navegação, então eu estendo 'NavigationDrawer' e, em algumas outras atividades, eu quero usar a mesma gaveta de navegação

  public class SampleActivity extends NavigationDrawer {...}

Não sei o que mudar ...

MEX
fonte
1
Você pode encontrar os exemplos aqui .
Naddy 07/07
1
você pode encontrar em: stackoverflow.com/questions/33009469/…
varotariya vajsi

Respostas:

188

Se você quiser uma gaveta de navegação, use fragmentos. Eu segui este tutorial na semana passada e funciona muito bem:

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

Você também pode fazer o download do código de amostra deste tutorial, para ver como fazer isso.


Sem fragmentos:

Este é o seu código 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);
    }
}

Todas as outras atividades que precisam ter uma gaveta de navegação devem estender esta atividade em vez da própria atividade, exemplo:

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>

Editar:

Eu mesmo tive algumas dificuldades, então aqui está uma solução se você receber NullPointerExceptions. Em BaseActivity, altere a função onCreate para protected void onCreateDrawer(). O resto pode permanecer o mesmo. Nas atividades que estendem BaseActivity, coloque o código nesta ordem:

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

Isso me ajudou a resolver meu problema, espero que ajude!

É assim que você pode criar uma gaveta de navegação com várias atividades, se tiver alguma dúvida, não hesite em perguntar.


Edição 2:

Como dito por @GregDan, você BaseActivitytambém pode substituir setContentView()e chamar onCreateDrawer lá:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}
Kevin van Mierlo
fonte
7
Não quero usar atividades sobre fragmentos, só quero usar atividades diferentes que usem a mesma gaveta de navegação. Quero atividade, porque lá posso usar diferentes tipos de layout, como exibição de furto, exibição de mapa ...
MEX
135
Ter apenas uma atividade pode ser uma tarefa assustadora para qualquer aplicativo bastante complexo. O uso de atividades oferece muitas coisas gratuitas do sistema - portanto, é um ponto válido como usar várias atividades. Não consigo imaginar uma atividade manipulando a comunicação entre qualquer número de combinações de fragmentos - simplesmente não vai funcionar.
Slott
1
Me desculpe, demorou tanto tempo para eu responder. Eu editei minha resposta. Eu acredito que este é o tutorial que você estava procurando. Espero que isto ajude.
Kevin van Mierlo
2
@ KevinvanMierlo, você pode me dizer o que você quer dizer com: R.id.drawer_layout deve estar em todas as atividades com exatamente o mesmo ID. Porque eu fiz exatamente o que você disse aqui e eu recebo um NullPointerException no método onCreate () da atividade que estende esta BaseActivity ..
Loolooii
1
@KevinvanMierlo btw, acho que você esqueceu essas duas linhas? super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii
34

Eu encontrei a melhor implementação. Está no Google I / O 2014 aplicativo .

Eles usam a mesma abordagem que a de Kevin. Se você puder se abstrair de todas as coisas desnecessárias no aplicativo de E / S, poderá extrair tudo o que precisa e é garantido pelo Google que é um uso correto do padrão da gaveta de navegação. Cada atividade opcionalmente tem um DrawerLayoutcomo layout principal. A parte interessante é como é feita a navegação para outras telas. É implementado da BaseActivityseguinte maneira:

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

Isso difere da maneira comum de substituir o fragmento atual por uma transação de fragmento. Mas o usuário não vê diferença visual.

Cavaleiro do Vento
fonte
Isso ... eu não consigo descobrir como eles iniciam novas atividades e isso funciona perfeitamente. É um aplicativo grande para trabalhar.
Html.united
@ hitch.united Isso ocorre porque eles usam muitos fragmentos e apenas algumas atividades.
Joaquin Iurchuk
@ hitch.united eles provavelmente substituem a animação da atividade por overridePendingTransitions.
EpicPandaForce
está carregando fragmentos em vez de atividades de subclasse?
Vikas Pandey
Aqui está o arquivo de outubro de 2014: github.com/google/iosched/blob/…
denvercoder9
8

Portanto, esta resposta está atrasada alguns anos, mas alguém pode apreciá-la. O Android nos deu um novo widget que facilita o uso de uma gaveta de navegação com várias atividades.

android.support.design.widget.NavigationView é modular e possui seu próprio layout na pasta de menus. A maneira como você o usa é agrupar layouts de xml da seguinte maneira:

  1. O Layout da raiz é um android.support.v4.widget.DrawerLayout que contém dois filhos: um <include ... />para o layout que está sendo agrupado (consulte 2) e um 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 é apenas um LinearLayout com orientação = vertical para o cabeçalho do seu Drawar de navegação.

activity_main_drawer é um xml de menu no diretório res / menu. Pode conter itens e grupos de sua escolha. Se você usar a Galeria AndroidStudio, o assistente fará uma escolha básica para você e você poderá ver quais são suas opções.

  1. O layout da barra de aplicativos agora é agora um android.support.design.widget.CoordinatorLayout e isso inclui dois filhos: um android.support.design.widget.AppBarLayout (que contém uma android.support.v7.widget.Toolbar) e um <include ... >for seu conteúdo real (consulte 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. O layout do conteúdo pode ser o layout que você deseja. Esse é o layout que contém o conteúdo principal da atividade (sem incluir a gaveta de navegação ou a barra de aplicativos).

Agora, o mais interessante disso tudo é que você pode agrupar cada atividade nesses dois layouts, mas ter o NavigationView (consulte a etapa 1) sempre apontar para activity_main_drawer (ou o que for). Isso significa que você terá a mesma gaveta de navegação (*) em todas as atividades.

  • Eles não serão a mesma instância do NavigationView, mas, para ser justo, isso não foi possível, mesmo com a solução BaseActivity descrita acima.
jwehrle
fonte
O stackoverflow está cortando alguns dos colchetes xml anexos, mas o material importante está lá.
jwehrle
mas como você trata a funcionalidade como botões? você deve escrever o mesmo código em todas as atividades?
Laur89
Sim, porque são instâncias separadas. No entanto, você pode criar uma super classe para suas atividades estender e colocar esse código lá uma vez.
jwehrle
@jwehrle, você pode escrever um exemplo sobre como fazer uma super turma para nossas atividades?
CDrosos
classe abstrata pública MyBaseActivity estende AppCompatActivity implementa NavigationView.OnNavigationItemSelectedListener {// implementa o seguinte: Substitua o público booleano onNavigationItemSelected (@NonNull MenuItem item) {}} classe pública MyActivity estende MyBaseActivity {}
jwehrle
7

A maneira mais fácil de reutilizar uma gaveta comum do Navigation entre um grupo de atividades

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;
    }
}
Levon Petrosyan
fonte
Você pode fornecer um exemplo de atividade que usa essa atividade base?
CDrosos
Na verdade, não consigo me lembrar de nenhum detalhe sobre isso, acho que apenas a extensão AppBaseActivity e a setContentViewmaneira padrão devem funcionar.
Levon Petrosyan
6

Para quem quiser fazer o que o pôster original está pedindo, considere usar fragmentos da maneira que Kevin disse. Aqui está um excelente tutorial sobre como fazer isso:

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

Se você optar por usar atividades em vez de fragmentos, encontrará o problema de a gaveta de navegação ser recriada toda vez que você navegar para uma nova atividade. Isso resulta em uma renderização feia / lenta da gaveta de navegação a cada vez.

Micro
fonte
5

Minha sugestão é: não use atividades, use fragmentos e substitua-os no contêiner (layout linear, por exemplo), onde você mostra seu primeiro fragmento.

O código está disponível nos Tutoriais para desenvolvedores Android, você só precisa personalizar.

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

É aconselhável usar cada vez mais fragmentos em seu aplicativo e deve haver apenas quatro atividades básicas locais, mencionadas no AndroidManifest.xml, além das externas (FacebookActivity, por exemplo):

  1. SplashActivity: não usa fragmentos e usa o tema Tela Inteira.

  2. LoginSignUpActivity: Não requer o NavigationDrawer, e também nenhum botão de retorno; basta usar a barra de ferramentas normal, mas serão necessários pelo menos 3 ou 4 fragmentos. Usa o tema sem barra de ação

  3. Atividade HomeActivity ou DashBoard: Usa o tema sem barra de ação. Aqui você precisa da gaveta Navegação, todas as telas a seguir serão fragmentos ou fragmentos aninhados, até a visualização em folha, com a gaveta compartilhada. Todas as configurações, perfil do usuário e etc. estarão aqui como fragmentos nesta atividade. Os fragmentos aqui não serão adicionados à pilha traseira e serão abertos nos itens de menu da gaveta. No caso de fragmentos que exijam o botão Voltar em vez da gaveta, há um quarto tipo de atividade abaixo.

  4. Atividade sem gaveta. Esta atividade tem um botão voltar na parte superior e os fragmentos dentro compartilharão a mesma barra de ação. Esses fragmentos serão adicionados à pilha traseira, pois haverá um histórico de navegação.

[Para obter mais orientações, consulte: https://stackoverflow.com/a/51100507/787399 ]

Feliz codificação !!

Abhinav Saxena
fonte
Esta é uma postagem mais antiga. Você pode usar fragmentos para garantir que você tenha uma atividade sempre. Você continua substituindo os fragmentos em um contêiner dedicado a ele. Coloque a pilha de volta quando precisar de navegação para trás ou pop todos os fragmentos quando precisar que um fragmento seja mostrado como o primeiro.
Abhinav Saxena
@ Cabuxa.Mapache Verifique o link em anexo da minha resposta para obter mais assistência. Peguei uma BaseActivity comum, que ajuda a compartilhar o ActionBar ToolBar, o NavigatonDrawer e outros componentes em todos os fragmentos anexados a ele.
Abhinav Saxena
1

atualize esse código na atividade básica. e não se esqueça de incluir drawer_list_header no seu xml de atividade.

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

e não use request () em sua atividade. mas a gaveta ainda não está visível ao clicar na imagem .. e arrastando-a ficará visível sem itens da lista. Eu tentei muito, mas sem sucesso. precisa de alguns exercícios para isso ...

MS Gadag
fonte
1

Com a resposta de @Kevin van Mierlo, você também é capaz de implementar várias gavetas. Por exemplo, o menu padrão localizado no lado esquerdo (iniciar) e outro menu opcional, localizado no lado direito, que é mostrado apenas quando fragmentos determinados são carregados.

Eu fui capaz de fazer isso.

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







    }

use isso para o seu 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>

use isso no cabeçalho de navegação se quiser usar

<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>
Volverine
fonte
1

Eu faço isso no Kotlin assim:

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

As atividades da gaveta devem herdar isso BaseAppCompatActivity, chamar super.onCreatedepois que o conteúdo é definido (na verdade, pode ser movido para algum método init) e ter elementos correspondentes para os IDs em seu layout

Pavlus
fonte
Queria tentar sua solução, mas recebi o seguinte erro: "Esta atividade já possui uma barra de ação fornecida pela decoração da janela". Quero alternar entre três atividades e o outro tem sua própria barra de aplicativos. Você acha que é possível ?
davoid
Eu acho que você precisa mover sua barra de ação para fragmentos nesse caso. Em nosso aplicativo, usamos o tema NoActionBar e fornecemos barra de ferramentas para compatibilidade, tanto quanto me lembro.
Pavlus
@ Pavlus como seria o código na segunda atividade? classe trackActivity: BaseAppCompatActivity () {?
Craig P
0

Minha resposta é apenas conceitual, sem nenhum código fonte. Pode ser útil para alguns leitores como eu entender.

Depende da sua abordagem inicial de como você arquiteta seu aplicativo. Existem basicamente duas abordagens.

  1. Você cria uma atividade (atividade base) e todas as outras visualizações e telas serão fragmentos. Essa atividade base contém a implementação dos Layouts de gaveta e coordenador. Na verdade, é a minha maneira preferida de fazer, porque ter pequenos fragmentos independentes tornará o desenvolvimento de aplicativos mais fácil e suave.

  2. Se você iniciou o desenvolvimento do aplicativo com atividades, uma para cada tela, provavelmente criará uma atividade básica e todas as outras atividades se estendem a partir dela. A atividade base conterá o código para a implementação da gaveta e do coordenador. Qualquer atividade que precise da implementação da gaveta pode se estender da atividade básica.

Eu pessoalmente preferiria evitar usar fragmentos e atividades misturadas sem nenhuma organização. Isso dificulta o desenvolvimento e, eventualmente, você fica preso. Se você tiver feito isso, refatorar seu código.

Farruh Habibullaev
fonte
-1

Crie a gaveta de navegação em sua MainActivity usando fragmento.
Inicialize a gaveta de navegação no MainActivity
agora em todas as outras atividades que você deseja usar a mesma gaveta de navegação, coloque DrawerLayout como base e fragmento como gaveta de navegação. Basta definir android: name no seu fragmento apontando para o seu arquivo Java do fragmento. Você não precisará inicializar o fragmento em outras atividades.
Você pode acessar o Nav Drawer deslizando em outras atividades, como no aplicativo Google Play Store

droidlabel
fonte