安卓导航抽屉示例教程

在本教程中,我们将在Android应用程序 中实现一个** 导航抽屉** 。Android导航抽屉是一个滑动菜单,是一个重要的用户界面组件。你会在大多数Android应用程序中看到导航抽屉,它就像网站中的导航菜单栏。

Android导航抽屉

Android导航抽屉是一个向左滑动的菜单,用于显示应用程序中的重要链接。导航抽屉使您可以轻松地在这些链接之间来回导航。默认情况下,它是不可见的,需要通过向左滑动或在ActionBar中单击其图标来打开它。更广泛地说,导航抽屉是一个覆盖面板,它取代了专门用于显示应用程序中的所有选项和链接的活动屏幕。在这篇Android导航抽屉教程中,我们将使用Android支持库中的抽屉布局API来实现导航抽屉。我们将展示可以从抽屉项打开的3个片段视图。

Android导航抽屉项目结构

安卓导航drawer

Android导航抽屉示例

要实现导航抽屉,我们首先需要添加android.support.v4.widget.DrawerLayout作为活动布局的根,如下所示。active_main.xml

 1<android.support.v4.widget.DrawerLayout 
 2    xmlns:android="https://schemas.android.com/apk/res/android"
 3    android:id="@+id/drawer_layout"
 4    android:layout_width="match_parent"
 5    android:layout_height="match_parent" >
 6
 7    <LinearLayout
 8        android:layout_width="match_parent"
 9        android:layout_height="match_parent"
10        android:orientation="vertical">
11
12    <LinearLayout
13        android:id="@+id/container_toolbar"
14        android:layout_width="match_parent"
15        android:layout_height="wrap_content"
16        android:orientation="vertical">
17
18        <include
19            android:id="@+id/toolbar"
20            layout="@layout/toolbar" />
21    </LinearLayout>
22
23    <FrameLayout
24        android:id="@+id/content_frame"
25        android:layout_width="match_parent"
26        android:layout_height="match_parent" />
27
28    </LinearLayout>
29
30    <ListView
31        android:id="@+id/left_drawer"
32        android:layout_width="240dp"
33        android:layout_height="match_parent"
34        android:layout_gravity="start"
35        android:background="#FFFFFF"
36        android:choiceMode="singleChoice"
37        android:divider="@android:color/darker_gray"
38        android:dividerHeight="1dp" />
39
40</android.support.v4.widget.DrawerLayout>

导航抽屉中的菜单选项以ListView的形式存储。每个选项都会在FrameLayout中打开。我们在这里使用了工具栏 来代替ActionBar。工具栏是从Android 5.0开始引入的,是ActionBar的泛化。它给了我们更多的控制和修改的灵活性,并且更容易与层次结构中的其他视图交错。布局工具栏在下面给出的XML布局中定义。Toolbar.xml

1<android.support.v7.widget.Toolbar xmlns:android="https://schemas.android.com/apk/res/android"
2    xmlns:local="https://schemas.android.com/apk/res-auto"
3    android:id="@+id/toolbar"
4    android:layout_width="match_parent"
5    android:layout_height="wrap_content"
6    android:minHeight="?attr/actionBarSize"
7    android:background="?attr/colorPrimary"
8    local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
9    local:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

在使用工具栏时,我们需要在style es.xml中使用主题Theme.AppCompat.NoActionBar。导航抽屉中的ListView行的布局如下所示。List_view_Item_row.xml

 1<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 2    android:layout_width="match_parent"
 3    android:layout_height="wrap_content"
 4    android:background="?android:attr/activatedBackgroundIndicator"
 5    android:minHeight="?android:attr/listPreferredItemHeightSmall"
 6    android:padding="10dp" >
 7
 8    <ImageView
 9        android:id="@+id/imageViewIcon"
10        android:layout_width="wrap_content"
11        android:layout_height="wrap_content"
12        android:layout_alignParentLeft="true"
13        android:layout_alignParentTop="true"
14        android:paddingRight="10dp" />
15
16    <TextView
17        android:id="@+id/textViewName"
18        android:layout_width="wrap_content"
19        android:layout_height="wrap_content"
20        android:layout_centerVertical="true"
21        android:layout_toRightOf="@+id/imageViewIcon"
22        android:paddingRight="10dp"
23        android:text="Item Name"
24        android:textColor="@android:color/black"
25        android:textAppearance="?android:attr/textAppearanceListItemSmall"
26        />
27
28</RelativeLayout>

