<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"> <!-- The main content view --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- The navigation drawer --> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="1dp" android:background="#111"/> </android.support.v4.widget.DrawerLayout>
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:paddingLeft="16dp" android:paddingRight="16dp" android:textColor="#fff" android:background="?android:attr/activatedBackgroundIndicator" android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
package com.example.navigationdemo; import android.os.Bundle; import android.app.Activity; import android.support.v4.widget.DrawerLayout; import android.view.Menu; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { private String[] mPlanetTiles; private DrawerLayout mDrawerLayout; private ListView mDrawerList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPlanetTiles = getResources().getStringArray(R.array.planets_array); mDrawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList= (ListView) findViewById(R.id.left_drawer); mDrawerList.setAdapter(new ArrayAdapter<String>(this,R.layout.drawer_list_item,mPlanetTiles)); mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); } @Override public 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; } private class DrawerItemClickListener implements ListView.OnItemClickListener{ @Override public void onItemClick(AdapterView parent, View view, int position, long id) { // TODO Auto-generated method stub selectItem(position); } } public void selectItem(int position) { // TODO Auto-generated method stub Log.d("",position+""); } }
到了这一步就基本可用跑起来了,运行看看效果:
点两下:
不过还有点问题,左边的侧滑栏并不会在点击后自动收回。我们继续。
继续增加下面的代码:
public void selectItem(int position) { // Create a new fragment and specify the planet to show based on position Log.d("",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()//此函数返回一个FragmentTransactiond对象,用来开始一系列对Fragments的操作 .replace(R.id.content_frame, fragment)//Replace an existing fragment that was added to a container //依旧返回返回一个FragmentTransactiond对象 .commit(); // Highlight the selected item, update the title, and close the drawer mDrawerList.setItemChecked(position, true); setTitle(mPlanetTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } public static class PlanetFragment extends Fragment { public static final String ARG_PLANET_NUMBER = "planet_number"; public PlanetFragment() { // Empty constructor required for fragment subclasses } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
//作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化 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; }
同样,增加一个fragment_planet的布局:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" android:gravity="center" android:padding="32dp" />
当你点击了listview中的项目时,系统就会setOnItemClickListener()函数设定的OnItemClickListener 类里的
onItemClick()函数。
上面这段代码的作用就是在点击了Drawer对应项目之后,新生成一个Fragment,将现有的替换掉。然后关闭Drawer。
官方demo中用的是几颗行星的图片,所以对应变量也是,我随便放了几张图片上去:
不过还是有点小问题,程序刚运行的时候,并没有任何fragment被载入,程序是一片空白。
接下来要实现的效果是点击actionbar上的图标来展示drawer,同时还有一个指示的动画。
我们需要使用ActionBarDrawerToggle的类:
This class provides a handy way to tie together the functionality
of DrawerLayout
and
the framework ActionBar
to implement the recommended
design for navigation drawers.
To use ActionBarDrawerToggle
, create one in your Activity
and call through to the following methods corresponding to your Activity
callbacks:
Call syncState()
from
your Activity
‘s onPostCreate
to
synchronize the indicator with the state of the linked DrawerLayout
after onRestoreInstanceState
has occurred.
ActionBarDrawerToggle
can be used directly as
a DrawerLayout.DrawerListener
,
or if you are already providing your own listener, call through to each of the
listener methods from your own.
在activity的OnCreate函数里加入:
getActionBar().setDisplayHomeAsUpEnabled(true);
显示向上箭头
getActionBar().setHomeButtonEnabled(true);让程序图标可以点击。
接下来在,activity里重写一个函数,用来在点击图标后drawer。
@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); }
其余的应该都是保持、恢复程序状态的函数。
ActionBarDrawerToggle也提供了onDrawerClosed(View drawerView) onDrawerOpened(View drawerView) 的函数,动态改变actionbar的标题就是用这个。比较有技巧的一点是,每次改变标题的时候需要把之前的标题保存下来。
项目代码参考:http://developer.android.com/training/implementing-navigation/nav-drawer.html