侧滑控件DrawerLayout浅析

DrawerLayout是android.support.v4.view包中定义的侧滑系统控件,在很多商业APP中都使用了侧滑控件,如下所示:


这里写图片描述
网易新闻客户端中的侧滑菜单


这里写图片描述
腾讯QQ客户端中的侧滑菜单


本文将浅析一个利用DrawerLayout实现侧滑功能的简易菜单,点击侧滑菜单中的每一项,将切换Activity中的Fragment。


activity的XML布局


主Activity的XML布局代码如下:


<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" />

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

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

注意事项:


  • 要使用DrawerLayout的全限定包名:android.support.v4.widget.DrawerLayout;

  • 主视图内容(上述代码为FrameLayout)必须是DrawerLayout的第一个子控件;

  • 侧滑视图(上述代码为ListView)需指定属性android:layout_gravity,属性值”start”代表抽屉菜单隐藏在屏幕左侧,从左向右可滑出;属性值”end”反之。属性值”left”和”right”同样可实现相应效果,但Google官方不推荐使用;

  • 侧滑视图的的宽度(用属性android:layout_width指定)尽量不要超过320dp,以保证看到一些主视图内容;

侧滑菜单ListView的XML布局

代码如下:


<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:background="?android:attr/activatedBackgroundIndicator"
    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:textColor="#fff" />

定义Fragment的布局XML

为Fragment定义布局代码如下:


<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:textSize="50sp"/>

Activity逻辑实现


public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private String[] mItemArray;

    @Override
    public 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);
        mItemArray = getResources().getStringArray(R.array.item_array);

        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mItemArray));

        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    }

    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 MyFragment();
        Bundle args = new Bundle();
        args.putInt(MyFragment.ITEM_NUMBER, position);
        fragment.setArguments(args);

        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment)
                .commit();
        //点击ListView中的项时给用户以反馈
        mDrawerList.setItemChecked(position, true);
        //打开主内容视图的同时,收起滑动菜单DrawerLayout
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    public static class MyFragment extends Fragment {
        public static final String ITEM_NUMBER = "item_number";

        public MyFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_item, container, false);
            int i = getArguments().getInt(ITEM_NUMBER);
            String itemName = getResources().getStringArray(R.array.item_array)[i];
            ((TextView) (rootView.findViewById(R.id.textview))).setText(itemName);
            return rootView;
        }
    }
}

要点总结:

  1. 创建Drawer布局文件;
  2. 初始化Drawer列表;
  3. 响应Drawer列表的点击事件。

效果演示


当从屏幕左侧边缘向右滑动时,有如下效果:
这里写图片描述


点击某一项,切换至相应fragment:

这里写图片描述这里写图片描述


补充

为DrawerLayout添加监听事件的注意事项:


  • mDrawerLayout.setDrawerListener(DrawerLayout.DrawerListener);

为DrawerLayout绑定监听器,并传入DrawerLayout的内部接口对象DrawerListener,可以监听当DrawerLayout处于滑入滑出状态时,触发动作事件。


  • ActionBarDrawerToggle是DrawerLayout.DrawerListener的具体实现类:
    –修改ActionBar的默认图标(通过其构造方法改变android.R.id.home图标);
    –DrawerLayout被拉出、隐藏时,通过该类添加动画效果 (syncState()方法);
    –重写ActionBarDrawerToggle的onDrawerOpened()和onDrawerClosed()方法,以监听DrawerLayout被拉出和隐藏时的动作事件;

  • 重写Activity的onPostCreate()和 onConfigurationChanged()方法,以配合syncState()方法实现ActionBar上图标的动画效果。

这里写图片描述


这里写图片描述
当DrawerLayout被拉出时,ActionBar右上角的图标(如搜索图标)隐藏


这里写图片描述
当DrawerLayout被收起时,ActionBar右上角的图标显示


  • 如上所示,为实现当DrawerLayout被拉出时,ActionBar右上角的图标(如搜索图标)隐藏;当DrawerLayout被收起时,ActionBar右上角的图标显示的效果,可在onDrawerOpened()和onDrawerClosed()方法中添加invalidateOptionMenu()方法,以重绘该图标,在执行该方法之前,系统会先调用onPrepareOptionsMenu(Menu menu)方法,可通过该方法设置DrawerLayout被拉出和隐藏时,ActionBar右上角图标的隐藏状态:这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值