Один и тот же навигационный ящик в разных действиях


206

Я сделал рабочий ящик навигации, как показано в учебнике на сайте developer.android.com . Но теперь я хочу использовать один Навигационный ящик, который я создал в NavigationDrawer.class для нескольких действий в моем приложении.

Мой вопрос заключается в том, может ли кто-нибудь здесь создать небольшой учебник, в котором объясняется, как использовать один ящик навигации для нескольких действий.

Сначала я прочитал его в этом ящике для ответов Android на несколько действий

но это не сработало в моем проекте

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

В этом действии я хочу иметь Навигационный ящик, поэтому я расширяю 'NavigationDrawer', а в некоторых других видах деятельности я хочу использовать тот же ящик навигации

  public class SampleActivity extends NavigationDrawer {...}

Я не знаю, что изменить ...


1
Вы можете найти примеры здесь .
Надди

1
Вы можете найти по
адресу

Ответы:


188

Если вы хотите навигационный ящик, вы должны использовать фрагменты. Я следовал этому уроку на прошлой неделе, и он прекрасно работает:

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

Вы также можете загрузить пример кода из этого учебного пособия, чтобы увидеть, как это можно сделать.


Без фрагментов:

Это ваш код 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);
    }
}

Все остальные действия, для которых требуется навигационный ящик, должны расширять это действие вместо самого действия, например:

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>

Редактировать:

Я сам испытал некоторые трудности, так что вот решение, если вы получаете NullPointerExceptions. В BaseActivity измените функцию onCreate на protected void onCreateDrawer(). Остальные могут остаться прежними. В действиях, расширяющих BaseActivity, поместите код в следующем порядке:

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

Это помогло мне решить мою проблему, надеюсь, это поможет!

Вот как вы можете создать навигационный ящик с несколькими действиями, если у вас есть какие-либо вопросы, не стесняйтесь задавать.


Изменить 2:

Как сказал @GregDan, вы BaseActivityтакже можете переопределить setContentView()и вызвать onCreateDrawer:

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

7
Я не хочу использовать действия над фрагментами, я просто хочу использовать разные действия, которые используют один и тот же блок навигации. Я хочу активности, потому что там я могу использовать различные типы макетов, например, пролистывание, просмотр карты ...
MEX

135
Наличие только одного Activity может быть сложной задачей для любого довольно сложного приложения. Использование Деятельности дает вам много бесплатных вещей из системы - так что это правильный момент, как использовать несколько Активностей. Я не могу представить, чтобы один Activity обрабатывал связь между любым количеством комбинаций фрагментов - он просто не сработает.
Слот

1
Мне жаль, что я так долго отвечал. Я отредактировал свой ответ. Я считаю, что это учебник, который вы искали. Надеюсь это поможет.
Кевин ван Миерло

2
@KevinvanMierlo, можете ли вы сказать мне, что вы подразумеваете под: R.id.drawer_layout должен быть в каждом действии с точно таким же идентификатором. Потому что я сделал именно то, что вы сказали здесь, и я получил NullPointerException в методе onCreate () класса Activity, который расширяет этот BaseActivity ..
Loolooii

1
@KevinvanMierlo Кстати, я думаю, что вы забыли эти 2 строки? super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii

34

Я нашел лучшую реализацию. Это в Google I / O 2014 .

Они используют тот же подход, что и Кевин. Если вы можете абстрагироваться от всего ненужного в приложении ввода-вывода, вы можете извлечь все, что вам нужно, и Google уверен, что это правильное использование шаблона навигационной панели. Каждое действие может иметь DrawerLayoutсвой основной макет. Интересная часть - как осуществляется переход на другие экраны. Это реализовано 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;

Это отличается от обычного способа замены текущего фрагмента транзакцией фрагмента. Но пользователь не видит визуальной разницы.


Это ... Я не могу понять, как они начинают новые действия, и это работает безупречно. Это большое приложение для работы.
hitch.united

@ hitch.united Это потому, что они используют много фрагментов и всего несколько действий.
Хоакин Иурчук

@ hitch.united они, вероятно, перекрывают анимацию действия с overridePendingTransitions.
EpicPandaForce

Загрузка фрагментов вместо операций с подклассами?
Викас Пандей

Вот файл с октября 2014 года: github.com/google/iosched/blob/...
denvercoder9

8

