如何在android中创建自定义导航抽屉

Posted

技术标签:

【中文标题】如何在android中创建自定义导航抽屉【英文标题】:How to create a custom navigation drawer in android 【发布时间】:2014-03-14 19:24:34 【问题描述】:

您好,我正在尝试创建一个类似于 gmail 应用程序导航抽屉的导航抽屉。我关注开发者网站,但它只指定基本实现。但我需要根据我的规范自定义导航。

    我需要添加一个标题来对抽屉中的列表项进行分类 我需要一个单选按钮来选择我的一些选项

我该怎么做?

【问题讨论】:

【参考方案1】:

教程android Custom Navigation Drawer (via archive.org) 包含一个basic 和一个custom 项目。后者显示了如何设置导航抽屉,如屏幕截图所示:

source code of the projects (via archive.org) 可供下载。


这也是Navigation Drawer - Live-O 项目...

source code of the project 可在 GitHub 上找到。


MaterialDrawer library 旨在为您的应用程序提供最简单的导航抽屉实现。它提供了大量开箱即用的自定义,还包括一个易于使用的标题,可用作 AccountSwitcher。


请注意Android Studio同时有一个模板项目来创建一个Navigation Drawer Activity,如截图所示。

此repository 跟踪对模板所做的更改。

【讨论】:

我有类似和奇怪的问题:***.com/questions/24863616/…:我设法让抽屉工作,但有几个错误。不知道如何解决? 好的!我知道我可以在 android studio 中简单地做到这一点,但是如果我要更改导航抽屉字体呢? @AmirH 请在 *** 上打开一个新问题。 @JJD,请更新源代码链接。好像坏了downloads.tutecentral.com/wp-content/uploads/2014/02/… @user5038993 我对此无能为力。建议您联系文章作者或留言on the website。【参考方案2】:

我使用了下面的布局,可以在导航视图中实现自定义布局。

<android.support.design.widget.NavigationView
        android:id="@+id/navi_view"
        android:layout_
        android:layout_
        android:layout_gravity="start|top"
        android:background="@color/navigation_view_bg_color"
        app:theme="@style/NavDrawerTextStyle">

        <LinearLayout
            android:layout_
            android:layout_
            android:orientation="vertical">

            <include layout="@layout/drawer_header" />

            <include layout="@layout/navigation_drawer_menu" />
        </LinearLayout>
</android.support.design.widget.NavigationView> 

【讨论】:

我如何访问@layout/drawer_heade活动中的项目【参考方案3】:

对我来说更简单的解决方案是:

注意事项:

此解决方案需要自动生成的导航抽屉活动 由 Android Studio 提供。 类DrawerItemCustomDrawerAdapter 和布局custom_drawer_item.xml 取自this tutorial。

1.创建这个类来包装自定义抽屉项:

public class DrawerItem 

  String ItemName;
  int imgResID;

  public DrawerItem(String itemName, int imgResID) 
        super();
        ItemName = itemName;
        this.imgResID = imgResID;
  

  public String getItemName() 
        return ItemName;
  
  public void setItemName(String itemName) 
        ItemName = itemName;
  
  public int getImgResID() 
        return imgResID;
  
  public void setImgResID(int imgResID) 
        this.imgResID = imgResID;
  

2。为您的抽屉项目创建自定义布局 (custom_drawer_item.xml):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

<LinearLayout
    android:id="@+id/itemLayout"
    android:layout_
    android:layout_
    android:layout_alignParentLeft="true"
    android:orientation="vertical"
    android:layout_marginTop="0dp"
    android:background="?android:attr/activatedBackgroundIndicator">

    <LinearLayout
        android:layout_
        android:layout_
        android:minHeight="55dp">

        <ImageView
            android:id="@+id/drawer_icon"
            android:layout_
            android:layout_/>

        <TextView
            android:id="@+id/drawer_itemName"
            android:layout_
            android:layout_
            android:textAppearance="?android:attr/textAppearanceLarge"/>
    </LinearLayout>

    <View
        android:layout_
        android:layout_
        android:layout_marginBottom="1dp"
        android:layout_marginTop="1dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="#DADADC">
    </View>
