Android側滑菜單DrawerLayout

jopen 10年前發布 | 2K 次閱讀 Java Android

側滑菜單控件DrawerLayout是Support 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

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