Android导航抽屉示例教程

时间:2020-02-23 14:29:06  来源:igfitidea点击:

在本教程中,我们将在Android应用程序中实现导航抽屉。
Android导航抽屉是一个滑动菜单,它是重要的UI组件。
您会在大多数android应用程序中看到导航抽屉,就像上的导航菜单列一样。

Android导航抽屉

Android导航抽屉是一个向左滑动菜单,用于显示应用程序中的重要链接。
导航抽屉可轻松在这些链接之间来回导航。
默认情况下它是不可见的,需要通过向左滑动或者在ActionBar中单击其图标来打开它。

从广义上讲,"导航抽屉"是一个覆盖面板,替代了专门用于显示应用程序中所有选项和链接的活动屏幕。

在本android导航抽屉教程中,我们将使用Android支持库中提供的Drawer Layout API来实现导航抽屉。
我们将显示3个可以从抽屉项目中打开的片段视图。

Android导航抽屉示例

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

activity_main.xml

<android.support.v4.widget.DrawerLayout 
  xmlns:android="https://schemas.android.com/apk/res/android"
  android:id="@+id/drawer_layout"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical">

  <LinearLayout
      android:id="@+id/container_toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical">

      <include
          android:id="@+id/toolbar"
          layout="@layout/toolbar" 
  </LinearLayout>

  <FrameLayout
      android:id="@+id/content_frame"
      android:layout_width="match_parent"
      android:layout_height="match_parent" 

  </LinearLayout>

  <ListView
      android:id="@+id/left_drawer"
      android:layout_width="240dp"
      android:layout_height="match_parent"
      android:layout_gravity="start"
      android:background="#FFFFFF"
      android:choiceMode="singleChoice"
      android:divider="@android:color/darker_gray"
      android:dividerHeight="1dp" 

</android.support.v4.widget.DrawerLayout>

导航抽屉中的菜单选项以ListView的形式存储。
每个选项在FrameLayout中打开。

其中我们使用工具列代替了ActionBar。
从Android 5.0开始,ToolBar就是ActionBar的概括。
它为我们提供了更多的控制权和修改的灵活性,并且更易于与层次结构中的其他视图进行交错。

布局工具列在下面给出的xml布局中定义。

toolbar.xml

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

使用工具列时,我们需要在styles.xml中使用主题Theme.AppCompat.NoActionBar

下面给出了导航抽屉中ListView行的布局。

list_view_item_row.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="?android:attr/activatedBackgroundIndicator"
  android:minHeight="?android:attr/listPreferredItemHeightSmall"
  android:padding="10dp" >

  <ImageView
      android:id="@+id/imageViewIcon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentTop="true"
      android:paddingRight="10dp" 

  <TextView
      android:id="@+id/textViewName"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerVertical="true"
      android:layout_toRightOf="@+id/imageViewIcon"
      android:paddingRight="10dp"
      android:text="Item Name"
      android:textColor="@android:color/black"
      android:textAppearance="?android:attr/textAppearanceListItemSmall"
      

</RelativeLayout>

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

strings.xml

<string-array name="navigation_drawer_items_array">
      <item>Connect</item>
      <item>Fixtures</item>
      <item>Table</item>
  </string-array>

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

DataModel.java

package com.theitroad.navigationdrawer;

public class DataModel {

  public int icon;
  public String name;

  //Constructor.
  public DataModel(int icon, String name) {

      this.icon = icon;
      this.name = name;
  }
}

抽屉项目以ListView的形式存储。
因此,我们需要使用适配器类将数据提供给活动类。

DrawerItemCustomAdapter.java

