Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android學習之界面篇(七)側滑菜單的實現

Android學習之界面篇(七)側滑菜單的實現

編輯:關於Android編程

側滑菜單的實現方式:
  1. SlidingMenu開源庫:https://github.com/jfeinstein10/SlidingMenu
  2. DrawerLayout:是2013年谷歌IO大會上由谷歌官方發布的,包含在support v4包中。
  3. 官方定義:http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
  4. 使用說明:http://developer.android.com/training/implementing-navigation/nav-drawer.html
接下來按照谷歌官方給定的創建步驟來實現一個側滑菜單。
Create a Drawer Layout
To add a navigation drawer, declare your user interface with aDrawerLayoutobject as the root view of your layout. Inside theDrawerLayout, add one view that contains the main content for the screen (your primary layout when the drawer is hidden) and another view that contains the contents of the navigation drawer. 按照谷歌官方給出的示例創建一個帶有Drawer Layout的項目: activity_main.xml配置如下:


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

    </framelayout>

    
    

    

 
啟動項目,通過從屏幕左端滑動來滑出菜單。 注: android:layout_gravity="start"是從屏幕左邊滑動,"end"則為從屏幕右端滑出。 android:choiceMode="singleChoice"模式為單選模式 android:divider="@android:color/transparent"分割線采用原始的透明分割線 android:dividerHeight="0dp"分割線高度為0,不可見。 注意事項:
  1. 主內容視圖一定要是DrawerLayout的第一個子視圖
  2. 主內容視圖寬度高度要匹配父視圖,即"match_parent",也就是說:當抽屜隱藏時,要讓用戶看到主視圖的全部內容。
  3. 必須顯示指定抽屜視圖(如LiistView)的android:layout_gravity屬性。
android:layout_gravity="start"從左向右滑出菜單
  • android:layout_gravity="end"從右向左滑出菜單
不推薦使用"left" 和"right" 4.抽屜視圖的寬度以dp為單位,請不要超過320dp(為了總能看到一些主內容視圖)
Initialize the Drawer List
In your activity, one of the first things to do is initialize the navigation drawer's list of items. How you do so depends on the content of your app, but a navigation drawer often consists of aListView, so the list should be populated by anAdapter(such asArrayAdapterorSimpleCursorAdapter). 接下來在項目中實現初始化Drawer List的操作。 1.首先對組件進行聲明,包括DrawerLayout和ListView。 privateDrawerLayoutmDrawerLayout;
privateListViewmDrawerList; 2.使用ArrayList集合來儲存菜單項,使用ArrayAdapter對ListView的內容進行填充。 //使用集合來儲存側滑菜單的菜單項
privateArrayListmenuLists;
//使用ArrayAdapter來對ListView的內容進行填充
privateArrayAdapteradapter;
3.在onCreate方法中對z組件進行查找和初始化數據操作。 mDrawerLayout=(DrawerLayout)findViewById(R.id.draw_layout);
mDrawerList=(ListView)findViewById(R.id.left_drawer);


//初始化menulists
menuLists=newArrayList();
for(inti=0;i<5;i++){
menuLists.add("測試菜單"+i);
}
//初始化adapter
adapter=newArrayAdapter(this,android.R.layout.simple_list_item_1,menuLists);
//為側邊菜單填充上內容
mDrawerList.setAdapter(adapter);
\
Handle Navigation Click Events
When the user selects an item in the drawer's list, the system callsonItemClick()on theOnItemClickListenergiven tosetOnItemClickListener(). What you do in theonItemClick()method depends on how you've implemented yourapp structure. 1.為菜單項添加點擊事件監聽器,並讓主類實現事件監聽器接口 mDrawerList.setOnItemClickListener(this); 2.復寫事件監聽器中的方法,動態插入一個Fragment到FrameLayout中去 publicvoidonItemClick(AdapterViewparent,Viewview,intposition,longid){
//動態插入一個Fragment到FrameLayout當中
FragmentcontentFragment=newContentFragment();
Bundleargs=newBundle();
args.putString("text",menuLists.get(position));

contentFragment.setArguments(args);//?
//新建一個Fragment
FragmentManagerfm=getFragmentManager();
fm.beginTransaction().replace(R.id.content_frame,contentFragment).commit();

//點擊完成後關閉菜單欄
mDrawerLayout.closeDrawer(mDrawerList);

  } 3.新建一Fragment ContentFragment,對應配置文件為fragment_content.xml fragment_content.xml配置如下:   ContentFragment.java具體代碼: publicclassContentFragmentextendsFragment{
privateTextViewtextView;


@Override
publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
BundlesavedInstanceState){
//動態加載視圖
Viewview=inflater.inflate(R.layout.fragment_content,container,false);
//查找組件id
textView=(TextView)view.findViewById(R.id.textView);
//通過Arguments來傳遞數據
Stringtext=getArguments().getString("text");
//給textview設置文字
textView.setText(text);
//返回加載的視圖
returnview;
}

}
\ 問題: 1.為什麼要用Fragment.setArguments(Bundle bundle)來傳遞參數? Activity重新創建時,會重新構建它所管理的Fragment,原先的Fragment的字段值將會全部丟失,但是通過Fragment.setArguments(Bundle bundle)方法設置的bundle會保留下來。所以盡量使用Fragment.setArguments(Bundle bundle)方式來傳遞參數 具體:http://blog.csdn.net/tu_bingbing/article/details/24143249
Listen for Open and Close Events

