这篇文章会给大家带来7个不同效果的示例,每个示例都包含了最基本的使用方法,从易到难,循序渐进。能够
让初学者可以快速的掌握SlidingMenu的使用方法。下一篇文章会给大家带来三种不同的动画效果来实现滑动菜单栏
的滑动。
关于这些示例,都是SlidingMenu开源项目中自带的一些示例,但是对于初学者来说,要想运行这些示例查看效
果,就必须要导入很多的库,使用起来也是非常的麻烦。博主这里为了能够方便大家更好的学习,就把每个示例都单
独拿了出来,并且添加了一些非常详细的注释,让初学者能够一看就懂,那么博主的目的就达到了。
好的,话不多说,希望大家能够继续支持!
一、示例效果图
先上效果图是博主一贯的作风,这样做可以让大家对于效果的实现有一个大概的了解,可以从中得到自己想要去
实现的效果。
1、示例一效果图
该示例主要是演示通过改变不同的值来改变滑动菜单不同的效果,可以设置的值有:
<1> 设置滑动菜单显示的位置(左边、右边或者左右两边都有);
<2> 设置触摸屏幕的模式(全屏触摸打开滑动菜单、边缘触摸打开滑动菜单或者触摸不能打开滑动菜单);
<3> 设置滑动菜单滑动时缩放的效果以及关闭此效果(值越大效果越明显);
<4> 设置滑动菜单滑动时的阴影效果以及关闭此效果(值越大效果越明显);
<5> 设置滑动菜单滑动时渐入渐出的效果(值越大效果越明显)。
效果图一 效果图二
上面代码包括全部SlidingMenu的情况:
MainActivity.java 代码:
package com.yangyu.myslidingmenudemo01; import android.os.Bundle; import android.view.MenuItem; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity; public class MainActivity extends SlidingFragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置标题栏的标题 setTitle("SlidingMenu Properties"); //设置是否能够使用ActionBar来滑动 setSlidingActionBarEnabled(true); //设置是否显示Home图标按钮 getActionBar().setDisplayHomeAsUpEnabled(true); //设置主界面视图 setContentView(R.layout.properties); //初始化滑动菜单 initSlidingMenu(savedInstanceState); //初始化组件 initView(); } /** * 初始化滑动菜单 */ private void initSlidingMenu(Bundle savedInstanceState) { // 设置滑动菜单的视图 setBehindContentView(R.layout.menu_frame); getSupportFragmentManager().beginTransaction().replace(R.id.menu_frame, new SampleListFragment()).commit(); // 实例化滑动菜单对象 SlidingMenu sm = getSlidingMenu(); // 设置滑动阴影的宽度 sm.setShadowWidthRes(R.dimen.shadow_width); // 设置滑动阴影的图像资源 sm.setShadowDrawable(R.drawable.shadow); // 设置滑动菜单视图的宽度 sm.setBehindOffsetRes(R.dimen.slidingmenu_offset); // 设置渐入渐出效果的值 sm.setFadeDegree(0.35f); // 设置触摸屏幕的模式 sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); } /** * 初始化组件 */ private void initView() { // 设置滑动菜单的位置(左边、右边或者左右两边都有) RadioGroup mode = (RadioGroup) findViewById(R.id.mode); mode.check(R.id.left); mode.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { SlidingMenu sm = getSlidingMenu(); switch (checkedId) { case R.id.left: sm.setMode(SlidingMenu.LEFT); sm.setShadowDrawable(R.drawable.shadow); break; case R.id.right: sm.setMode(SlidingMenu.RIGHT); sm.setShadowDrawable(R.drawable.shadowright); break; case R.id.left_right: sm.setMode(SlidingMenu.LEFT_RIGHT); sm.setSecondaryMenu(R.layout.menu_frame_two); getSupportFragmentManager().beginTransaction() .replace(R.id.menu_frame_two, new SampleListFragment()).commit(); sm.setSecondaryShadowDrawable(R.drawable.shadowright); sm.setShadowDrawable(R.drawable.shadow); } } }); // 设置触摸的模式(全屏触摸滑动、边缘触摸滑动或者触摸不能滑动) RadioGroup touchAbove = (RadioGroup) findViewById(R.id.touch_above); touchAbove.check(R.id.touch_above_full); touchAbove.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.touch_above_full: getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); break; case R.id.touch_above_margin: getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN); break; case R.id.touch_above_none: getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE); break; } } }); // 设置滑动菜单滑动时缩放的效果(值越大效果越明显) SeekBar scrollScale = (SeekBar) findViewById(R.id.scroll_scale); scrollScale.setMax(1000); scrollScale.setProgress(333); scrollScale.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { getSlidingMenu().setBehindScrollScale((float) seekBar.getProgress() / seekBar.getMax()); } }); // 设置滑动菜单时下方视图的宽度(值越大宽度越大) SeekBar behindWidth = (SeekBar) findViewById(R.id.behind_width); behindWidth.setMax(1000); behindWidth.setProgress(750); behindWidth.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { float percent = (float) seekBar.getProgress() / seekBar.getMax(); getSlidingMenu().setBehindWidth((int) (percent * getSlidingMenu().getWidth())); getSlidingMenu().requestLayout(); } }); // 设置滑动菜单滑动时的阴影效果(值越大效果越明显) CheckBox shadowEnabled = (CheckBox) findViewById(R.id.shadow_enabled); shadowEnabled.setChecked(true); shadowEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) getSlidingMenu().setShadowDrawable(getSlidingMenu().getMode() == SlidingMenu.LEFT ? R.drawable.shadow: R.drawable.shadowright); else getSlidingMenu().setShadowDrawable(null); } }); SeekBar shadowWidth = (SeekBar) findViewById(R.id.shadow_width); shadowWidth.setMax(1000); shadowWidth.setProgress(75); shadowWidth.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { float percent = (float) seekBar.getProgress() / (float) seekBar.getMax(); int width = (int) (percent * (float) getSlidingMenu().getWidth()); getSlidingMenu().setShadowWidth(width); getSlidingMenu().invalidate(); } }); // 设置滑动菜单滑动时渐入渐出的效果(值越大效果越明显) CheckBox fadeEnabled = (CheckBox) findViewById(R.id.fade_enabled); fadeEnabled.setChecked(true); fadeEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { getSlidingMenu().setFadeEnabled(isChecked); } }); SeekBar fadeDeg = (SeekBar) findViewById(R.id.fade_degree); fadeDeg.setMax(1000); fadeDeg.setProgress(666); fadeDeg.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { getSlidingMenu().setFadeDegree( (float) seekBar.getProgress() / seekBar.getMax()); } }); } /** * 菜单按钮点击事件,通过点击ActionBar的Home图标按钮来打开滑动菜单 */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: toggle(); return true; } return super.onOptionsItemSelected(item); } }
SampleListFragment.java 用于显示
功能描述:列表Fragment,用来显示滑动菜单打开后的内容
package com.yangyu.myslidingmenudemo01; 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; /** * @author zjn * 功能描述:列表Fragment,用来显示滑动菜单打开后的内容 */ public class SampleListFragment extends ListFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.list, null); } public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); SampleAdapter adapter = new SampleAdapter(getActivity()); for (int i = 0; i < 20; i++) { adapter.add(new SampleItem("Sample List", android.R.drawable.ic_menu_search)); } setListAdapter(adapter); } 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.row, 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; } } private class SampleItem { public String tag; public int iconRes; public SampleItem(String tag, int iconRes) { this.tag = tag; this.iconRes = iconRes; } } }
2、示例二效果图
该示例主要就是教大家实现一个简单的放置在左边滑动菜单栏的效果。
效果图一
3、示例三效果图
该示例实现了在左右两边存放两个视图,并且都可以通滑动屏幕来打开。
4、示例四效果图
该示例主要演示了通过Fragment来改变主视图的界面内容。
5、示例五效果图
该示例也是通过Fragment来改变主视图的界面内容,但不同的是列表中存放的是图片,并且点击列表图片之后会
经过压缩显示出来。
6、示例六效果图
在该示例中使用ViewPager这个类,将多个Fragment存放在viewpager中,并在主界面视图内容中显示出来。
效果图一 效果图二
7、示例七效果图
该示例主要演示了当触摸屏幕滑动时,上面的标题栏TitleBar并不会跟随着一起滑动,滑动的只是中间的内容视图。(印象笔记实现了此效果)
二、代码讲解
由于示例比较多,所以博主我就不对每个示例的代码一一进行讲解了,这里就挑一个最基础的示例给大家讲解一
下。在文章的末尾,我会把所有的示例打包供大家下载学习,里面有一些详细的注释,相信大家能一看就懂。
1、项目结构图
2、content_frame.xml布局
我们先从布局文件开始讲起,这里为什么要定义一个content_frame.xml呢?主要是为了定义一个虚拟的视图,方便Fragment能够替换该视图,以达到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布局,在给它附上一个id,以至于在系统中可以找到该布局对象。
3、menu_frame.xml布局
这个布局文件是用来存放滑动菜单打开后的视图界面的。
<?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" />
4、list.xml
这个list布局文件会在ListFragment中用到。
<?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" android:paddingLeft="@dimen/list_padding" android:paddingRight="@dimen/list_padding" />
5、row.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="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 Text" android:textAppearance="@android:style/TextAppearance.Medium" /> </LinearLayout>
6、shadow.xml资源
这个资源文件是用来实现阴影效果的图形,使用了渐变的绘图效果。
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <gradient android:endColor="#33000000" android:centerColor="#11000000" android:startColor="#00000000" /> </shape>
7、SampleListFragment类
讲完了布局文件,再让我们来看看Java文件。这个类是用来显示界面中的列表的。
package com.yangyu.myslidingmenudemo02; 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; /** * @author yangyu * 功能描述:列表Fragment,用来显示滑动菜单打开后的内容 */ public class SampleListFragment extends ListFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.list, null); } public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); SampleAdapter adapter = new SampleAdapter(getActivity()); for (int i = 0; i < 20; i++) { adapter.add(new SampleItem("Sample List", android.R.drawable.ic_menu_search)); } 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.row, 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; } } }
8、MainActivity类
这是整个程序的入口类,也是在这个类中,对SlidingMenu的属性进行设置。
package com.yangyu.myslidingmenudemo02; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; public class MainActivity extends FragmentActivity { private SlidingMenu menu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置标题 setTitle("Attach"); //初始化滑动菜单 initSlidingMenu(); } /** * 初始化滑动菜单 */ private void initSlidingMenu() { // 设置主界面视图 setContentView(R.layout.content_frame); getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new SampleListFragment()).commit(); // 设置滑动菜单的属性值 menu = new SlidingMenu(this); 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.35f); menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); // 设置滑动菜单的视图界面 menu.setMenu(R.layout.menu_frame); getSupportFragmentManager().beginTransaction().replace(R.id.menu_frame, new SampleListFragment()).commit(); } @Override public void onBackPressed() { //点击返回键关闭滑动菜单 if (menu.isMenuShowing()) { menu.showContent(); } else { super.onBackPressed(); } } }
讲到这里差不多就要结束了,下一篇会给大家带来打开滑动菜单时实现的动画效果,希望大家能够继续关注!
压缩包中包含所有的项目示例:
每个项目中包含了源码、实现的效果图以及可直接安装运行的APK:
特别注意:大家运行项目的时候千万别忘了导入slidingmenu_library项目,使用方法请参照上一篇文章。