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

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

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

我该怎么做?

【问题讨论】:

    标签: android android-listview navigation-drawer


    【解决方案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 跟踪对模板所做的更改。

    【讨论】:

    【解决方案2】:

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

    <android.support.design.widget.NavigationView
            android:id="@+id/navi_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start|top"
            android:background="@color/navigation_view_bg_color"
            app:theme="@style/NavDrawerTextStyle">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                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_width="fill_parent"
        android:layout_height="fill_parent" >
    
    <LinearLayout
        android:id="@+id/itemLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:orientation="vertical"
        android:layout_marginTop="0dp"
        android:background="?android:attr/activatedBackgroundIndicator">
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:minHeight="55dp">
    
            <ImageView
                android:id="@+id/drawer_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
            <TextView
                android:id="@+id/drawer_itemName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"/>
        </LinearLayout>
    
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            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_width="match_parent"
          android:layout_height="match_parent">
      
          <!-- Framelayout to display Fragments -->
          <FrameLayout
              android:id="@+id/frame_container"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
      
          <!-- Listview to display slider menu -->
          <ListView
              android:id="@+id/list_slidermenu"
              android:layout_width="240dp"
              android:layout_height="match_parent"
              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_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity">
        
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        
        
        
            <android.support.design.widget.AppBarLayout
                android:id="@+id/appBarLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        
                <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/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_width="wrap_content"
            android:layout_height="match_parent"
            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_width="64dp"
            android:layout_height="64dp"
            android:layout_margin="@dimen/spacing_large"
            android:elevation="4dp"
            tools:src="@drawable/ic_launcher"/>
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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_width="wrap_content"
            android:layout_height="wrap_content"
            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
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-01
          • 2014-07-12
          • 2020-07-20
          • 1970-01-01
          • 1970-01-01
          • 2023-03-08
          相关资源
          最近更新 更多