To listen for drawer open and close events, callsetDrawerListener()on yourDrawerLayoutand pass it an implementation ofDrawerLayout.DrawerListener. This interface provides callbacks for drawer events such asonDrawerOpened()andonDrawerClosed().

However, rather than implementing theDrawerLayout.DrawerListener, if your activity includes theaction bar, you can instead extend theActionBarDrawerToggleclass. TheActionBarDrawerToggleimplementsDrawerLayout.DrawerListenerso you can still override those callbacks, but it also facilitates the proper interaction behavior between the action bar icon and the navigation drawer (discussed further in the next section).

As discussed in theNavigation Drawerdesign guide, you should modify the contents of the action bar when the drawer is visible, such as to change the title and remove action items that are contextual to the main content. 知識點介紹: 1.mDrawerLayout.setDrawerListener(DrawerLayout.DrawerListener); 2.ActionBarDrawerToggle是DrawerLayout.DrawerListener的具體實現類。 1)改變android.R.id.home圖標(構造方法) 2)Drawer拉出、隱藏,帶有android.R.id.home動畫效果(syncState()) 3)監聽Drawer拉出、隱藏事件 3.復寫ActionBarDrawerToggle的onDrawerOpended()和onDrawerClosed()以監聽抽屜拉出或隱藏事件。 4.復寫Activity中的onPostCreate()方法和onConfigurationChange()方法,是為了結合syncState()方法來s實現左上角圖標動畫的效果。當設備的y一些參數發生變化時(屏幕旋轉等)就會調用onConfigurationChange方法,在方法中對ActionBarDrawerToggle進行配置。
在代碼中實現: (一)設置菜單被拉出時Title文字的改變   1.首先聲明一個ActionBarDrawerToggle,注意是support.v7包中的(support.v4包中的已經失效) 使用v7替換v4方法請看:ActionBarDrawerToggle is Deprecated privateActionBarDrawerTogglemDrawerToggle; 2.接著初始化ActionBarDrawerToggle,(具體參數為:ActionBarDrawerToggle(Activityactivity, DrawerLayoutdrawerLayout, int openDrawerContentD escRes, int closeDrawerContentDescRes))並復寫其中的onDrawerOpended()和onDrawerClosed()方法來實現拉出或隱藏抽屜時對Title的更改。 注:使用v7包的時候得使用getSupportActionBar()來設置Title信息 mDrawerToggle=newActionBarDrawerToggle(this,mDrawerLayout,
R.string.drawer_open,R.string.drawer_close){
/**
*當抽屜被打開是執行
*設置抽屜被打開時的Title
*通過getActionBar()來改變
*@paramdrawerView
*/
@Override
publicvoidonDrawerOpened(ViewdrawerView){
super.onDrawerOpened(drawerView);
//BUG:此處產生空指針異常,使用getSupportActionBar()
//getActionBar().setTitle("請選擇");

getSupportActionBar().setTitle("請選擇");
invalidateOptionsMenu();//重繪actionbar上的菜單項,會自動調用onPrepareOptionsMenu方法
}

/**
*當抽屜被關閉時執行
*設置抽屜被關閉時的Title
*@paramdrawerView
*/
@Override
publicvoidonDrawerClosed(ViewdrawerView){
super.onDrawerClosed(drawerView);
getSupportActionBar().setTitle(mTitle);
invalidateOptionsMenu();//重繪actionbar上的菜單項
}
}; 3.給DrawerLayout添加DrawerListener。setDrawerListener以失效,使用addDrawerListener mDrawerLayout.addDrawerListener(mDrawerToggle);
  (二)在ActionBar上添加搜索圖標 1.在res中新建menu文件夾,在其中添加main.xml,其中 android:showAsAction。   這個屬性可接受的值有:   1、always:這個值會使菜單項一直顯示在Action Bar上。   2、ifRoom:如果有足夠的空間,這個值會使菜單項顯示在Action Bar上。   3、never:這個值使菜單項永遠都不出現在Action Bar上。   4、withText:這個值使菜單項和它的圖標,菜單文本一起顯示。 main.xml配置如下: 2.在MainActivity中使用onCreateOptionsMenu()來加載menu publicbooleanonCreateOptionsMenu(Menumenu){
getMenuInflater().inflate(R.menu.main,menu);
returntrue;
} 3.在執行invalidateOptionsMenu()方法時會調用onPrepareOptionsMenu(),復寫此方法來實現菜單圖標的顯示狀態。首先先獲取Drawer的打開狀態,當Drawer打開時菜單圖標被隱藏,當Drawer關閉時顯示菜單圖標。即菜單圖標的顯示狀態與Drawer的打開狀態正好相反。 publicbooleanonPrepareOptionsMenu(Menumenu){
//獲取Drawer的打開狀態
booleanisDrawerOpen=mDrawerLayout.isDrawerOpen(mDrawerList);
//對menuItem的可見狀態進行改變,總是跟Drawer的打開狀態相反
menu.findItem(R.id.action_websearch).setVisible(!isDrawerOpen);
returnsuper.onPrepareOptionsMenu(menu);
} 4.使用onOptionsItemSelected()方法來為菜單項設置點擊事件。讓其使用系統浏覽器打開指定的網頁(百度)。 publicbooleanonOptionsItemSelected(MenuItemitem){
switch(item.getItemId()){
caseR.id.action_websearch:
Intentintent=newIntent();
intent.setAction("android.intent.action.VIEW");
Uriuri=Uri.parse("http://www.baidu.com");
intent.setData(uri);
startActivity(intent);
break;
}
returnsuper.onOptionsItemSelected(item);
} \
Open and Close with the App Icon