package com.theitroad.navigationdrawer;

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 DrawerItemCustomAdapter extends ArrayAdapter<DataModel> {

  Context mContext;
  int layoutResourceId;
  DataModel data[] = null;

  public DrawerItemCustomAdapter(Context mContext, int layoutResourceId, DataModel[] data) {

      super(mContext, layoutResourceId, data);
      this.layoutResourceId = layoutResourceId;
      this.mContext = mContext;
      this.data = data;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {

      View listItem = convertView;

      LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
      listItem = inflater.inflate(layoutResourceId, parent, false);

      ImageView imageViewIcon = (ImageView) listItem.findViewById(R.id.imageViewIcon);
      TextView textViewName = (TextView) listItem.findViewById(R.id.textViewName);

      DataModel folder = data[position];

      imageViewIcon.setImageResource(folder.icon);
      textViewName.setText(folder.name);

      return listItem;
  }
}

MainActivity.java源代码如下所示。

MainActivity.java

package com.theitroad.navigationdrawer;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

  private String[] mNavigationDrawerItemTitles;
  private DrawerLayout mDrawerLayout;
  private ListView mDrawerList;
  Toolbar toolbar;
  private CharSequence mDrawerTitle;
  private CharSequence mTitle;
  android.support.v7.app.ActionBarDrawerToggle mDrawerToggle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      mTitle = mDrawerTitle = getTitle();
      mNavigationDrawerItemTitles= getResources().getStringArray(R.array.navigation_drawer_items_array);
      mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
      mDrawerList = (ListView) findViewById(R.id.left_drawer);

      setupToolbar();

      DataModel[] drawerItem = new DataModel[3];

      drawerItem[0] = new DataModel(R.drawable.connect, "Connect");
      drawerItem[1] = new DataModel(R.drawable.fixtures, "Fixtures");
      drawerItem[2] = new DataModel(R.drawable.table, "Table");
      getSupportActionBar().setDisplayHomeAsUpEnabled(false);
      getSupportActionBar().setHomeButtonEnabled(true);

      DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.list_view_item_row, drawerItem);
      mDrawerList.setAdapter(adapter);
      mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
      mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
      mDrawerLayout.setDrawerListener(mDrawerToggle);
      setupDrawerToggle();

  }

  private class DrawerItemClickListener implements ListView.OnItemClickListener {

      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          selectItem(position);
      }

  }

  private void selectItem(int position) {

      Fragment fragment = null;

      switch (position) {
          case 0:
              fragment = new ConnectFragment();
              break;
          case 1:
              fragment = new FixturesFragment();
              break;
          case 2:
              fragment = new TableFragment();
              break;

          default:
              break;
      }

      if (fragment != null) {
          FragmentManager fragmentManager = getSupportFragmentManager();
          fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

          mDrawerList.setItemChecked(position, true);
          mDrawerList.setSelection(position);
          setTitle(mNavigationDrawerItemTitles[position]);
          mDrawerLayout.closeDrawer(mDrawerList);

      } else {
          Log.e("MainActivity", "Error in creating fragment");
      }
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {

      if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
      }

      return super.onOptionsItemSelected(item);
  }

  @Override
  public void setTitle(CharSequence title) {
      mTitle = title;
      getSupportActionBar().setTitle(mTitle);
  }

  @Override
  protected void onPostCreate(Bundle savedInstanceState) {
      super.onPostCreate(savedInstanceState);
      mDrawerToggle.syncState();
  }

  void setupToolbar(){
      toolbar = (Toolbar) findViewById(R.id.toolbar);
      setSupportActionBar(toolbar);
      getSupportActionBar().setDisplayShowHomeEnabled(true);
  }

  void setupDrawerToggle(){
      mDrawerToggle = new android.support.v7.app.ActionBarDrawerToggle(this,mDrawerLayout,toolbar,R.string.app_name, R.string.app_name);
      //This is necessary to change the icon of the Drawer Toggle upon state change.
      mDrawerToggle.syncState();
  }
}

在上面的代码中," getSupportActionBar()。
setDisplayHomeAsUpEnabled(false);"用于隐藏默认的后退按钮。

在此代码中,我们使用了DrawerItemClickListener类,该类加载使用FragmentManager单击的列表项的相应片段。
工具列的标题也更改为使用setTitle(mNavigationDrawerItemTitles [position]);单击的列表项。

片段类及其各自的布局如下。

ConnectFragment.java

package com.theitroad.navigationdrawer;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class ConnectFragment extends Fragment {

  public ConnectFragment() {
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

      View rootView = inflater.inflate(R.layout.fragment_connect, container, false);

      return rootView;
  }

}

以上片段的布局定义如下。

fragment_connect.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:tools="https://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <TextView
      android:id="@+id/label"
      android:layout_alignParentTop="true"
      android:layout_marginTop="100dp"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center_horizontal"
      android:textSize="45dp"
      android:text="Connect"
      android:textStyle="bold"

  <TextView
      android:layout_below="@id/label"
      android:layout_centerInParent="true"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:textSize="12dp"
      android:layout_marginTop="10dp"
      android:gravity="center_horizontal"
      android:text="Edit fragment_connect.xml to change the appearance"
      android:id="@+id/textView2" 

</RelativeLayout>