編輯:關於android開發
抽屜式導航欄是顯示在屏幕的左邊緣,它是應用程序的主導航選項面板。它大部分時間是處於隱藏狀態的,但是當用戶從屏幕的左邊緣揮動手指時它就會顯示出來,而在應用程序的頂層,用戶觸摸操作欄上的應用程序圖標也可以將其顯示出來。
本課程介紹在可用的API 支持庫下如何實現導航抽屜DrawerLayout。
首先我們可以看一下最終的效果圖:
要添加一個抽屜式導航,首先你必須要聲明你的用戶界面的根布局為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>
這個布局文件演示了一些比較重要的布局特點,如下:
在你的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()來接收抽屜導航欄列表的點擊事件。下一節將展示如何實現此接口,以實現當用戶選擇一個項目後更改主內容視圖。
當用戶選擇在抽屜導航欄裡列表中的項目時,系統調用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); }
要監聽抽屜打開和關閉事件,在你的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構造函數的參數,並設置它來處理與操作欄圖標交互所需的其他步驟。
用戶可以通過來自或朝向屏幕的左邊緣輕掃的手勢來打開與關閉抽屜式導航欄,但如果你正在使用操作欄(ActionBar) ,你也應該允許用戶通過觸摸應用程序圖標的方式打開或者關閉抽屜導航欄。而應用程序圖標也應用一個特殊的圖標注明抽屜的存在。你也可以通過實現上一節講到的ActionBarDrawerToggle來實現這些行為。
為了使ActionBarDrawerToggle發揮作用,你將需要創建它的一個實例與它的構造方法,這需要下列參數:
最後,不管你是否已經創建了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
Android AsyncTask 深度理解、簡單封裝、任務隊列分析、自定義線程池,androidasynctask前言:由於最近在做SDK的功能,需要設計線程池。看了很
Android工程打包成jar文件,並且將工程中引用的jar一起打入新的jar文件中,androidjar前言: 關於.jar文件: 平時我們Android項目開發中經常
Android中解析JSON格式數據常見方法合集,androidjson 待解析的JSON格式的文件如下: [{id:5, version:1.0, name:
Android Scroll詳解(一):基礎知識 Android Scroll詳解(一):基礎知識 在前邊