如下所示,导航抽屉项被放在字符串.xml文件中的字符串数组中。字符串.xml

1<string-array name="navigation_drawer_items_array">
2        <item>Connect</item>
3        <item>Fixtures</item>
4        <item>Table</item>
5    </string-array>

Java类用于定义抽屉列表项的对象。DataModel.java

 1package com.journaldev.navigationdrawer;
 2
 3public class DataModel {
 4
 5    public int icon;
 6    public String name;
 7
 8    // Constructor.
 9    public DataModel(int icon, String name) {
10
11        this.icon = icon;
12        this.name = name;
13    }
14}

抽屉项以ListView的形式存储。因此,我们需要使用Adapter Class将该数据提供给Activity类。DrawerItemCustomAdapter.java

 1package com.journaldev.navigationdrawer;
 2
 3import android.app.Activity;
 4import android.content.Context;
 5import android.view.LayoutInflater;
 6import android.view.View;
 7import android.view.ViewGroup;
 8import android.widget.ArrayAdapter;
 9import android.widget.ImageView;
10import android.widget.TextView;
11
12public class DrawerItemCustomAdapter extends ArrayAdapter<DataModel> {
13
14    Context mContext;
15    int layoutResourceId;
16    DataModel data[] = null;
17
18    public DrawerItemCustomAdapter(Context mContext, int layoutResourceId, DataModel[] data) {
19
20        super(mContext, layoutResourceId, data);
21        this.layoutResourceId = layoutResourceId;
22        this.mContext = mContext;
23        this.data = data;
24    }
25
26    @Override
27    public View getView(int position, View convertView, ViewGroup parent) {
28
29        View listItem = convertView;
30
31        LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
32        listItem = inflater.inflate(layoutResourceId, parent, false);
33
34        ImageView imageViewIcon = (ImageView) listItem.findViewById(R.id.imageViewIcon);
35        TextView textViewName = (TextView) listItem.findViewById(R.id.textViewName);
36
37        DataModel folder = data[position];
38
39        imageViewIcon.setImageResource(folder.icon);
40        textViewName.setText(folder.name);
41
42        return listItem;
43    }
44}

下面给出了MainActivity.java的源代码。MainActivity.java

  1package com.journaldev.navigationdrawer;
  2
  3import android.support.v4.app.Fragment;
  4import android.support.v4.app.FragmentManager;
  5import android.support.v4.widget.DrawerLayout;
  6import android.support.v7.app.AppCompatActivity;
  7import android.os.Bundle;
  8import android.support.v7.widget.Toolbar;
  9import android.util.Log;
 10import android.view.MenuItem;
 11import android.view.View;
 12import android.widget.AdapterView;
 13import android.widget.ListView;
 14
 15public class MainActivity extends AppCompatActivity {
 16
 17    private String[] mNavigationDrawerItemTitles;
 18    private DrawerLayout mDrawerLayout;
 19    private ListView mDrawerList;
 20    Toolbar toolbar;
 21    private CharSequence mDrawerTitle;
 22    private CharSequence mTitle;
 23    android.support.v7.app.ActionBarDrawerToggle mDrawerToggle;
 24
 25    @Override
 26    protected void onCreate(Bundle savedInstanceState) {
 27        super.onCreate(savedInstanceState);
 28        setContentView(R.layout.activity_main);
 29        mTitle = mDrawerTitle = getTitle();
 30        mNavigationDrawerItemTitles= getResources().getStringArray(R.array.navigation_drawer_items_array);
 31        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
 32        mDrawerList = (ListView) findViewById(R.id.left_drawer);
 33
 34        setupToolbar();
 35
 36        DataModel[] drawerItem = new DataModel[3];
 37
 38        drawerItem[0] = new DataModel(R.drawable.connect, "Connect");
 39        drawerItem[1] = new DataModel(R.drawable.fixtures, "Fixtures");
 40        drawerItem[2] = new DataModel(R.drawable.table, "Table");
 41        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
 42        getSupportActionBar().setHomeButtonEnabled(true);
 43
 44        DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.list_view_item_row, drawerItem);
 45        mDrawerList.setAdapter(adapter);
 46        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
 47        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
 48        mDrawerLayout.setDrawerListener(mDrawerToggle);
 49        setupDrawerToggle();
 50
 51    }
 52
 53    private class DrawerItemClickListener implements ListView.OnItemClickListener {
 54
 55        @Override
 56        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 57            selectItem(position);
 58        }
 59
 60    }
 61
 62    private void selectItem(int position) {
 63
 64        Fragment fragment = null;
 65
 66        switch (position) {
 67            case 0:
 68                fragment = new ConnectFragment();
 69                break;
 70            case 1:
 71                fragment = new FixturesFragment();
 72                break;
 73            case 2:
 74                fragment = new TableFragment();
 75                break;
 76
 77            default:
 78                break;
 79        }
 80
 81        if (fragment != null) {
 82            FragmentManager fragmentManager = getSupportFragmentManager();
 83            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
 84
 85            mDrawerList.setItemChecked(position, true);
 86            mDrawerList.setSelection(position);
 87            setTitle(mNavigationDrawerItemTitles[position]);
 88            mDrawerLayout.closeDrawer(mDrawerList);
 89
 90        } else {
 91            Log.e("MainActivity", "Error in creating fragment");
 92        }
 93    }
 94
 95    @Override
 96    public boolean onOptionsItemSelected(MenuItem item) {
 97
 98        if (mDrawerToggle.onOptionsItemSelected(item)) {
 99            return true;
100        }
101
102        return super.onOptionsItemSelected(item);
103    }
104
105    @Override
106    public void setTitle(CharSequence title) {
107        mTitle = title;
108        getSupportActionBar().setTitle(mTitle);
109    }
110
111    @Override
112    protected void onPostCreate(Bundle savedInstanceState) {
113        super.onPostCreate(savedInstanceState);
114        mDrawerToggle.syncState();
115    }
116
117    void setupToolbar(){
118        toolbar = (Toolbar) findViewById(R.id.toolbar);
119        setSupportActionBar(toolbar);
120        getSupportActionBar().setDisplayShowHomeEnabled(true);
121    }
122
123    void setupDrawerToggle(){
124        mDrawerToggle = new android.support.v7.app.ActionBarDrawerToggle(this,mDrawerLayout,toolbar,R.string.app_name, R.string.app_name);
125        //This is necessary to change the icon of the Drawer Toggle upon state change.
126        mDrawerToggle.syncState();
127    }
128}