</LinearLayout>
</RelativeLayout>

3.创建您的自定义适配器:

import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class CustomDrawerAdapter extends ArrayAdapter<DrawerItem> 

Context context;
List<DrawerItem> drawerItemList;
int layoutResID;

public CustomDrawerAdapter(Context context, int layoutResourceID, List<DrawerItem> listItems) 
    super(context, layoutResourceID, listItems);
    this.context = context;
    this.drawerItemList = listItems;
    this.layoutResID = layoutResourceID;


@Override
public View getView(int position, View convertView, ViewGroup parent) 
    // TODO Auto-generated method stub

    DrawerItemHolder drawerHolder;
    View view = convertView;

    if (view == null) 
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        drawerHolder = new DrawerItemHolder();

        view = inflater.inflate(layoutResID, parent, false);
        drawerHolder.ItemName = (TextView)view.findViewById(R.id.drawer_itemName);
        drawerHolder.icon = (ImageView) view.findViewById(R.id.drawer_icon);

        view.setTag(drawerHolder);

     else 
        drawerHolder = (DrawerItemHolder) view.getTag();
    

    DrawerItem dItem = (DrawerItem) this.drawerItemList.get(position);

    drawerHolder.icon.setImageDrawable(view.getResources().getDrawable(
            dItem.getImgResID()));
    drawerHolder.ItemName.setText(dItem.getItemName());

    return view;


private static class DrawerItemHolder 
    TextView ItemName;
    ImageView icon;


4.在自动生成的NavigationDrawerFragmentonCreateView 方法中,为此替换自动生成的适配器:

ArrayList<DrawerItem> dataList = new ArrayList<DrawerItem>();
dataList.add(new DrawerItem(getString(R.string.title_section1), R.drawable.ic_action_1));
dataList.add(new DrawerItem(getString(R.string.title_section2), R.drawable.ic_action_2));
dataList.add(new DrawerItem(getString(R.string.title_section3), R.drawable.ic_action_3));

mDrawerListView.setAdapter(new CustomDrawerAdapter(
        getActivity(),
        R.layout.custom_drawer_item,
        dataList));

记住将R.string.title_sectionNR.drawable.ic_action_N 替换为您自己的资源。

【讨论】:

【参考方案4】:

一旦您知道它是如何实现的,您就可以轻松地自定义 android Navigation 抽屉。这是一个不错的tutorial,您可以在其中进行设置。

这将是您的 mainXML 的结构:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_
    android:layout_>

    <!-- Framelayout to display Fragments -->
    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_
        android:layout_ />

    <!-- Listview to display slider menu -->
    <ListView
        android:id="@+id/list_slidermenu"
        android:layout_
        android:layout_
        android:layout_gravity="right"
        android:choiceMode="singleChoice"
        android:divider="@color/list_divider"
        android:dividerHeight="1dp"        
        android:listSelector="@drawable/list_selector"
        android:background="@color/list_background"/>
</android.support.v4.widget.DrawerLayout>

您可以通过添加标题来根据自己的喜好自定义此列表视图。和单选按钮。

【讨论】:

【参考方案5】:

使用 Activity 的 Android 导航抽屉 我只是按照示例:http://antonioleiva.com/navigation-view/

您只需要少量定制:

public class MainActivity extends AppCompatActivity  

public static final String AVATAR_URL = "http://lorempixel.com/200/200/people/1/";


private DrawerLayout drawerLayout;
private View content;
private Toolbar toolbar;
private NavigationView navigationView;
private ActionBarDrawerToggle drawerToggle;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dashboard);
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    initToolbar();
    setupDrawerLayout();

    content = findViewById(R.id.content);
    drawerToggle = setupDrawerToggle();
    final ImageView avatar = (ImageView) navigationView.getHeaderView(0).findViewById(R.id.avatar);
    Picasso.with(this).load(AVATAR_URL).transform(new CircleTransform()).into(avatar);





