先来上图:

我们把主界面从左向右拉动,可以看到地下有一层菜单页,从透明渐渐变得不透明,从小渐渐变大,感觉上觉得菜单页是从屏幕外面被拉到屏幕中的。下面的代码实现这个DEMO:

首先是自定义控件SlidingMenu控件的代码

 public class SlidingMenu extends HorizontalScrollView {
// 自定义View的步骤:
// 1、onMeasure():决定子View的宽和高和自己的宽和高
// 2、onLayout():决定子View放置的位置
// 3、onTouchEvent:判断用户手指的滑动状态
// 自定义属性的步骤:
// 1、书写XML文件(values/attrs.xml)
// 2、在布局文件中进行使用,注意xmlns命名空间
// 3、在三个参数的构造方法中获得我们设置的值 private LinearLayout wrapper; // 总容器
private ViewGroup menu, content; // 菜单页,内容页
private int screenWidth; // 屏幕的宽度
private int menuWidth; // menu的宽度
private int menuRightPadding = 50; // menu菜单距离屏幕右侧的距离(单位是DIP)
private boolean once; // onMeasure()方法是不是第一次调用
private boolean isOpen; // 侧滑菜单是否是开启状态 // 在界面上通过上下文直接生成控件时,调用这个构造方法
public SlidingMenu(Context context) {
this(context, null);
} // 当没有使用自定义属性时,调用这个构造方法
public SlidingMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} // 当使用了自定义属性(values/attrs.xml)时,调用这个构造方法
public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 获取我们自定义的属性
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu, defStyleAttr, 0);
for (int i = 0; i < a.getIndexCount(); i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.SlidingMenu_rightPadding:
// getDimensionPixelSize:为attr下标的属性设置默认值(第二个参数)
menuRightPadding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
50, context.getResources().getDisplayMetrics()));
break;
}
}
a.recycle(); // 获取屏幕的宽度
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!once) {
wrapper = (LinearLayout) getChildAt(0);
menu = (ViewGroup) wrapper.getChildAt(0);
content = (ViewGroup) wrapper.getChildAt(1);
// 设置菜单和主页的宽度
menuWidth = menu.getLayoutParams().width = screenWidth - menuRightPadding;
content.getLayoutParams().width = screenWidth; once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} // 通过设置偏移量,将Menu隐藏
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
this.scrollTo(menuWidth, 0);
}
} @Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX(); // 隐藏在左边的宽度
if (scrollX >= menuWidth / 2) {
this.smoothScrollTo(menuWidth, 0);
isOpen = false;
} else {
this.smoothScrollTo(0, 0);
isOpen = true;
}
return true;
}
return super.onTouchEvent(ev);
} // 打开菜单
public void openMenu() {
if (isOpen)
return;
this.smoothScrollTo(0, 0);
isOpen = false;
} // 关闭菜单
public void closeMenu() {
if (!isOpen)
return;
this.smoothScrollTo(menuWidth, 0);
isOpen = true;
} // 管理菜单的状态和动作(如果菜单是关闭的就打开它,如果是打开的就关闭它)
public void toggle() {
if (isOpen) {
closeMenu();
} else {
openMenu();
}
} // 抽屉式侧滑(这个方法监听滚动的全过程)
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
float scale = l * 1.0f / menuWidth;
// 实现仿QQ5.0的侧滑界面:在滑动时,滑动朝向的ViewGroup不断缩小,另一个ViewGroup不断放大
float rightScrollScale = 0.85f + 0.15f * scale; // 主界面的滑动缩放比例
float leftScrollScale = 1.0f - 0.4f * scale; // 菜单的滑动缩放比例
float leftAlphaScale = 0.6f + 0.4f * (1 - scale); // 菜单透明度的变化比例
// 调用属性动画(Android3.0时引入),设置TranslationX(这里需要引入nineoldandroids.jar包)
ViewHelper.setTranslationX(menu, menuWidth * scale * 0.75f);
// 设置Menu的缩放和透明度
ViewHelper.setScaleX(menu, leftScrollScale);
ViewHelper.setScaleY(menu, leftScrollScale);
ViewHelper.setAlpha(menu, leftAlphaScale);
// 设置Content的缩放
ViewHelper.setPivotX(content, 0);
ViewHelper.setPivotY(content, content.getHeight() / 2);
ViewHelper.setScaleX(content, rightScrollScale);
ViewHelper.setScaleY(content, rightScrollScale);
}
}

