Android---62---DrawerLayout實現抽屜效果

來源:互聯網
上載者:User

標籤:android   drawerlayout   抽屜   

如何?android中的抽屜效果?

1.建立xml檔案

其根視圖是<android.support.v4.widget.DrawerLayout/>

這個xml分為兩部分,一部分是主要內容的視圖,一部分是抽屜的視圖。

主要內容視圖一般是FrameLayout,一定要是DrawerLayout的第一個視圖,其高度和父視圖的高度匹配。

 

 

抽屜視圖一般是ListView,在寫抽屜視圖的時候要注意

1.寬度一般要小於320dp

2.android:layout_gravity屬性是確定抽屜的位置

當該屬性為left/start時,位於左邊

當該屬性為right/end時,位於右邊

推薦使用start/end

3.android:choiceMode = “singleChoice”

4.android:divider 以及 android:dividerHeight

 

 

 

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/drawer_layout"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <FrameLayout        android:id="@+id/content_frame"        android:layout_width="match_parent"        android:layout_height="match_parent" >    </FrameLayout>    <ListView        android:id="@+id/left_drawer"        android:layout_width="240dp"        android:layout_height="match_parent"        android:layout_gravity="start"        android:choiceMode="singleChoice"        android:background="#ffffcc"        android:divider="@android:color/transparent"        android:dividerHeight="0dp" >    </ListView></android.support.v4.widget.DrawerLayout>


 

將這個xml檔案部署到模擬器上,就能看到一個簡單的效果:

 

 

 

2.為抽屜新增內容:

因為抽屜視圖裡是ListView,所以要用到Adapter

 

在Activity中聲明各種組件及所使用到的list,adapter

 

public class MainActivity extends Activity {private DrawerLayout mDrawerLayout;private ListView mDrawerList;private ArrayList<String> mList;private ArrayAdapter<String> adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);mDrawerList = (ListView) findViewById(R.id.left_drawer);// 初始化mlistmList = new ArrayList<String>();for (int i = 0; i < 5; i++) {mList.add("Item--->" + (i + 1));}// 初始化adapter// 適配器資料填充adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, mList);mDrawerList.setAdapter(adapter);}}


 

 

3.監聽左側ListView

現在點擊左側抽屜欄沒有什麼效果,需要為左側的LiseView設定監聽器(onItemClickListener)並實現onItemClick方法

 

當點擊左側抽屜裡的功能表項目時,在右邊主視圖內動態插入一個Fragment

需要建立一個class content_fragment繼承Fragment,並重寫onCreateView方法,返回inflater.inflate 方法產生的view

 

public class content_fragment extends Fragment {private TextView textView;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// inflater.inflate(resource, root, attachToRoot)View view = inflater.inflate(R.layout.fragment_content, container,false);textView = (TextView) view.findViewById(R.id.textView);// 接收傳遞過來的參數,並顯示到textView中String text = getArguments().getString("text");textView.setText(text);return view;}}


 

inflater.inflate(resource, root, attachToRoot)

 

Inflate的作用只是將xml定義的一個布局找出來

參數1:要載入的xml資源檔,載入出錯拋出InflateException

參數2:新產生視圖的父層

 

如果第三個參數attachToRoot為true,就將這個root作為根對象返回,否則僅僅將這個root對象的LayoutParams屬性附加到resource對象的根布局對象上,也就是布局檔案resource的最外層的View上,比如是一個LinearLayout或者其它的Layout對象。

 

當點擊左側抽屜內的某一功能表項目的時候需要為將要填充到FragmentLayout中的Fragment傳遞資料,通過Fragment的setArguments (Bundle )方法。

建立的Fragment中調用getArguments.getXX()方法即可獲得傳遞過來的資料。

 

 

// 設定監聽器mDrawerList.setOnItemClickListener(this);@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {// 動態插入一個Fragment到右側Fragment contentFragment = new content_fragment();Bundle bundle = new Bundle();bundle.putString("text", mList.get(position));// 傳遞資料contentFragment.setArguments(bundle);FragmentManager fm = getFragmentManager();fm.beginTransaction()// 開啟一個事務.replace(R.id.content_frame, contentFragment)// 建立的視圖替換掉原來的視圖,將contentFragment填充到右側.commit();// 當點擊了左側抽屜裡的某一功能表項目時,視圖會跳轉到右側顯示contentFragment,這時候,左側抽屜需要隱藏了mDrawerLayout.closeDrawer(mDrawerList);}


 

這時候在模擬器中啟動並執行話,點擊左側某一功能表項目就會在右側顯示相應的視圖。

點擊Item--->3

 

 

 

