Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 【原創+譯文】官方文檔中聲明的如何創建抽屜導航欄(Navigation Drawer),navigationdrawer

【原創+譯文】官方文檔中聲明的如何創建抽屜導航欄(Navigation Drawer),navigationdrawer

編輯:關於android開發

【原創+譯文】官方文檔中聲明的如何創建抽屜導航欄(Navigation Drawer),navigationdrawer


如需轉載請注明出處:http://www.cnblogs.com/ghylzwsb/p/5831759.html

創建一個抽屜導航欄

抽屜式導航欄是顯示在屏幕的左邊緣,它是應用程序的主導航選項面板。它大部分時間是處於隱藏狀態的,但是當用戶從屏幕的左邊緣揮動手指時它就會顯示出來,而在應用程序的頂層,用戶觸摸操作欄上的應用程序圖標也可以將其顯示出來。

本課程介紹在可用的API 支持庫下如何實現導航抽屜DrawerLayout。

首先我們可以看一下最終的效果圖:

 

1、創建一個抽屜布局文件(Drawer Layout)

要添加一個抽屜式導航,首先你必須要聲明你的用戶界面的根布局為DrawerLayout對象。在DrawerLayout裡面,添加一個主視圖內容的view對象(當抽屜被隱藏的時候顯示在屏幕上的 視圖)和另外一個包含抽屜導航視圖的view對象。

例如,下面的布局采用了包含兩個子視圖的DrawerLayout:一個是FrameLayout,包含了主要內容(在運行時由填充Fragment),和一個ListView的導航抽屜。

 1 <android.support.v4.widget.DrawerLayout 
 2     xmlns:android="http://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     <!-- 主視圖 -->
 8     <FrameLayout
 9         android:id="@+id/content_frame"
10         android:layout_width="match_parent"
11         android:layout_height="match_parent" />
12 
13     <!-- 抽屜視圖 -->
14     <ListView
15         android:id="@+id/left_drawer"
16         android:layout_width="240dp"
17         android:layout_height="match_parent"
18         android:layout_gravity="start"
19         android:background="#111"
20         android:choiceMode="singleChoice"
21         android:divider="@android:color/transparent"
22         android:dividerHeight="0dp" />
23 
24 </android.support.v4.widget.DrawerLayout>

這個布局文件演示了一些比較重要的布局特點,如下:

  • 主內容視圖(上面的FrameLayout)必須是DrawerLayout布局對象的第一個子view對象,這是因為xml文件意味著是z排序(即空間上的上下排序,也就是說抽屜導航欄應該位於住內容視圖的垂直上方)。
  • 主內容視圖的view對象的兩個屬性:layout_width、layout_height必須是match_parent的,這是因為當抽屜導航欄被隱藏的時候他便是整個UI。
  • 抽屜視圖要指定其寬度的單位為dp,高度與父視圖相匹配。抽屜的寬度應該不超過320dp,這樣用戶可以隨時看到主要內容視圖的一些部分。
  • 抽屜視圖(ListView)必須用 android:layout_gravity 屬性來指定他的水平重力方向。為了支持從右到左(RTL)的語言,應該要指定其屬性為"start" ,而不是"left" 。

2、初始化抽屜列表

在你的Activity中,首先要做的事之一就是初始化抽屜導航欄中的列表項。至於你要如何做取決於你的應用程序中的內容,但是通常情況下抽屜導航欄都是包含了一個ListView,所以列表應該由Adapter來填充(如ArrayAdapter或者SimpleCursorAdapter)。

例如下面將告訴你如何用字符串數組初始化抽屜導航欄列表:

public class MainActivity extends Activity {
    private String[] mPlanetTitles;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPlanetTitles = getResources().getStringArray(R.array.planets_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        // Set the adapter for the list view
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mPlanetTitles));
        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        ...
    }
}

此代碼還調用setOnItemClickListener()來接收抽屜導航欄列表的點擊事件。下一節將展示如何實現此接口,以實現當用戶選擇一個項目後更改主內容視圖。