private void initToolbar() 
    final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    final ActionBar actionBar = getSupportActionBar();

    if (actionBar != null) 
        actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_black_24dp);
        actionBar.setDisplayHomeAsUpEnabled(true);
    

private ActionBarDrawerToggle setupDrawerToggle() 
    return new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open,  R.string.drawer_close);


   @Override
protected void onPostCreate(Bundle savedInstanceState) 
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    drawerToggle.syncState();


@Override
public void onConfigurationChanged(Configuration newConfig) 
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggles
    drawerToggle.onConfigurationChanged(newConfig);

 private void setupDrawerLayout() 

    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    navigationView = (NavigationView) findViewById(R.id.navigation_view);

    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() 

        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) 

            int id = menuItem.getItemId();

          switch (id) 
                case R.id.drawer_home:
                    Intent i = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(i);
                    finish();
                    break;
                case R.id.drawer_favorite:
                    Intent j = new Intent(getApplicationContext(), SecondActivity.class);
                    startActivity(j);
                    finish();
                    break;

            


        return true;
    
);

这是xml布局

<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
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_
android:layout_
android:fitsSystemWindows="true"
tools:context=".MainActivity">

<FrameLayout
    android:id="@+id/content"
    android:layout_
    android:layout_>



    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_
        android:layout_
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways|snap" />

    </android.support.design.widget.AppBarLayout>



</FrameLayout>

<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_
    android:layout_
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:menu="@menu/drawer"/>

在菜单中添加drawer.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<group
    android:checkableBehavior="single">

    <item
        android:id="@+id/drawer_home"
        android:checked="true"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/home"/>

    <item
        android:id="@+id/drawer_favourite"
        android:icon="@drawable/ic_favorite_black_24dp"
        android:title="@string/favourite"/>
    ...

    <item
        android:id="@+id/drawer_settings"
        android:icon="@drawable/ic_settings_black_24dp"
        android:title="@string/settings"/>

</group>

要打开和关闭抽屉,请在 string.xml 中添加此值

<string name="drawer_open">Open</string>
<string name="drawer_close">Close</string>

抽屉.xml

enter code here

<ImageView
    android:id="@+id/avatar"
    android:layout_
    android:layout_
    android:layout_margin="@dimen/spacing_large"
    android:elevation="4dp"
    tools:src="@drawable/ic_launcher"/>

<TextView
    android:layout_
    android:layout_
    android:layout_above="@+id/email"
    android:layout_marginLeft="@dimen/spacing_large"
    android:layout_marginStart="@dimen/spacing_large"
    android:text="Username"
    android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
<TextView
    android:id="@+id/email"
    android:layout_
    android:layout_
    android:layout_alignParentBottom="true"
    android:layout_marginLeft="@dimen/spacing_large"
    android:layout_marginStart="@dimen/spacing_large"
    android:layout_marginBottom="@dimen/spacing_large"
    android:text="username@mymail.com"
    android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>

【讨论】:

【参考方案6】:

我需要添加一个标题来对抽屉中的列表项进行分类

自定义listView或使用expandableListView

我需要一个单选按钮来选择我的一些选项

您可以在不修改NavigationDrawer 的当前实现的情况下做到这一点,您只需为您的listView 创建一个自定义适配器。您可以将父布局添加为Drawer,然后您可以照常在其中执行任何复杂的布局。

【讨论】:

请不要将代码标签用于非代码文本。在这种情况下,您应该使用带有大于号 &gt; 的块引用,例如 &gt; This is a quote. 看看 Formatting help page

以上是关于如何在android中创建自定义导航抽屉的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift Xcode 中创建自定义导航栏?

在 React native 中创建自定义底部选项卡导航器

Android:如何使用自定义布局创建导航抽屉

Android上的自定义导航抽屉

如何在 Android 中更改汉堡图标(导航抽屉)

如何在抽屉导航器中的屏幕反应导航中设置自定义边框半径和 zIndex?