如何在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 提供。 类DrawerItem
、CustomDrawerAdapter
和布局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.在自动生成的NavigationDrawerFragment
类onCreateView
方法中,为此替换自动生成的适配器:
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_sectionN
和R.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
,然后您可以照常在其中执行任何复杂的布局。
【讨论】:
请不要将代码标签用于非代码文本。在这种情况下,您应该使用带有大于号>
的块引用,例如 > This is a quote.
看看 Formatting help page以上是关于如何在android中创建自定义导航抽屉的主要内容,如果未能解决你的问题,请参考以下文章