Так что этот ответ опоздал на несколько лет, но кто-то может оценить его. Android предоставил нам новый виджет, который облегчает использование одного навигационного ящика с несколькими действиями.

android.support.design.widget.NavigationView является модульным и имеет собственный макет в папке меню. То, как вы его используете, заключается в следующем:

  1. Корневой макет - это android.support.v4.widget.DrawerLayout, который содержит двух дочерних элементов: <include ... />оборачиваемый макет (см. 2) и 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 - это просто LinearLayout с ориентацией = вертикали для заголовка вашего Навигационного Рисунка.

Activity_main_drawer - это xml меню в вашем каталоге res / menu. Он может содержать элементы и группы по вашему выбору. Если вы используете AndroidStudio Gallery, мастер сделает для вас базовую галерею, и вы увидите, какие у вас есть варианты.

  1. Макет панели приложения обычно теперь представляет собой android.support.design.widget.CoordinatorLayout, и он будет включать двух дочерних элементов: android.support.design.widget.AppBarLayout (который содержит android.support.v7.widget.Toolbar) и <include ... >для ваш фактический контент (см. 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. Макет контента может быть любым макетом, который вы хотите. Это макет, который содержит основное содержание действия (не включая панель навигации или панель приложения).

Теперь, во всем этом круто то, что вы можете обернуть каждое действие в эти два макета, но ваш NavigationView (см. Шаг 1) всегда указывает на activity_main_drawer (или что-то еще). Это означает, что у вас будет один и тот же (*) Навигационный ящик для всех видов деятельности.

  • Это не будет тот же экземпляр NavigationView, но, честно говоря, это было невозможно даже с решением BaseActivity, описанным выше.

StackOverflow обрезает некоторые из скобок XML, но важные вещи все есть.
17

а как вы относитесь к функциональности как к кнопкам? Вы должны написать один и тот же код в каждой деятельности?
Laur89

Да, потому что это отдельные случаи. Тем не менее, вы можете создать суперкласс для ваших действий, чтобы расширить и поместить этот код там один раз.
jwehrle

@jwehrle Можете ли вы написать пример о создании суперкласса для нашей деятельности?
CDrosos

открытый абстрактный класс MyBaseActivity расширяет AppCompatActivity реализует NavigationView.OnNavigationItemSelectedListener {// реализует следующее: переопределяет public boolean onNavigationItemSelected (@NonNull MenuItem item) {}} открытый класс MyActivity расширяет MyBaseActivity {}
jwehrle

7

Самый простой способ повторно использовать общий блок навигации в группе действий

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

Можете ли вы привести пример действия, которое использует это базовое действие?
CDrosos

На самом деле не могу вспомнить какие-либо подробности об этом, я думаю, что должно работать только расширение AppBaseActivity и setContentViewстандартный способ.
Левон Петросян

6

Для тех, кто хочет сделать то, о чем просит оригинальный постер, рассмотрите возможность использования фрагментов вместо того, как сказал Кевин. Вот отличное руководство о том, как это сделать:

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

Если вы решите использовать действия вместо фрагментов, вы столкнетесь с проблемой повторного создания навигационной панели каждый раз, когда вы переходите к новому действию. Это приводит к уродливой / медленной визуализации навигационного ящика каждый раз.


5

Мое предложение: вообще не используйте действия, вместо этого используйте фрагменты и заменяйте их в контейнере (например, в Linear Layout), где вы показываете свой первый фрагмент.

Код доступен в учебниках по Android для разработчиков, вам просто нужно его настроить.

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

Желательно, чтобы вы использовали все больше и больше фрагментов в вашем приложении, и должно быть только четыре основных действия, локальных для вашего приложения, которые вы упомянули в вашем AndroidManifest.xml, помимо внешних (например, FacebookActivity):

  1. SplashActivity: не использует фрагмент и использует тему FullScreen.

  2. LoginSignUpActivity: вообще не требует NavigationDrawer и никакой кнопки «назад», поэтому просто используйте обычную панель инструментов, но, как минимум, потребуется 3 или 4 фрагмента. Используется тема без действия бара

  3. HomeActivity или DashBoard Activity: используется тема без действия бара. Здесь вам требуется блок навигации, также все последующие экраны будут фрагментами или вложенными фрагментами, вплоть до представления листа, с общим блоком. Все настройки, профиль пользователя и т. Д. Будут представлены здесь как фрагменты в этом упражнении. Фрагменты здесь не будут добавлены в задний стек и будут открываться из пунктов меню ящика. В случае фрагментов, которые требуют кнопку возврата вместо ящика, ниже есть четвертый вид деятельности.

  4. Деятельность без ящика. В этом упражнении кнопка «Назад» сверху и фрагменты внутри будут использовать одну и ту же панель действий. Эти фрагменты будут добавлены в бэк-стек, так как там будет история переходов.

[Для получения дальнейших указаний см .: https://stackoverflow.com/a/51100507/787399 ]

Удачного кодирования!


Это старый пост. Вы можете использовать фрагменты, чтобы всегда иметь один вид деятельности. Вы продолжаете заменять фрагменты в одном специальном контейнере. Поместите обратно в стек, если вам нужна обратная навигация, или извлеките все фрагменты, когда вам нужно, чтобы фрагмент отображался как первый.
Абхинав Саксена

@ Cabuxa.Mapache Пожалуйста, проверьте прикрепленную ссылку на мой ответ для получения дополнительной помощи. Я взял общий BaseActivity, который помогает совместно использовать ActionBar ToolBar и NavigatonDrawer и другие компоненты во всех прикрепленных к нему фрагментах.
Абхинав Саксена

1

обновить этот код в базовой активности. и не забудьте включить в список действий xml.

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

и не используйте request () в своей деятельности. но все еще ящик не виден при нажатии на изображение .. и при перетаскивании он будет виден без элементов списка. Я много пробовал, но безуспешно. нужны тренировки для этого ...


1

С ответом @Kevin van Mierlo вы также можете реализовать несколько ящиков. Например, меню по умолчанию, расположенное слева (начало), и дополнительное меню, расположенное справа, которое отображается только при загрузке определенных фрагментов.

Я был в состоянии сделать это.


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







    }

используйте это для вашего 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>

используйте это для заголовка навигации, если хотите использовать

<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

Я делаю это в Котлине так:

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

Действия для ящика должны наследовать это BaseAppCompatActivity, вызывать super.onCreateпосле того, как контент установлен (на самом деле, может быть перемещен в какой-то метод init) и иметь соответствующие элементы для идентификаторов в их макете


Я хотел попробовать ваше решение, но я получаю эту ошибку: «В этом действии уже есть панель действий, предоставляемая декором окна». Я хочу переключаться между 3 видами деятельности, и у каждого есть своя панель приложений. Как вы думаете, это возможно?
Давид

Я думаю, вам нужно переместить панель действий на фрагменты в этом случае. Насколько я помню, в нашем приложении мы использовали тему NoActionBar и предоставили панель инструментов для совместимости.
Pavlus

@Pavlus как будет выглядеть код на втором занятии? class trackActivity: BaseAppCompatActivity () {?
Крейг П

0

Мой ответ - просто концептуальный, без какого-либо исходного кода. Это может быть полезно для некоторых читателей, как я, чтобы понять.

Это зависит от вашего первоначального подхода к архитектуре вашего приложения. Есть в основном два подхода.

  1. Вы создаете одно действие (базовое действие), а все остальные виды и экраны будут фрагментами. Это базовое действие содержит реализацию макетов «Ящик» и «Координатор». На самом деле это мой предпочтительный способ сделать, потому что наличие небольших автономных фрагментов сделает разработку приложений более легкой и гладкой.

  2. Если вы начали разработку приложения с действий, по одному для каждого экрана, то вы, вероятно, создадите базовое действие, а все остальные действия будут исходить из него. Базовое действие будет содержать код для реализации в комитете и координаторе. Любое действие, для которого требуется реализация ящика, может выходить за пределы базового действия.

Я лично предпочел бы избегать использования фрагментов и действий, смешанных без какой-либо организации. Это усложняет разработку и в конечном итоге застревает. Если вы сделали это, рефакторинг вашего кода.


-1

Создайте навигационный ящик в вашей MainActivity, используя фрагмент.
Инициализируйте Навигационный ящик в MainActivity
теперь во всех других действиях, для которых вы хотите использовать тот же Навигационный ящик, поместите DrawerLayout в качестве основы и фрагмент в качестве ящика навигации. Просто установите android: имя в вашем фрагменте, указывающее на ваш фрагмент Java-файла. Вам не нужно инициализировать фрагмент в других действиях.
Вы можете получить доступ к Nav Drawer, проводя в других действиях, как в приложении Google Play Store

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.