 4.監聽抽屜的開啟關閉

 

為DrawerLayout設定監聽器,當抽屜開啟/關閉的時候頂部的title會出現變化。

 

通常設定監聽有兩種方法:

1.DrawerLayout.setDrawerListener (DrawerLayout.DrawerListener)

2.如果Activity中包含了ActionBar,可以直接使用ActionBarDrawerToggle這個類,這個類是DrawerListener的子類

a) 改變android.R.id.home表徵圖

b) Drawer拉出或隱藏的時候帶有動畫效果 (syncState())

c) 可以監聽Drawer拉出、隱藏事件

 

覆寫ActionBarDrawerToggle的onDrawerOpened()和onDrawerClosed()以監聽抽屜拉出或隱藏

當使用ActionBarDrawerToggle時 覆寫Activity的onPostCreate 和onConfigurationChanged方法

 

 

public class MainActivity extends Activity implements OnItemClickListener {private DrawerLayout mDrawerLayout;private ListView mDrawerList;private ArrayList<String> mList;private ArrayAdapter<String> adapter;private ActionBarDrawerToggle mDrawerToggle;private String mTitle;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTitle = (String) getTitle();mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);mDrawerList = (ListView) findViewById(R.id.left_drawer);// 初始化mlistmList = new ArrayList<String>();for (int i = 0; i < 5; i++) {mList.add("Item--->" + (i + 1));}// 初始化adapter// 適配器資料填充adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, mList);mDrawerList.setAdapter(adapter);// 設定監聽器mDrawerList.setOnItemClickListener(this);mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,R.drawable.ic_drawer, // 應用左上方的表徵圖R.string.drawer_open, R.string.drawer_close) {// 覆寫 抽屜開啟/關閉時調用的方法@Overridepublic void onDrawerOpened(View drawerView) {super.onDrawerOpened(drawerView);// 當抽屜開啟的時候,頂部顯示的標題getActionBar().setTitle("請選擇");}@Overridepublic void onDrawerClosed(View drawerView) {super.onDrawerClosed(drawerView);// 當抽屜關閉的時候,顯示的標題getActionBar().setTitle(mTitle);}};mDrawerLayout.setDrawerListener(mDrawerToggle);}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {// 動態插入一個Fragment到右側Fragment contentFragment = new content_fragment();Bundle bundle = new Bundle();bundle.putString("text", mList.get(position));// 傳遞資料contentFragment.setArguments(bundle);FragmentManager fm = getFragmentManager();fm.beginTransaction()// 開啟一個事務.replace(R.id.content_frame, contentFragment)// 建立的視圖替換掉原來的視圖,將contentFragment填充到右側.commit();// 當點擊了左側抽屜裡的某一功能表項目時,視圖會跳轉到右側顯示contentFragment,這時候,左側抽屜需要隱藏了mDrawerLayout.closeDrawer(mDrawerList);}}


 

 

 

 

5.在右上方添加一個表徵圖,這個表徵圖其實是optionmenu

修改main.xml

 

<menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    tools:context="com.example.drawerlayoutbymyself.MainActivity" >    <item        android:id="@+id/action_websearch"        android:icon="@drawable/web_search"        android:showAsAction="ifRoom|withText"        android:title="webSearch"/></menu>


 

當抽屜開啟或是隱藏的時候需要重繪功能表項目,需要有onCreateOptionsMenu方法

 

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}


 