Users can open and close the navigation drawer with a swipe gesture from or towards the left edge of the screen, but if you're using theaction bar, you should also allow users to open and close it by touching the app icon. And the app icon should also indicate the presence of the navigation drawer with a special icon. You can implement all this behavior by using theActionBarDrawerToggleshown in the previous section.

To makeActionBarDrawerTogglework, create an instance of it with its constructor, which requires the following arguments:

  • TheActivityhosting the drawer.
  • TheDrawerLayout.
  • A drawable resource to use as the drawer indicator.

    The standard navigation drawer icon is available in theAndroid_Design_Icons_20130926.zip" target="_blank">Download the Action Bar Icon Pack.

  • A String resource to describe the "open drawer" action (for accessibility).
  • A String resource to describe the "close drawer" action (for accessibility).
Then, whether or not you've created a subclass ofActionBarDrawerToggleas your drawer listener, you need to call upon yourActionBarDrawerTogglein a few places throughout your activity lifecycle:
我們希望使用app的圖標來打開和關閉側邊欄,根據谷歌開發者文檔 1.首先打開ActionBar Icon的功能 getSupportActionBar().setDisplayHomeAsUpEnabled(true); 2.使左上角的Home-Button可用,因為左上角的Home-Button也屬於menu的一種所以點擊時會回調onOptionItemSelected方法。 getSupportActionBar().setHomeButtonEnabled(true); 3.在onOptionItemSelected方法中將ActionBar上的圖標與Drawer結合起來。 if(mDrawerToggle.onOptionsItemSelected(item)){
returntrue;
} 4.需要將ActionDrawerToggler與DrawerLayout的狀態同步 ,將ActionBarDrawerTaggler中的drawer圖標,設置為ActionBar中的Home-Button的icon publicvoidonPostCreate(BundlesavedInstanceState,PersistableBundlepersistentState){
super.onPostCreate(savedInstanceState,persistentState);
mDrawerToggle.syncState();
} 5.谷歌開發者文檔建議使用onConfigurationChanged方法 ,當屏幕旋轉等發生Configuration變化的時候執行 publicvoidonConfigurationChanged(ConfigurationnewConfig){
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
} \

到此,我們使用谷歌開發者文檔提供的DrawerLayout成功完成了側滑菜單的開發! 項目源碼下載: https://github.com/icaruswang/DrawerLayoutUsing
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved