Android DrawerLayout 侧滑


在support.v4包中新增的DrawerLayout可以满足基本的导航抽屉视图的需求,但是和网易等客户端相比还是有差距的

效果:

      

点击左边listview的栏目会切换背景,有2种方法调出左边的listview,一种是用手势从左向右滑动,一种是点击左上角的抽屉图片。

下面说下实现,是根据官网training给出的例子简化的。实现这个效果需要一点点Fragment和ActionBar的知识

第一步,.在布局文件中使用DrawerLayout

[html]  view plain copy
  1. <android.support.v4.widget.DrawerLayout  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/drawer_layout"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent">  
  6.     <!-- The main content view -->  
  7.     <FrameLayout  
  8.         android:id="@+id/content_frame"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="match_parent" />  
  11.     <!-- The navigation drawer -->  
  12.     <ListView android:id="@+id/left_drawer"  
  13.         android:layout_width="240dp"  
  14.         android:layout_height="match_parent"  
  15.         android:layout_gravity="start"  
  16.         android:choiceMode="singleChoice"  
  17.         android:divider="@android:color/transparent"  
  18.         android:dividerHeight="0dp"  
  19.         android:background="#111"/>  
  20. </android.support.v4.widget.DrawerLayout>  

要注意这几个原则:

1.主view( content view) 必须是drawerlayout的第一个子节点
2.主view宽和高必需match_parent
3. drawer view必须指定 android:layout_gravity 属性,如果值为“start”,会根据系统的语言顺序自动决定从左滑还是从右滑
4.  drawer view宽度不能太宽,最好不要超过320dp

这里主view是一个FrameLayout,用来切换Fragment,也就是显示的背景图片

第二步,初始化选择list

这里用最基本的adapter就可以

[java]  view plain copy
  1. mPlanetTitles = getResources().getStringArray(R.array.planets_array);  
  2.   
  3. mDrawerList = (ListView) findViewById(R.id.left_drawer);  
  4.   
  5. mDrawerList.setAdapter(new ArrayAdapter<String>(this,  
  6.         R.layout.drawer_list_item, mPlanetTitles));  

第三步,处理列表的点击,这里用DrawerItemClickListener,onItemClick方法中处理fragment的切换

[java]  view plain copy
  1. private class DrawerItemClickListener implements ListView.OnItemClickListener {  
  2.     @Override  
  3.     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  4.         selectItem(position);  
  5.     }  
  6. }  
[java]  view plain copy
  1. mDrawerList.setOnItemClickListener(new DrawerItemClickListener());  
第四步,监听抽屉的打开和关闭

如果activitiy中有ActionBar的话,可以用ActionBarDrawerToggle

[java]  view plain copy
  1. mDrawerToggle = new ActionBarDrawerToggle(  
  2.         this,                  /* host Activity */  
  3.         mDrawerLayout,         /* DrawerLayout object */  
  4.         R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */  
  5.         R.string.drawer_open,  /* "open drawer" description for accessibility */  
  6.         R.string.drawer_close  /* "close drawer" description for accessibility */  
  7.         ) {  
  8.     public void onDrawerClosed(View view) {  
  9.         getActionBar().setTitle(mTitle);  
  10.         invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()  
  11.     }  
  12.   
  13.     public void onDrawerOpened(View drawerView) {  
  14.         getActionBar().setTitle(mDrawerTitle);  
  15.         invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()  
  16.     }  
  17. };  
  18. mDrawerLayout.setDrawerListener(mDrawerToggle);  
第四步,让左上角的图标可以控制抽屉的打开和关闭

注意一定要设置这2个属性

[java]  view plain copy
  1. getActionBar().setDisplayHomeAsUpEnabled(true);  
  2. getActionBar().setHomeButtonEnabled(true);  

同时重写onOptionsItemSelected方法

[java]  view plain copy
  1. @Override  
  2. public boolean onOptionsItemSelected(MenuItem item) {  
  3.      // The action bar home/up action should open or close the drawer.  
  4.      // ActionBarDrawerToggle will take care of this.  
  5.     if (mDrawerToggle.onOptionsItemSelected(item)) {  
  6.         return true;  
  7.     }  
  8.     return false;  
  9. }  

下面是完整的代码:

工程目录:


布局文件:

activity_main.xml

[html]  view plain copy
  1. <android.support.v4.widget.DrawerLayout  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/drawer_layout"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent">  
  6.       
  7.       <FrameLayout  
  8.         android:id="@+id/content_frame"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="match_parent" />  
  11.         
  12.        <ListView  
  13.         android:id="@+id/left_drawer"  
  14.         android:layout_width="240dp"  
  15.         android:layout_height="match_parent"  
  16.         android:layout_gravity="start"  
  17.         android:choiceMode="singleChoice"  
  18.         android:divider="@android:color/transparent"  
  19.         android:dividerHeight="0dp"  
  20.         android:background="#111"/>   
  21. </android.support.v4.widget.DrawerLayout>  
  22.       

drawer_list_item.xml

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@android:id/text1"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="wrap_content"  
  6.     android:textAppearance="?android:attr/textAppearanceListItemSmall"  
  7.     android:gravity="center_vertical"  
  8.     android:paddingLeft="16dp"  
  9.     android:paddingRight="16dp"  
  10.     android:textColor="#fff"  
  11.     android:background="?android:attr/activatedBackgroundIndicator"  
  12.     android:minHeight="?android:attr/listPreferredItemHeightSmall"/>  

fragment_planet.xml

[html]  view plain copy
  1. <ImageView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/image"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#000000"  
  6.     android:gravity="center"  
  7.     android:padding="32dp" />  