在mDrawerToggle的監聽事件中 添加invalidateOptionsMenu()方法

當調用該方法時,系統會自動調用onPrepareOptionsMenu方法,需要重寫該方法

 

@Overridepublic boolean onPrepareOptionsMenu(Menu menu) {// 抽屜是否被開啟boolean isDrawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);menu.findItem(R.id.action_websearch).setVisible(!isDrawerOpen);return super.onPrepareOptionsMenu(menu);}


 

 

 

 

 

 

這個時候,當抽屜開啟或隱藏的時候,螢幕右上方的表徵圖也會發生相應的變動。但是點擊這個表徵圖是沒有任何反應的。需要覆寫 onOptionsItemSelected方法

 

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.action_websearch:Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");Uri uri = Uri.parse("http://www.baidu.com");intent.setData(uri);startActivity(intent);break;default:break;}return super.onOptionsItemSelected(item);}


 

這時候點擊右上方的表徵圖時,會呼叫瀏覽器開啟百度首頁。

 

 完整代碼:

public class MainActivity extends Activity implements OnItemClickListener {private DrawerLayout mDrawerLayout;private ListView mDrawerList;private ArrayList<String> mList;private ArrayAdapter<String> adapter;private ActionBarDrawerToggle mDrawerToggle;private String mTitle;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTitle = (String) getTitle();mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);mDrawerList = (ListView) findViewById(R.id.left_drawer);// 初始化mlistmList = new ArrayList<String>();for (int i = 0; i < 5; i++) {mList.add("Item--->" + (i + 1));}// 初始化adapter// 適配器資料填充adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, mList);mDrawerList.setAdapter(adapter);// 設定監聽器mDrawerList.setOnItemClickListener(this);mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,R.drawable.ic_drawer, // 應用左上方的表徵圖R.string.drawer_open, R.string.drawer_close) {// 覆寫 抽屜開啟/關閉時調用的方法@Overridepublic void onDrawerOpened(View drawerView) {super.onDrawerOpened(drawerView);// 當抽屜開啟的時候,頂部顯示的標題getActionBar().setTitle("請選擇");// 重繪功能表項目,會自動調用 onPrepareOptionsMenu(),要重寫該方法invalidateOptionsMenu();}@Overridepublic void onDrawerClosed(View drawerView) {super.onDrawerClosed(drawerView);// 當抽屜關閉的時候,顯示的標題getActionBar().setTitle(mTitle);// 重繪功能表項目invalidateOptionsMenu();}};mDrawerLayout.setDrawerListener(mDrawerToggle);}@Overridepublic boolean onPrepareOptionsMenu(Menu menu) {// 抽屜是否被開啟boolean isDrawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);menu.findItem(R.id.action_websearch).setVisible(!isDrawerOpen);return super.onPrepareOptionsMenu(menu);}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {// 動態插入一個Fragment到右側Fragment contentFragment = new content_fragment();Bundle bundle = new Bundle();bundle.putString("text", mList.get(position));// 傳遞資料contentFragment.setArguments(bundle);FragmentManager fm = getFragmentManager();fm.beginTransaction()// 開啟一個事務.replace(R.id.content_frame, contentFragment)// 建立的視圖替換掉原來的視圖,將contentFragment填充到右側.commit();// 當點擊了左側抽屜裡的某一功能表項目時,視圖會跳轉到右側顯示contentFragment,這時候,左側抽屜需要隱藏了mDrawerLayout.closeDrawer(mDrawerList);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.action_websearch:Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");Uri uri = Uri.parse("http://www.baidu.com");intent.setData(uri);startActivity(intent);break;default:break;}return super.onOptionsItemSelected(item);}}


 

6.在左上方添加一個表徵圖,當使用者點擊表徵圖時,能夠開啟抽屜

 

在MainActivity的onCreate方法中添加代碼:

// 開啟ActionBar上APP ICON功能getActionBar().setDisplayHomeAsUpEnabled(true);getActionBar().setHomeButtonEnabled(true);


 

這個時候如果部署到模擬器的話,就會發現在左上方有一個返回的表徵圖,但是點擊沒有任何效果

 

 

 

// 將ActionBar上的表徵圖與Drawer結合起來if (mDrawerToggle.onOptionsItemSelected(item)) {return true;}


 

在onOptionsItemSelected方法中添加一個判斷,左上方的表徵圖也是一個  menu item

 

 這時候 點擊左上方的表徵圖 可以開啟抽屜,並且左上方表徵圖還有動畫效果

 

 

最終Activity代碼:

 

public class MainActivity extends Activity implements OnItemClickListener {private DrawerLayout mDrawerLayout;private ListView mDrawerList;private ArrayList<String> mList;private ArrayAdapter<String> adapter;private ActionBarDrawerToggle mDrawerToggle;private String mTitle;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTitle = (String) getTitle();mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);mDrawerList = (ListView) findViewById(R.id.left_drawer);// 初始化mlistmList = new ArrayList<String>();for (int i = 0; i < 5; i++) {mList.add("Item--->" + (i + 1));}// 初始化adapter// 適配器資料填充adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, mList);mDrawerList.setAdapter(adapter);// 設定監聽器mDrawerList.setOnItemClickListener(this);mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,R.drawable.ic_drawer, // 應用左上方的表徵圖R.string.drawer_open, R.string.drawer_close) {// 覆寫 抽屜開啟/關閉時調用的方法@Overridepublic void onDrawerOpened(View drawerView) {super.onDrawerOpened(drawerView);// 當抽屜開啟的時候,頂部顯示的標題getActionBar().setTitle("請選擇");// 重繪功能表項目,會自動調用 onPrepareOptionsMenu(),要重寫該方法invalidateOptionsMenu();}@Overridepublic void onDrawerClosed(View drawerView) {super.onDrawerClosed(drawerView);// 當抽屜關閉的時候,顯示的標題getActionBar().setTitle(mTitle);// 重繪功能表項目invalidateOptionsMenu();}};mDrawerLayout.setDrawerListener(mDrawerToggle);// 開啟ActionBar上APP ICON功能getActionBar().setDisplayHomeAsUpEnabled(true);getActionBar().setHomeButtonEnabled(true);}@Overridepublic boolean onPrepareOptionsMenu(Menu menu) {// 抽屜是否被開啟boolean isDrawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);menu.findItem(R.id.action_websearch).setVisible(!isDrawerOpen);return super.onPrepareOptionsMenu(menu);}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {// 動態插入一個Fragment到右側Fragment contentFragment = new content_fragment();Bundle bundle = new Bundle();bundle.putString("text", mList.get(position));// 傳遞資料contentFragment.setArguments(bundle);FragmentManager fm = getFragmentManager();fm.beginTransaction()// 開啟一個事務.replace(R.id.content_frame, contentFragment)// 建立的視圖替換掉原來的視圖,將contentFragment填充到右側.commit();// 當點擊了左側抽屜裡的某一功能表項目時,視圖會跳轉到右側顯示contentFragment,這時候,左側抽屜需要隱藏了mDrawerLayout.closeDrawer(mDrawerList);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// 將ActionBar上的表徵圖與Drawer結合起來if (mDrawerToggle.onOptionsItemSelected(item)) {return true;}switch (item.getItemId()) {case R.id.action_websearch:Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");Uri uri = Uri.parse("http://www.baidu.com");intent.setData(uri);startActivity(intent);break;default:break;}return super.onOptionsItemSelected(item);}@Overrideprotected void onPostCreate(Bundle savedInstanceState) {super.onPostCreate(savedInstanceState);// 需要將ActionDrawerToggle與DrawerLayout的狀態同步// 將ActionBarDrawerToggle中的drawer表徵圖,設定為Home-Button iconmDrawerToggle.syncState();}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);mDrawerToggle.onConfigurationChanged(newConfig);}}


 

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android---62---DrawerLayout實現抽屜效果

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.