Android之自定义侧滑菜单
先来上图:
我们把主界面从左向右拉动,可以看到地下有一层菜单页,从透明渐渐变得不透明,从小渐渐变大,感觉上觉得菜单页是从屏幕外面被拉到屏幕中的。下面的代码实现这个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之自定义侧滑菜单的更多相关文章
- Android 自定义View修炼-打造完美的自定义侧滑菜单/侧滑View控件
一.概述 在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上 咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点: ...
- Android 高大上的侧滑菜单DrawerLayout,解决了不能全屏滑动的问题
DrawerLayout预览 DrawerLayout主要功能就是 实现侧滑菜单效果的功能,并且可以通过增加一些设置来实现高大上的效果,那么就请看动态图: 注意左上角那个图标,有木有很好玩,哈哈. ...
- vue2.X 自定义 侧滑菜单 组件
1.vue2.0 封装 侧滑菜单组件 Sidebar.vue <!-- 侧滑菜单 组件 --> <template> <div> <transition na ...
- android 实现自定义卫星菜单
看了hyman老师的视频,听起来有点迷糊,所以就想把实现卫星菜单的实现总结一下.长话短说,下面总结一下: 一.自定义ViewGroup1).自定义属性文件 属性的定义: <attr name=& ...
- android的左右侧滑菜单实现
最近看了很多app应用都采用的是左右侧滑,比如网易新闻.凡客等 这里也试着写一下侧滑 首先看一下效果 然后给出xml布局代码 <RelativeLayout xmlns:android=&quo ...
- android文章学习 侧滑菜单实现
http://blog.csdn.net/jj120522/article/details/8075249 http://blog.csdn.net/lilybaobei/article/detail ...
- Android 自定义View修炼-仿QQ5.0 的侧滑菜单效果的实现
有一段时间没有写博客了,最近比较忙,没什么时间写,刚好今天有点时间, 我就分享下,侧滑菜单的实现原理,一般android侧滑的实现原理和步骤如下:(源码下载在下面最后给出哈) 1.使用ViewGrou ...
- Android带侧滑菜单和ToolBar的BaseActivity
写Android的时候,可能有多个界面.在风格统一的软件中,写Activity时会有很多重复.例如我所在软工课程小组的项目:Github链接 ,里面的TaskListActivity和TeacherL ...
- Android-自定义侧滑菜单
效果图: 需要继承ViewGroup,因为包含了子控件,菜单子控件 与 主页面子控件 Activity Xml布局相关: <!-- 自定义侧滑菜单 SlideMenu --> <Li ...
随机推荐
- 15天玩转redis —— 第九篇 发布/订阅模式
本系列已经过半了,这一篇我们来看看redis好玩的发布订阅模式,其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果 ...
- python列表模拟堆栈和队列
对列特点:先进先出.后进后出 用列表insert.pop模拟进队出队: >>> l = [] >>> l.insert(0,'p1') >>> l ...
- 压缩和解压文件:tar gzip bzip2 compress(转)
tar[必要参数][选择参数][文件] 压缩:tar -czvf filename.tar.gz targetfile解压:tar -zxvf filename.tar.gz参数说明: -c 建立新的 ...
- nginx+php-fpm+mysql分离部署详解
相信大家将这三者部署到同一台主机应该已经不陌生了,今天在这里,给大家演示一下如何将三者部署到三台主机上. 实验系统:CentOS 6.6_x86_64 实验前提:大部分软件使用编译安装,请提前准备好编 ...
- Ubuntu 14.04 LTS 下升级 gcc 到 gcc-4.9、gcc-5 版本
如果没记错的话,阿里云ECS上的Ubuntu也是LTS版本. 如果还在使用较旧版本的Ubuntu,或者是Ubuntu LTS,那么我们是很难体验新版gcc的.怎么办呢? 我们或许可以自己去编译用旧版本 ...
- codeforces 597C C. Subsequences(dp+树状数组)
题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...
- java多线程系类:JUC线程池:06之Callable和Future(转)
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- [LeetCode] Strobogrammatic Number II 对称数之二
A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...
- WPF实现三星手机充电界面
GitHub地址:https://github.com/ptddqr/wpf-samsung-phone-s5-charging-ui/tree/master 先上效果图 这个效果来自于三星S5的充电 ...
- 常用DOS命令
1.查询端口占用情况:netstat -aon |findstr "8080"; 查看端口进程号: 2.查看进程号信息: tasklist |findstr "999 ...