资源文件 strings.xml,每个item的值和drawable文件夹下的图片名字一样

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string name="app_name">Navigation Drawer Example</string>  
  4.     <string-array name="planets_array">  
  5.         <item>Mercury</item>  
  6.         <item>Venus</item>  
  7.         <item>Earth</item>  
  8.         <item>Mars</item>  
  9.         <item>Jupiter</item>  
  10.         <item>Saturn</item>  
  11.         <item>Uranus</item>  
  12.         <item>Neptune</item>  
  13.     </string-array>  
  14.       
  15.     <string name="drawer_open">Open navigation drawer</string>  
  16.     <string name="drawer_close">Close navigation drawer</string>  
  17.     <string name="action_websearch">Web search</string>  
  18.     <string name="app_not_available">Sorry, there\'s no web browser available</string>  
  19. </resources>  


MainActivity.java

[java]  view plain copy
  1. public class MainActivity extends Activity {  
  2.     private DrawerLayout mDrawerLayout;  
  3.     private ListView mDrawerList;  
  4.     private ActionBarDrawerToggle mDrawerToggle;  
  5.   
  6.     private CharSequence mDrawerTitle;  
  7.     private CharSequence mTitle;  
  8.     private String[] mPlanetTitles;  
  9.   
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.activity_main);  
  14.   
  15.         mTitle = mDrawerTitle = getTitle();  
  16.         mPlanetTitles = getResources().getStringArray(R.array.planets_array);  
  17.         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);  
  18.         mDrawerList = (ListView) findViewById(R.id.left_drawer);  
  19.   
  20.         mDrawerList.setAdapter(new ArrayAdapter<String>(this,  
  21.                 R.layout.drawer_list_item, mPlanetTitles));  
  22.         mDrawerList.setOnItemClickListener(new DrawerItemClickListener());  
  23.   
  24.         //使得左上角的图标可以控制drawerlayout  
  25.         getActionBar().setDisplayHomeAsUpEnabled(true);  
  26.         getActionBar().setHomeButtonEnabled(true);  
  27.   
  28.         // ActionBarDrawerToggle ties together the the proper interactions  
  29.         // between the sliding drawer and the action bar app icon  
  30.         mDrawerToggle = new ActionBarDrawerToggle(  
  31.                 this,                  /* host Activity */  
  32.                 mDrawerLayout,         /* DrawerLayout object */  
  33.                 R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */  
  34.                 R.string.drawer_open,  /* "open drawer" description for accessibility */  
  35.                 R.string.drawer_close  /* "close drawer" description for accessibility */  
  36.                 ) {  
  37.             public void onDrawerClosed(View view) {  
  38.                 getActionBar().setTitle(mTitle);  
  39.                 invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()  
  40.             }  
  41.   
  42.             public void onDrawerOpened(View drawerView) {  
  43.                 getActionBar().setTitle(mDrawerTitle);  
  44.                 invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()  
  45.             }  
  46.         };  
  47.         mDrawerLayout.setDrawerListener(mDrawerToggle);  
  48.   
  49.         if (savedInstanceState == null) {  
  50.             selectItem(0);  
  51.         }  
  52.     }  
  53.     @Override  
  54.     public boolean onOptionsItemSelected(MenuItem item) {  
  55.          // The action bar home/up action should open or close the drawer.  
  56.          // ActionBarDrawerToggle will take care of this.  
  57.         if (mDrawerToggle.onOptionsItemSelected(item)) {  
  58.             return true;  
  59.         }  
  60.         return false;  
  61.     }  
  62.   
  63.     /* The click listner for ListView in the navigation drawer */  
  64.     private class DrawerItemClickListener implements ListView.OnItemClickListener {  
  65.         @Override  
  66.         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  67.             selectItem(position);  
  68.         }  
  69.     }  
  70.   
  71.     private void selectItem(int position) {  
  72.         // update the main content by replacing fragments  
  73.         Fragment fragment = new PlanetFragment();  
  74.         Bundle args = new Bundle();  
  75.         args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);  
  76.         fragment.setArguments(args);  
  77.   
  78.         FragmentManager fragmentManager = getFragmentManager();  
  79.         fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();  
  80.   
  81.         // update selected item and title, then close the drawer  
  82.         mDrawerList.setItemChecked(position, true);  
  83.         setTitle(mPlanetTitles[position]);  
  84.         mDrawerLayout.closeDrawer(mDrawerList);  
  85.     }  
  86.   
  87.     @Override  
  88.     public void setTitle(CharSequence title) {  
  89.         mTitle = title;  
  90.         getActionBar().setTitle(mTitle);  
  91.     }  
  92.   
  93.     /** 
  94.      * Fragment that appears in the "content_frame", shows a planet 
  95.      */  
  96.     public static class PlanetFragment extends Fragment {  
  97.         public static final String ARG_PLANET_NUMBER = "planet_number";  
  98.   
  99.         public PlanetFragment() {  
  100.             // Empty constructor required for fragment subclasses  
  101.         }  
  102.   
  103.         @Override  
  104.         public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  105.                 Bundle savedInstanceState) {  
  106.             View rootView = inflater.inflate(R.layout.fragment_planet, container, false);  
  107.             int i = getArguments().getInt(ARG_PLANET_NUMBER);  
  108.             String planet = getResources().getStringArray(R.array.planets_array)[i];  
  109.   
  110.             int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),  
  111.                             "drawable", getActivity().getPackageName());  
  112.             ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);  
  113.             getActivity().setTitle(planet);  
  114.             return rootView;  
  115.         }  
  116.     }  
  117. }  

用到的图片资源官网的training页面都有的。

http://developer.android.com/training/implementing-navigation/nav-drawer.html#ActionBarIcon


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值