1.下载开源SlidingMenu,去Github下载 https://github.com/jfeinstein10/SlidingMenu。
SlidingMenu是一个强大的侧边栏导航框架,自己去codeKK看了源码分析才有了更多的收获 :http://codekk.com/open-source-project-analysis/detail/Android/huxian99/SlidingMenu%20源码解析,这个网站codeKK有许多开源项目的源码解析,是个很不错的学习资源,很感谢这些大牛的奉献。力推这个网站codeKK。
此文章只是自己学习笔记记录,看这个大牛写的,自己加之整理学习了下,感兴趣的看他写的,http://blog.csdn.net/yangyu20121224/article/details/9255829。
1>SlidingMenu功能介绍
SlidingMenu 是一个强大的侧边栏导航框架,主要特点如下:
(1) 侧边栏可以是一个 Fragment,包含任何 View
(2) 使用简单方便,支持左滑和右滑等
(3) 自定义侧边栏显示动画
2>总体设计
SlidingMenu 总体由三个主要的类组成。
(1) SlidingMenu 继承自 RelativeLayout,对外暴露 API 给用户,同时在添加 CustomViewAbove 和。 CustomViewBehind
(2) CustomViewAbove 继承自 ViewGroup,主要用来处理触摸屏事件。
(3) CustomViewBehind 继承自 ViewGroup,主要用来配置参数,显示侧边栏的 Menu 部分。
2.下载SlidingMenu直接导入eclipse,自己再新建Android项目,取名SlidingMenuDemo,之后,右击SlidingMenuDemo-->properties->Android->Add(下面)关联SlidingMenu->Apply->OK,就行,参考下图1. 注意关联后,将SlidingMenuDemo项目中lib下的android-support-v4.jar删除,因为SlidingMenu以及存android-support-v4.jar,否则后面在MainActivity.java会报错。
3. 效果图如下,可以左右滑动,
4.项目类以及布局有关介绍,如下图:
5.具体代码:
1>left_function_fragment.xml 为左侧菜单栏布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myapp="http://schemas.android.com/apk/res-auto" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#6B6B6B" android:orientation="vertical" > <LinearLayout android:id="@+id/logout_layout" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="2" android:gravity="center_horizontal" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16.0dip" android:layout_marginTop="34.0dip" android:orientation="horizontal" > <ImageView android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_num2" /> <ImageView android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="30.0dip" android:layout_marginRight="30.0dip" android:src="@drawable/ic_num4" /> <ImageView android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_num5" /> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="13.0dip" android:text="一个吊车尾改变世界的故事" android:textColor="#ffffff" android:textSize="11.0sp" /> <TextView android:layout_width="match_parent" android:layout_height="0.5dp" android:background="#ff272727" /> </LinearLayout> <ScrollView android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="3" > <com.example.slidingdemo.MyListView android:id="@+id/list_itme" android:layout_width="match_parent" android:layout_height="200dp" /> </ScrollView> <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_marginBottom="10.0dip" android:layout_marginLeft="19.0dip" android:layout_weight="1" android:gravity="center_vertical" android:orientation="horizontal" > <TextView android:id="@+id/setting" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15.0dip" android:text="设置" android:textColor="#ffffff" android:textSize="15.0sp" /> <TextView android:id="@+id/setting1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15.0dip" android:text="其他" android:textColor="#ffffff" android:textSize="15.0sp" /> </LinearLayout> </LinearLayout>
2>main_content_frame.xml 为存放右侧菜单内容的Fragment布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout>
3>menu_frame.xml 是用来存放菜单的Fragment
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/menu_frame" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout>
4>content_item.xml为菜单内容listview的item
<?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="50dp" android:orientation="horizontal" > <ImageView android:id="@+id/row_icon" android:layout_width="50dp" android:layout_height="50dp" android:padding="10dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/row_title" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:padding="10dp" android:text="Medium Text111" android:textColor="@android:color/white" android:background="@android:color/holo_blue_light" android:textAppearance="@android:style/TextAppearance.Medium" /> </LinearLayout>
5>list.xml为右边每个菜单内容中的Listview布局
<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView>
6>menu_item.xml为菜单栏中MyListView中的item
<?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="50dp" android:orientation="horizontal" > <ImageView android:id="@+id/row_icon" android:layout_width="50dp" android:layout_height="50dp" android:padding="10dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/row_title" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:padding="10dp" android:text="Medium Text111" android:textColor="@android:color/white" android:textAppearance="@android:style/TextAppearance.Medium" /> </LinearLayout>
在values下的dimens.xml添加了这个2个大小属性:
<dimen name="shadow_width">20dp</dimen> <dimen name="slidingmenu_offset">40dp</dimen>
接着是类
1> MenuListFragment.java是左侧菜单类:
package com.example.slidingdemo; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; public class MenuListFragment extends Fragment { private MyListView listview; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.left_function_fragment, null); listview=(MyListView)view.findViewById(R.id.list_itme); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); SampleAdapter adapter = new SampleAdapter(getActivity()); adapter.add(new SampleItem("菜单 List 鸣人", R.drawable.ic_num6)); adapter.add(new SampleItem("菜单 List 佐助", R.drawable.ic_num2)); adapter.add(new SampleItem("菜单 List 卡卡西", R.drawable.ic_num3)); adapter.add(new SampleItem("菜单 List 我爱罗", R.drawable.ic_num7)); adapter.add(new SampleItem("菜单 List 自来也", R.drawable.ic_num4)); adapter.add(new SampleItem("菜单 List 四代", R.drawable.ic_num5)); listview.setAdapter(adapter); listview.setOnItemClickListener(new OnItemClickListener() { Fragment newContent=null; @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub switch (position) { case 0: newContent = new MyFragment0(); break; case 1: newContent = new MyFragment1(); break; case 2: newContent = new MyFragment2(); break; case 3: newContent = new MyFragment3(); break; } if (newContent != null) { //切换Fragment switchFragment(newContent); } } }); } protected void switchFragment(Fragment newContent) { // TODO Auto-generated method stub if (getActivity() == null) { return; } if (getActivity() instanceof MainActivity) { MainActivity fragChange = (MainActivity) getActivity(); fragChange.switchContent(newContent); } } private class SampleItem { public String tag; public int iconRes; public SampleItem(String tag, int iconRes) { this.tag = tag; this.iconRes = iconRes; } } public class SampleAdapter extends ArrayAdapter<SampleItem> { public SampleAdapter(Context context) { super(context, 0); } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.menu_item, null); } ImageView icon = (ImageView) convertView.findViewById(R.id.row_icon); icon.setImageResource(getItem(position).iconRes); TextView title = (TextView) convertView.findViewById(R.id.row_title); title.setText(getItem(position).tag); return convertView; } } }2> MainActivity.java对SlidingMenu进行相关属性配置:
package com.example.slidingdemo; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.CanvasTransformer; import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity; import android.graphics.Canvas; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.animation.Interpolator; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; public class MainActivity extends SlidingFragmentActivity { private SlidingMenu menu; private CanvasTransformer transfor; private Fragment mContent; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_content_frame); //设置标题 setTitle("客户端"); //设置是否能够使用ActionBar来滑动 setSlidingActionBarEnabled(true); //设置是否显示Home图标按钮 getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setIcon(R.drawable.ic_num1); //初始化滑动效果 initAnimation(); //初始化滑动菜单 initSlidingMenu(savedInstanceState); } /** * 初始化动画效果 */ private void initAnimation() { // TODO Auto-generated method stub transfor = new CanvasTransformer(){ @Override public void transformCanvas(Canvas canvas, float percentOpen) { //canvas画布类;percentOpen:滑动菜单栏打开时的百分比值 // TODO Auto-generated method stub //以为3种效果,任选一个进行测试 //1.实现滑动时缩放的效果,左边缩下淡去,右边切入屏幕 float scale = (float) (percentOpen*0.25 + 0.75); canvas.scale(scale, scale, canvas.getWidth()/2, canvas.getHeight()/2); //2.实现收缩效果 //canvas.scale(percentOpen, 1, 0, 0); //3.实现菜单栏从下往上滑动效果 // canvas.translate(0, canvas.getHeight() * (1 - interp.getInterpolation(percentOpen))); } }; } private static Interpolator interp = new Interpolator() { @Override public float getInterpolation(float t) { t -= 1.0f; return t * t * t + 1.0f; } }; /** * 初始化滑动菜单 */ private void initSlidingMenu(Bundle savedInstanceState) { // TODO Auto-generated method stub // 如果保存的状态不为空则得到之前保存的Fragment,否则实例化MyFragment if(savedInstanceState!=null){ mContent=getSupportFragmentManager().getFragment(savedInstanceState, "mContent"); } if(mContent==null){ mContent=new MyFragment0(); } //设置主界面视图 setContentView(R.layout.main_content_frame); getSupportFragmentManager().beginTransaction() .replace(R.id.content_frame, new MyFragment0()).commit(); // 设置滑动菜单的视图界面 setBehindContentView(R.layout.menu_frame); getSupportFragmentManager().beginTransaction() .replace(R.id.menu_frame, new MenuListFragment()).commit(); // 设置滑动菜单的属性值 menu=getSlidingMenu(); // 设置触摸屏幕的模式 menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); // 设置滑动阴影的宽度 menu.setShadowWidthRes(R.dimen.shadow_width); // 设置滑动阴影的图像资源 menu.setShadowDrawable(R.drawable.shadow); // 设置滑动菜单视图的宽度 menu.setBehindOffsetRes(R.dimen.slidingmenu_offset); // 设置渐入渐出效果的值 menu.setFadeDegree(0.45f); menu.setBehindScrollScale(0.0f); menu.setBehindCanvasTransformer(transfor); } /* * 保存Fragment的状态 */ @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); getSupportFragmentManager().putFragment(outState, "mContent", mContent); } @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; } @Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); if(menu.isMenuShowing()){ menu.showContent(); }else{ super.onBackPressed(); } } /* * 菜单按钮点击事件,通过点击ActionBar的Home图标按钮(顶部左边)来打开滑动菜单栏 */ @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub switch (item.getItemId()) { case android.R.id.home: toggle(); return true; } return super.onOptionsItemSelected(item); } /* * 切换视图 */ public void switchContent(Fragment newContent) { // TODO Auto-generated method stub mContent = newContent; getSupportFragmentManager().beginTransaction() .replace(R.id.content_frame, newContent).commit(); getSlidingMenu().showContent(); } }3> MyListView .java重写listview:
package com.example.slidingdemo; import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; /** * 重写ListView->实现Listview和ScrollView的滚动不冲突 */ public class MyListView extends ListView { public MyListView(Context context) { super(context); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }4> MyFragment0 .java是左侧菜单切换对应的内容界面: MyFragment1.java, MyFragment2.java, MyFragment3.java这三个一样,贴出一个代码,测试即可。
package com.example.slidingdemo; import android.content.Context; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; public class MyFragment0 extends ListFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.list, null); } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); SampleAdapter adapter = new SampleAdapter(getActivity()); for (int i = 0; i < 30; i++) { adapter.add(new SampleItem("内容 List 鸣人", R.drawable.ic_left)); } setListAdapter(adapter); } private class SampleItem { public String tag; public int iconRes; public SampleItem(String tag, int iconRes) { this.tag = tag; this.iconRes = iconRes; } } public class SampleAdapter extends ArrayAdapter<SampleItem> { public SampleAdapter(Context context) { super(context, 0); } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.content_item, null); } ImageView icon = (ImageView) convertView.findViewById(R.id.row_icon); icon.setImageResource(getItem(position).iconRes); TextView title = (TextView) convertView.findViewById(R.id.row_title); title.setText(getItem(position).tag); return convertView; } } }<span style="font-weight: bold;"> </span>6.SlidingMenu相关配置属性说明:
//设置侧边, 必须为 LEFT(左边),RIGHT(右边),LEFT_RIGHT(左右两边)三者之一 public void setMode(int mode)
//设置触摸方式,必须为 TOUCHMODE_FULLSCREEN(全屏可触摸),TOUCHMODE_MARGIN(边缘可触摸),默认 48dp, TOUCHMODE_NONE(不可触摸)三者之一
public void setTouchModeAbove(int i)
// 根据资源文件 ID 设置阴影部分的 width
public void setShadowWidthRes(int resId)
// 根据资源文件 ID 设置阴影部分的效果
public void setShadowDrawable(int resId)
// 根据资源文件 ID 设置第二个侧边栏阴影部分的效果
public void setSecondaryShadowDrawable(int resId)
// 根据资源文件 ID 设置主界面距离屏幕的偏移量
public void setBehindOffsetRes(int resID)
// 设置 fade in 和 fade out 效果的值
public void setFadeDegree(float f)
// 设置滑动比例的值,范围为 0-1 之间
public void setBehindScrollScale(float f)
// 根据资源文件 ID 设置侧边栏布局
public void setMenu(int res)
// 根据 View 设置侧边栏布局
public void setMenu(View v)
// 根据资源文件 ID 设置第二个侧边栏布局
public void setSecondaryMenu(int res)
// 根据 View 设置第二个侧边栏布局
public void setSecondaryMenu(View v)
// 打开菜单
public void showMenu()
// 打开第二个菜单
public void showSecondaryMenu()
// SlidingMenu 的开关
public void toggle()
// 检查侧边栏是否打开
public boolean isMenuShowing()
// 检查第二个侧边栏是否打开
public boolean isSecondaryMenuShowing()
源码下载