在上面的代码中,getSupportActionBar().setDisplayHomeAsUpEnabled(false);用于隐藏默认的后退按钮。在这段代码中,我们使用了一个DrawerItemClickListener类,它加载使用FragmentManager单击的列表项的相应片段。此外,工具栏的标题将更改为使用setTitle(mNavigationDrawerItemTitles[position]);.单击的列表项片段类及其各自的布局如下所示。ConnectFragment.java

 1package com.journaldev.navigationdrawer;
 2
 3import android.os.Bundle;
 4import android.support.v4.app.Fragment;
 5import android.view.LayoutInflater;
 6import android.view.View;
 7import android.view.ViewGroup;
 8
 9public class ConnectFragment extends Fragment {
10
11    public ConnectFragment() {
12    }
13
14    @Override
15    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
16
17        View rootView = inflater.inflate(R.layout.fragment_connect, container, false);
18
19        return rootView;
20    }
21
22}

上述片段的布局定义如下。Fragment_Connect.xml

 1<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 2    xmlns:tools="https://schemas.android.com/tools"
 3    android:layout_width="match_parent"
 4    android:layout_height="match_parent"
 5    android:orientation="vertical">
 6
 7    <TextView
 8        android:id="@+id/label"
 9        android:layout_alignParentTop="true"
10        android:layout_marginTop="100dp"
11        android:layout_width="fill_parent"
12        android:layout_height="wrap_content"
13        android:gravity="center_horizontal"
14        android:textSize="45dp"
15        android:text="Connect"
16        android:textStyle="bold"/>
17
18    <TextView
19        android:layout_below="@id/label"
20        android:layout_centerInParent="true"
21        android:layout_width="fill_parent"
22        android:layout_height="wrap_content"
23        android:textSize="12dp"
24        android:layout_marginTop="10dp"
25        android:gravity="center_horizontal"
26        android:text="Edit fragment_connect.xml to change the appearance"
27        android:id="@+id/textView2" />
28
29</RelativeLayout>

另外两个项目的定义方式与上面完全相同,因此我们在这里跳过它。

导航抽屉Android示例输出

下面是我们的导航抽屉Android示例应用程序产生的输出。安卓导航抽屉example这将结束安卓导航抽屉示例教程。您可以通过下面的链接下载最终的Android导航抽屉项目

下载安卓导航抽屉示例Project

Published At
Categories with 技术
Tagged with
comments powered by Disqus