3、處理導航的點擊事件

當用戶選擇在抽屜導航欄裡列表中的項目時,系統調用OnItemClickListener接口中的onItemClick()方法以返回給OnItemClickListener() 。你要在onItemClick()方法中做什麼樣的處理取決於你如何實現你的的應用程序結構。在下面的例子中,你將可以實現下面的內容:當點擊抽屜導航欄中列表項裡的item時,將會在住內容視圖中插入一個不同的Fragment。(FrameLayout的id為 R.id.content_frame)。

private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}

/** Swaps fragments in the main content view */
private void selectItem(int position) {
    // Create a new fragment and specify the planet to show based on position
    Fragment fragment = new PlanetFragment();
    Bundle args = new Bundle();
    args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
    fragment.setArguments(args);

    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
                   .replace(R.id.content_frame, fragment)
                   .commit();

    // Highlight the selected item, update the title, and close the drawer
    mDrawerList.setItemChecked(position, true);
    setTitle(mPlanetTitles[position]);
    mDrawerLayout.closeDrawer(mDrawerList);
}

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

4、監聽打開以及關閉抽屜導航欄的事件

要監聽抽屜打開和關閉事件,在你的DrawerLayout中調用setDrawerListener()並傳入一個DrawerLayout.DrawerListener接口 。此接口為抽屜導航欄提供了回掉方法,如onDrawerOpened()和onDrawerClosed()。

然而,除了實現DrawerLayout.DrawerListener接口之外,如果你的Activity包含了ActionBar,你也可以繼承ActionBarDrawerToggle這個類,這是因為ActionBarDrawerToggle類實現DrawerLayout.DrawerListener接口,所以你仍然可以復寫這些方法,但是這對ActionBar圖標和抽屜的交互也有一定的幫助。

正如在抽屜導航設計指南討論的一樣,當抽屜處於可見狀態時你應該要修改操作欄(ActionBar)的內容,例如你應該要改變標題,並移除與主內容試圖相關的列表項。下面的代碼演示了如何通過實例化ActionBarDrawerToggle類並復寫在DrawerLayout.DrawerListener中的回調方法,以達到這樣的目的:

public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...

        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
}

下一節將介紹ActionBarDrawerToggle構造函數的參數,並設置它來處理與操作欄圖標交互所需的其他步驟。

5、如何通過應用程序圖標打開或關閉抽屜導航欄

用戶可以通過來自或朝向屏幕的左邊緣輕掃的手勢來打開與關閉抽屜式導航欄,但如果你正在使用操作欄(ActionBar) ,你也應該允許用戶通過觸摸應用程序圖標的方式打開或者關閉抽屜導航欄。而應用程序圖標也應用一個特殊的圖標注明抽屜的存在。你也可以通過實現上一節講到的ActionBarDrawerToggle來實現這些行為。

為了使ActionBarDrawerToggle發揮作用,你將需要創建它的一個實例與它的構造方法,這需要下列參數:

  • 持有該抽屜的Activity
  • 一個DrawerLayout
  • 用於作為抽屜指標的繪制資源(drawable resource),這裡會提供一個android官方提供的圖標包:Android_Design_Icons_20130926.zip。
  • 用來形容“打開抽屜”這一操作的字符串資源
  • 用來形容“關閉抽屜”這一操作的字符串資源

最後,不管你是否已經創建了ActionBarDrawerToggle的子類作為抽屜的監聽器,你還是需要在整個Activity的生命周期中的幾個地方調用ActionBarDrawerToggle:

public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    ...

    public void onCreate(Bundle savedInstanceState) {
        ...

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer icon to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description */
                R.string.drawer_close  /* "close drawer" description */
                ) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle(mDrawerTitle);
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
    }

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

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    ...
}

教程的最後,我提供了項目的下載地址:DrawerLayout_sample.rar,希望這個教程能夠幫到你。

 

 

BOB

2016-09-03

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved