Android側滑菜單DrawerLayout

fydxdk 9年前發布 | 21K 次閱讀 Android Android開發 移動開發

側滑菜單控件DrawerLayoutSupport Library包中實現了側滑菜單效果的控件,也許是因為第三方控件如MenuDrawer等的出現之后,Google借鑒而出現的產物。DrawerLayout分為側邊菜單和主內容兩部分,側邊菜單可以根據手勢展開與隱藏(DrawerLayout自身特性),主內容區的內容可以隨著菜單的點擊而變化,內容就要自己去實現啦。

下面的例子主要是根據官方文檔移植過來的,簡單的改動:

-----------------------界面布局----------------------------------------


<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/test_drawer_layout"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >


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


    <ListView
        android:id="@+id/left_drawer_lv"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="1dp" />


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

布局說明:

1、創建Drawer Layout在需要抽屜菜單的界面,用DrawerLayout 作為界面根控件。
2、在DrawerLayout里面第一個View為當前界面主內容;第二個和第三個View為抽屜菜單內容。如果當前界面只需要一個抽屜菜單,則第三個View可以省略。
3、下面的例子中DrawerLayout里面包含兩個View,第一個FrameLayout中是當前界面主要內容顯示區域;第二個ListView為抽屜菜單內容。

--------------------代碼部分------------------------------------

public class TestDrawerActivity extends Activity {
/**抽屜菜單(作為根布局) */

private DrawerLayout mDrawerLayout;
/**抽屜菜單之:左邊菜單 */
private ListView mDrawerList;
/**抽屜菜單之:應用圖標指示抽屜開關 */
private ActionBarDrawerToggle mDrawerToggle;
/**抽屜標題*/
private CharSequence mDrawerTitle;
/**抽屜菜單之:左邊菜單數據 */
private String[] mLeftTitles;



@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_drawer);
findViewById();
setListeners();
initdata();
if (savedInstanceState == null) {
selectItem(0);
}
}



private void findViewById() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.test_drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer_lv);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
/**菜單關閉操作*/
public void onDrawerClosed(View view) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu();
}



/**打開菜單操作 */
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu();
}
};
}



private void setListeners() {
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDrawerLayout.setDrawerListener(mDrawerToggle);
}



private void initdata() {
/**菜單標題*/
mDrawerTitle = getTitle();
mLeftTitles = getResources().getStringArray(R.array.planets_array);
/**設置拉出導航菜單時陰影,官方示例不明顯,可把圖片背景修改一下*/
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mLeftTitles));
/**ActionBar操作模式開啟*/
getActionBar().setDisplayHomeAsUpEnabled(false);
getActionBar().setHomeButtonEnabled(false);
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}



@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}



@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) { return true; }
switch (item.getItemId()) {
case R.id.action_websearch:
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
else {
Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}



/**菜單列表的點擊操作*/
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 = new PlanetFragment();
Bundle args = new Bundle();
args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);



FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_fr_layout, fragment).commit();
mDrawerList.setItemChecked(position, true);
setTitle(mLeftTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}



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



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



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



public static class PlanetFragment extends Fragment {
public static final String ARG_PLANET_NUMBER = "planet_number";



public PlanetFragment() {
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
int i = getArguments().getInt(ARG_PLANET_NUMBER);
String planet = getResources().getStringArray(R.array.planets_array)[i];



int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()), "drawable", getActivity().getPackageName());
((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
getActivity().setTitle(planet);
return rootView;
}
}
}
android.support.v4.widget.DrawerLayout使用時注意事項:

事項1:顯示界面主要內容的View (上面的 FrameLayout ) 必須為DrawerLayout的第一個子View, 國為XML布局文件中的View順序為Android系統中的 z-ordering順序,而抽屜必須出現在內容之上。顯示界面內容的View寬度和高度設置為和父View一樣,原因在于當抽屜菜單不可見的時候,界面內容代表整個界面UI。

事項2:抽屜菜單 ( ListView) 必須使用android:layout_gravity屬性設置水平的 gravity值 。如果要支持 right-to-left (RTL,從右向左閱讀)語言 用 "start" 代替 "left" (當在 RTL語言運行時候,菜單出現在右側)。抽屜菜單的寬度為 dp 單位而高度和父View一樣。抽屜菜單的寬度建議不超過320dp,這樣用戶可以在菜單打開的時候看到部分內容界面。

事項3:如果需要監聽菜單打開關閉事件,則需要調用 DrawerLayout類的 setDrawerListener() 函數,參數為 DrawerLayout.DrawerListener接口的實現。該接口提供了菜單打開關閉等事件的回調函數,例如 onDrawerOpened() 和onDrawerClosed()。

事項4:如果您的Activity使用了 action bar,則您可以使用Support庫提供的 ActionBarDrawerToggle 類,該類實現了 DrawerLayout.DrawerListener接口,并且您還可以根據需要重寫相關的函數。該類實現了菜單和Action bar相關的操作。當菜單顯示的時候您應該根據情況隱藏ActionBar上的功能菜單并且修改ActionBar的標題,可以使用 ActionBarDrawerToggle 類來實現這些功能。

官網詳細說明:http://developer.android.com/design/patterns/navigation-drawer.html</span>

 本文由用戶 fydxdk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!