下面是主界面布局的代码

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:xgz="http://schemas.android.com/apk/res/com.activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/menu_bg" > <com.view.SlidingMenu
android:id="@+id/main_slidingmenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
xgz:rightPadding="75.0dip" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" > <include layout="@layout/sideworks_menu" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/main_bg" > <Button
android:id="@+id/main_togglebtn"
android:layout_width="wrap_content"
android:layout_height="30.0dip"
android:layout_marginLeft="10.0dip"
android:layout_marginTop="10.0dip"
android:background="#00000000"
android:text="@string/main_toggle_btn"
android:textColor="#ffffff"
android:textSize="16.0sp" />
</LinearLayout>
</LinearLayout>
</com.view.SlidingMenu> </RelativeLayout>

下面是主界面中引用的菜单页的布局代码

 <?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:background="#00000000"
android:gravity="center_vertical"
android:orientation="vertical" > <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" > <ImageView
android:id="@+id/menu_icon1"
android:layout_width="40.0dip"
android:layout_height="40.0dip"
android:layout_marginLeft="10.0dip"
android:contentDescription="@string/app_name"
android:src="@drawable/img_1" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/menu_icon1"
android:text="@string/menu_icon1_text"
android:textColor="#ffffff"
android:textSize="15.0sp" />
</RelativeLayout> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15.0dip" > <ImageView
android:id="@+id/menu_icon2"
android:layout_width="40.0dip"
android:layout_height="40.0dip"
android:layout_marginLeft="10.0dip"
android:contentDescription="@string/app_name"
android:src="@drawable/img_2" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/menu_icon2"
android:text="@string/menu_icon2_text"
android:textColor="#ffffff"
android:textSize="15.0sp" />
</RelativeLayout> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15.0dip" > <ImageView
android:id="@+id/menu_icon3"
android:layout_width="40.0dip"
android:layout_height="40.0dip"
android:layout_marginLeft="10.0dip"
android:contentDescription="@string/app_name"
android:src="@drawable/img_3" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/menu_icon3"
android:text="@string/menu_icon3_text"
android:textColor="#ffffff"
android:textSize="15.0sp" />
</RelativeLayout> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15.0dip" > <ImageView
android:id="@+id/menu_icon4"
android:layout_width="40.0dip"
android:layout_height="40.0dip"
android:layout_marginLeft="10.0dip"
android:contentDescription="@string/app_name"
android:src="@drawable/img_4" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/menu_icon4"
android:text="@string/menu_icon4_text"
android:textColor="#ffffff"
android:textSize="15.0sp" />
</RelativeLayout> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15.0dip" > <ImageView
android:id="@+id/menu_icon5"
android:layout_width="40.0dip"
android:layout_height="40.0dip"
android:layout_marginLeft="10.0dip"
android:contentDescription="@string/app_name"
android:src="@drawable/img_5" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/menu_icon5"
android:text="@string/menu_icon5_text"
android:textColor="#ffffff"
android:textSize="15.0sp" />
</RelativeLayout> </LinearLayout>

下面是自定义属性attrs.xml文件中的代码

 <?xml version="1.0" encoding="utf-8"?>
<resources> <!-- 自定义属性:菜单离屏幕右侧的间距 -->
<attr name="rightPadding" format="dimension"></attr> <declare-styleable name="SlidingMenu">
<attr name="rightPadding"></attr>
</declare-styleable> </resources>

下面是主界面MainActivity.java中的代码

 public class MainActivity extends Activity {
private SlidingMenu slidingMenu;
private Button toggleBtn; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
slidingMenu = (SlidingMenu) findViewById(R.id.main_slidingmenu);
toggleBtn = (Button) findViewById(R.id.main_togglebtn); toggleBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
slidingMenu.toggle();
}
});
}
}

