Android侧滑菜单DrawerLayout(抽屉布局)实现

jopen 10年前

应用场景:

           由于侧滑菜单有更好的用户体验效果,所以更多的App使用侧滑抽屉式菜单列表,如网易客户端、百度影音、爱奇艺等等。至此,侧滑菜单有了更多的使用需求。

知识点介绍:

        实现侧滑菜单功能的方法有很多,如果开源的项目SlidingMenu,下载地址为https://github.com/jfeinstein10/SlidingMenu。该开源项目依赖于另一个开源项目ActionBarSherlock,下载地址为https://github.com/JakeWharton/ActionBarSherlock。这种实现方式,读者可以平时有时间自行研究一下。本例主要介绍android-support-v4.jar提供的支持,android.support.v4.widget.DrawerLayout,可兼容低版本的系统。

使用方式:

第一步:新建测试项目DrawerLayout。
第二步:编写相关的布局文件,主界面布局文件activity_main.xml。

</div>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical"        tools:context=".MainActivity" >        <android.support.v4.widget.DrawerLayout            android:id="@+id/drawer_layout"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:background="@android:color/white" >            <FrameLayout                android:id="@+id/fragment_layout"                android:layout_width="match_parent"                android:layout_height="match_parent"                android:background="@android:color/white" >                <TextView                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:gravity="center"                    android:text="主内容界面" />            </FrameLayout>            <!--             android:layout_gravity="start" 侧滑菜单在左边            android:layout_gravity="start" 侧滑菜单在右边             -->            <LinearLayout                android:id="@+id/menu_layout"                android:layout_width="180dp"                android:layout_height="match_parent"                android:layout_gravity="start"                android:background="@android:color/white"                android:orientation="vertical" >                <ImageView                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:gravity="center"                    android:src="@drawable/ic_launcher" />                <TextView                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:gravity="center"                    android:text="侧拉菜单"                    android:textColor="@android:color/black" />                <!--                android:cacheColorHint="#FFFFFF"                解决Android ListView 滚动 Item 背景变黑的问题                -->                <ListView                    android:id="@+id/menu_listView"                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:cacheColorHint="#FFFFFF" >                </ListView>            </LinearLayout>        </android.support.v4.widget.DrawerLayout>    </LinearLayout> 
</div> Fragment类的布局文件layout_first.xml,layout_next.xml。</div>
【layout_first.xml】
    <?xml version="1.0" encoding="utf-8"?>        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical" >            <TextView                 android:layout_width="match_parent"                android:layout_height="20dp"                android:text="FirstFragment"                android:id="@+id/textTextView"/>            <LinearLayout android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="vertical">                <ListView android:layout_height="wrap_content"                    android:layout_width="wrap_content"                    android:cacheColorHint="#FFFFFF"                    android:id="@+id/firstFragmentListView">                </ListView>            </LinearLayout>        </LinearLayout>  
</div> </div>
【layout_next.xml】</div>
    <?xml version="1.0" encoding="utf-8"?>        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical" >            <TextView                 android:layout_height="wrap_content"                android:layout_width="match_parent"                android:text="NextFragment"/>        </LinearLayout>  
</div> </div>
ListView的ListItem的布局文件main_listitem.xml。
</div>
【main_listitem.xml】
    <?xml version="1.0" encoding="utf-8"?>        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical" >            <TextView android:layout_width="match_parent"                android:layout_height="40dp"                android:id="@+id/menu"                android:textSize="20dp"                android:gravity="center_vertical"                android:text="加载中..."/>        </LinearLayout>  
</div> </div> 第二步:编写相关的java文件,FirstFragment.java、NextFragment、MainActivity.java、MenuListViewAdapter.java、DataBuiltUtils.java。
【FirstFragment.java】
</div>
    import android.os.Bundle;        import android.support.v4.app.Fragment;        import android.view.LayoutInflater;        import android.view.View;        import android.view.View.OnClickListener;        import android.view.ViewGroup;        import android.widget.ListView;        import android.widget.TextView;        import android.widget.Toast;        public class FirstFragment extends Fragment{            private TextView textView;            private ListView listView;                         @Override            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)            {                View layout = inflater.inflate(R.layout.layout_first, null);                textView = (TextView) layout.findViewById(R.id.textTextView);                textView.setOnClickListener(new OnClickListener() {                                        @Override                    public void onClick(View arg0) {                        Toast.makeText(getActivity(), "FirstFragment", Toast.LENGTH_SHORT).show();                    }                });                listView = (ListView) layout.findViewById(R.id.firstFragmentListView);                MenuListViewAdapter adapter = new MenuListViewAdapter(getActivity(), DataBuiltUtils.getFirstMapList());                listView.setAdapter(adapter);                return layout;            }        }  
</div> </div> 【NextFragment.java】</div>
    import android.os.Bundle;        import android.support.v4.app.Fragment;        import android.view.LayoutInflater;        import android.view.View;        import android.view.ViewGroup;                public class NextFragment extends Fragment{                        @Override            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){                View layout = inflater.inflate(R.layout.layout_next, null);                return layout;            }        }  
