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 ...
随机推荐
- Windows Installer 服务启动错误 14007 的解决办法
问题: 在 本地计算机 无法启动 Windows Installer 服务. 错误代码 14007: 在活动的激活上下文中没有找到任何查找密钥. 这个问题似乎涉及到 Windows Installer ...
- Warm myself by my hand
周末的尾巴了. 前几天白日里的气温降到10摄氏度以下,穿上了秋裤.隔天跑一次步,晚上九点多,5公里,25分钟左右.换上薄薄的运动裤,两件运动衣.一出宿舍门就没觉得冷,跑着跑着就愈加热了起来.遇到的问题 ...
- 使用Node.js+Socket.IO搭建WebSocket实时应用
Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...
- PHP核心技术与最佳实践——全局浏览
难得买到并喜欢一本好书,‘PHP核心技术与最佳实践’. 几天时间,先看了个大概,总结一下整体是什么样子的,怎么看怎么学. 1.总共14章: 2.第1.2章讲PHP的OOP: 其中第一章侧重于PHP的O ...
- HDOJ 1326. Box of Bricks 纯水题
Box of Bricks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- S5PV210_uart stdio移植
1.stdio : standard input output 标准输入输出 2.printf函数调用到的2个关键函数: vsprintf : 格式化打印信息,最终得到纯字符串的打印信息等待输出 pu ...
- 由一个多线程共享Integer类变量问题引起的。。。
最近看到一个多线程面试题,有三个线程分别打印A.B.C,请用多线程编程实现,在屏幕上循环打印10次ABCABC- 看到这个题目,首先想到的是解决方法是定义一个Integer类对象,初始化为0,由3个线 ...
- Spring之BeanFactory及Bean生命周期
1.spring通过BeanFactory灵活配置.管理bean,Spring对管理的bean没有任何特别的要求,完全支持对POJO的管理: 2.BeanFactory有个ApplicationCon ...
- Webform:Application、ViewState对象的用法
Application Application对象的作用范围是整个全局,也就是说对所有用户都有效.它在整个应用程序生命周期中都是有效的,类似于使用全局变量一样,所以可以在不同页面中对它进行存取.它和S ...
- html5标签知多少
此文为前段时间团队研究会出品,与小伙伴兮兮圆一起研究的成果,意外地上了公司km的今日推荐,今日挪过来,为新开张的博客先暖暖场吧. 一.常用标签 <header>.<footer> ...