Android之自定义侧滑菜单的更多相关文章

  1. Android 自定义View修炼-打造完美的自定义侧滑菜单/侧滑View控件

    一.概述 在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上 咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点: ...

  2. Android 高大上的侧滑菜单DrawerLayout,解决了不能全屏滑动的问题

    DrawerLayout预览 DrawerLayout主要功能就是 实现侧滑菜单效果的功能,并且可以通过增加一些设置来实现高大上的效果,那么就请看动态图:   注意左上角那个图标,有木有很好玩,哈哈. ...

  3. vue2.X 自定义 侧滑菜单 组件

    1.vue2.0 封装 侧滑菜单组件 Sidebar.vue <!-- 侧滑菜单 组件 --> <template> <div> <transition na ...

  4. android 实现自定义卫星菜单

    看了hyman老师的视频,听起来有点迷糊,所以就想把实现卫星菜单的实现总结一下.长话短说,下面总结一下: 一.自定义ViewGroup1).自定义属性文件 属性的定义: <attr name=& ...

  5. android的左右侧滑菜单实现

    最近看了很多app应用都采用的是左右侧滑,比如网易新闻.凡客等 这里也试着写一下侧滑 首先看一下效果 然后给出xml布局代码 <RelativeLayout xmlns:android=&quo ...

  6. android文章学习 侧滑菜单实现

    http://blog.csdn.net/jj120522/article/details/8075249 http://blog.csdn.net/lilybaobei/article/detail ...

  7. Android 自定义View修炼-仿QQ5.0 的侧滑菜单效果的实现

    有一段时间没有写博客了,最近比较忙,没什么时间写,刚好今天有点时间, 我就分享下,侧滑菜单的实现原理,一般android侧滑的实现原理和步骤如下:(源码下载在下面最后给出哈) 1.使用ViewGrou ...

  8. Android带侧滑菜单和ToolBar的BaseActivity

    写Android的时候,可能有多个界面.在风格统一的软件中,写Activity时会有很多重复.例如我所在软工课程小组的项目:Github链接 ,里面的TaskListActivity和TeacherL ...

  9. Android-自定义侧滑菜单

    效果图: 需要继承ViewGroup,因为包含了子控件,菜单子控件 与 主页面子控件 Activity Xml布局相关: <!-- 自定义侧滑菜单 SlideMenu --> <Li ...

随机推荐

  1. 记录 git 常用的操作命令总结

    记录 git 常用的操作命令总结 2016-12-15 16:44:04 作为一名开发者,熟悉使用 git 代码管理工具是一项必备的基本技能.git 相较 SVN 而言,其优点不言而喻.git 的功能 ...

  2. socket Bio demo

    最近在做socket通信,最开始是基于Bio开发(其实开发的时候也不知道这种是基于BIO).但是问题来了,客户端发的报文,服务端接收会少,为了解决问题,只能恶补一下相关知识. 服务端: import ...

  3. 【IScroll深入学习】解决IScroll疑难杂症

    前言 在去年,我们对IScroll的源码进行了学习,并且分离出了一段代码自己使用,在使用学习过程中发现几个致命问题: ① 光标移位 ② 文本框找不到(先让文本框获取焦点,再滑动一下,输入文字便可重现) ...

  4. C++基本数据类型总结

    一.整形 1.整形有char.short.int.long.long long,这5个也默认为signed XX ; 规则:short至少16位:int至少和short一样:long至少32位,且至少 ...

  5. 解读ASP.NET 5 & MVC6系列(9):日志框架

    框架介绍 在之前的.NET中,微软还没有提供过像样的日志框架,目前能用的一些框架比如Log4Net.NLog.CommonLogging使用起来多多少少都有些费劲,和java的SLF4J根本无法相比. ...

  6. [LeetCode] Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  7. WPF实现三星手机充电界面

    GitHub地址:https://github.com/ptddqr/wpf-samsung-phone-s5-charging-ui/tree/master 先上效果图 这个效果来自于三星S5的充电 ...

  8. CSS优先级

    一.CSS代码出现的几个位置 多重样式(Multiple Styles):如果外部样式.内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况. 一般情况下,优先级如下:(外部样式)Extern ...

  9. bzoj3223

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3700  Solved: 2097[Submit][Sta ...

  10. java中静态方法和静态类的学习

    静态内部类可以有静态成员,而非静态类 则不能有静态成员 静态内部类的非静态成员可以访问外部类的静态成员,而不可以访问外部类的非静态成员 非静态方法与对象相关,而静态方法属于类的方法, 总上所述:静态方 ...