</div> </div>
【MainActivity.java】</div>
    import java.util.ArrayList;        import java.util.HashMap;                import android.os.Bundle;        import android.app.Activity;        import android.content.Context;        import android.support.v4.app.Fragment;        import android.support.v4.app.FragmentActivity;        import android.support.v4.app.FragmentTransaction;        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.LinearLayout;        import android.widget.ListView;        import android.widget.RelativeLayout;        import android.widget.AdapterView.OnItemClickListener;                /**        * 抽屉效果        * DrawerLayout与Fragment的联用        * DrawerLayout相关:        * 1.一般内容层使用framelayout        * 2.slidingLayout需要设置一个layout_grative属性        *   文档建议使用android:layout_gravity="start"        */        public class MainActivity extends FragmentActivity{                       private DrawerLayout mDrawer_layout;  //抽屉式布局            private LinearLayout mMenu_layout;                                            @Override            protected void onCreate(Bundle savedInstanceState){                super.onCreate(savedInstanceState);                setContentView(R.layout.activity_main);                mDrawer_layout = (DrawerLayout) findViewById(R.id.drawer_layout);                mMenu_layout = (LinearLayout) findViewById(R.id.menu_layout);                ListView menu_listview = (ListView) mMenu_layout.findViewById(R.id.menu_listView);                ArrayList<HashMap<String, String>> tempMapList = DataBuiltUtils.getMainMapList();                menu_listview.setAdapter(new MenuListViewAdapter( getApplicationContext(), tempMapList));                //菜单ListView设置监听事件                menu_listview.setOnItemClickListener(new DrawerItemClickListener());            }                                         public class DrawerItemClickListener implements OnItemClickListener {                                @Override                public void onItemClick(AdapterView<?> parent, View view, int position, long id){                    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();                    Fragment fragment = null;                    //根据item点击行号判断启用指定Fragment                    switch (position){                        case 0:                            fragment = new FirstFragment();                            break;                        case 1:                            fragment = new NextFragment();                            break;                        default:                             fragment = new FirstFragment();                            break;                    }                    ft.replace(R.id.fragment_layout, fragment);                    ft.commit();                    mDrawer_layout.closeDrawer(mMenu_layout);//点击后关闭mMenu_layout                }            }        }  
</div> </div>
【MenuListViewAdapter.java】</div>
    import java.util.HashMap;        import java.util.List;        import java.util.Map;                import android.content.Context;        import android.view.LayoutInflater;        import android.view.View;        import android.view.ViewGroup;        import android.widget.BaseAdapter;        import android.widget.TextView;                public class MenuListViewAdapter extends BaseAdapter {            private List<HashMap<String, String>> lists;            private LayoutInflater mInflater;            private Context mainContext;                    public MenuListViewAdapter(Context context,                    List<HashMap<String, String>> dataList) {                mInflater = LayoutInflater.from(context);                mainContext = context;                lists = dataList;            }                    @Override            public int getCount() {                return lists.size();            }                    @Override            public Object getItem(int position) {                return lists.get(position);            }                    @Override            public long getItemId(int position) {                return position;            }                    @Override        public View getView(final int position, View convertView, ViewGroup parent) {                ViewHolder holder = null;                if (convertView == null) {                    holder = new ViewHolder();                    convertView = mInflater.inflate(R.layout.main_listitem, null);                    holder.menu = (TextView) convertView.findViewById(R.id.menu);                    convertView.setTag(holder);                } else {                    holder = (ViewHolder) convertView.getTag();                }                // 设置背景色                // if(position%2==1){                // convertView.setBackgroundColor(Color.rgb(220, 220, 220));                // }else {                // convertView.setBackgroundColor(Color.rgb(255, 250, 250));                // }                if (lists.size() > 0) {                    final Map<String, String> map = lists.get(position);                    String number = (String) map.get("menu");                    holder.menu.setText(number);                }                return convertView;            }                    static class ViewHolder {                TextView   menu;    //菜单名称            }        }  
</div> </div> 【DataBuiltUtils.java】
</div>
import java.util.ArrayList;    import java.util.HashMap;        public class DataBuiltUtils {            public static ArrayList<HashMap<String,String>> getMainMapList(){            ArrayList<HashMap<String, String>> tempMapList = new ArrayList<HashMap<String,String>>();                        for(int i=0;i<5;i++){                HashMap<String, String> tempMap = new HashMap<String, String>();                tempMap.put("menu", "菜单【"+(i+1)+"】");                tempMapList.add(tempMap);            }            return tempMapList;        }                public static ArrayList<HashMap<String,String>> getFirstMapList(){            ArrayList<HashMap<String, String>> tempMapList = new ArrayList<HashMap<String,String>>();                        for(int i=0;i<5;i++){                HashMap<String, String> tempMap = new HashMap<String, String>();                tempMap.put("menu", "FirstFragment菜单【"+(i+1)+"】");                tempMapList.add(tempMap);            }            return tempMapList;        }    }