Android自定义控件简单实现侧滑菜单效果
作者:lmj623565791 发布时间:2023-10-30 16:56:57
侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑动时,通过Scroller或者不断的改变leftMargin等实现;多少都有点复杂,完成以后还需要对滑动冲突等进行处理~~今天给大家带来一个简单的实现,史上最简单有点夸张,但是的确是我目前遇到过的最简单的一种实现~~~
1、原理分析
既然是侧滑,无非就是在巴掌大的屏幕,塞入大概两巴掌大的布局,需要滑动可以出现另一个,既然这样,大家为啥不考虑使用Android提供的HorizontalScrollView呢~
如果使用HorizontalScrollView,还需要在ACTION_DOWN , ACTION_MOVE里面去监听,判断,不断改变控件位置了么? NO!!!HorizontalScrollView本身就带了滑动的功能~~
还需要自己的手动处理各种冲突么?NO!!!当然了,还是需要了解下事件分发机制的~~~
2、效果图
嗯,主界面搞了QQ一张图片,左边盗用了一兄弟的布局文件~~罪过~~ 谁有好看的布局、图片、图标神马的,可以给我发点,感激~
3、布局文件
<com.example.zhy_slidingmenu.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scrollbars="none" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<include layout="@layout/layout_menu" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/qq" >
</LinearLayout>
</LinearLayout>
</com.example.zhy_slidingmenu.SlidingMenu>
首先是我们的自定义View,里面一个方向水平的LinearLayout,然后就是一个是菜单的布局,一个是主布局了~
4、自定义SlidingMenu
接下来就是我们最核心的代码了~
package com.example.zhy_slidingmenu;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import com.zhy.utils.ScreenUtils;
public class SlidingMenu extends HorizontalScrollView
{
/**
* 屏幕宽度
*/
private int mScreenWidth;
/**
* dp
*/
private int mMenuRightPadding = 50;
/**
* 菜单的宽度
*/
private int mMenuWidth;
private int mHalfMenuWidth;
private boolean once;
public SlidingMenu(Context context, AttributeSet attrs)
{
super(context, attrs);
mScreenWidth = ScreenUtils.getScreenWidth(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
/**
* 显示的设置一个宽度
*/
if (!once)
{
LinearLayout wrapper = (LinearLayout) getChildAt(0);
ViewGroup menu = (ViewGroup) wrapper.getChildAt(0);
ViewGroup content = (ViewGroup) wrapper.getChildAt(1);
// dp to px
mMenuRightPadding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, mMenuRightPadding, content
.getResources().getDisplayMetrics());
mMenuWidth = mScreenWidth - mMenuRightPadding;
mHalfMenuWidth = mMenuWidth / 2;
menu.getLayoutParams().width = mMenuWidth;
content.getLayoutParams().width = mScreenWidth;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@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(mMenuWidth, 0);
once = true;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev)
{
int action = ev.getAction();
switch (action)
{
// Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();
if (scrollX > mHalfMenuWidth)
this.smoothScrollTo(mMenuWidth, 0);
else
this.smoothScrollTo(0, 0);
return true;
}
return super.onTouchEvent(ev);
}
}
哈哈,完工~上面的演示图,就用到这么点代码~~
代码怎么样,短不短~除了设置宽度这些杂七杂八的代码~正在处理滑动的代码不过10行~~我说史上最简单不为过吧~
嗯,由于代码过于短,就不解释了,大家自己看 * 释~
5、扩展
嗯,就下来,我们完善下程序,我准备首先把菜单布局里面改成ListView来证明我们是没有冲突的;然后添加一个属性让用户配置菜单距离右边的边距的值;再对外公布一个方法,点击自动打开菜单,供用户点击某个按钮,菜单慢慢滑出来~
1)、添加自定义属性
a、首先在values文件夹下新建一个attr.xml,写入以下内容:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="rightPadding" format="dimension" />
<declare-styleable name="SlidingMenu">
<attr name="rightPadding" />
</declare-styleable>
</resources>
b、在布局中声明命名空间和使用属性
定义完了,肯定要使用么。
<com.example.zhy_slidingmenu.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_slidingmenu"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scrollbars="none"
zhy:rightPadding="100dp" >
可以看到我们的命名空间:xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_slidingmenu" 是http://schemas.android.com/apk/res/加上我们的包名;
我们的属性:zhy:rightPadding="100dp"这里我设置了100dp;
注:很多人问我,没有提示咋办,这样,你clean下项目,如果你运气好,就有提示了,嗯,运气好~
c、在我们自定义类中获得属性
public SlidingMenu(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mScreenWidth = ScreenUtils.getScreenWidth(context);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.SlidingMenu, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.SlidingMenu_rightPadding:
// 默认50
mMenuRightPadding = a.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50f,
getResources().getDisplayMetrics()));// 默认为10DP
break;
}
}
a.recycle();
}
在三个参数的构造方法中,通过TypeArray获取就行了~
本文出自【张鸿洋的博客】
来源:http://blog.csdn.net/lmj623565791/article/details/39185641


猜你喜欢
- (1)自定义泛型链表类。public class GenericList<T> { 
- 今天给大家带来一个向右滑动销毁Activity的效果,Activtiy随着手指的移动而移动,该效果在Android应用中还是比较少见的,在I
- 前言Java 中的 synchronized关键字可以在多线程环境下用来作为线程安全的同步锁。本文不讨论 synchronized 的具体使
- Android 5.0 后用 Battery Historian 工具分析电量。耗电因素移动网络请求手机通过内置的射频模块和基站联系,从而链
- 首先,必须要强调的一点,MD5不是加密算法,而是消息摘要算法,具有不可逆性。字符串通过MD5处理后会生成128位的二进制串。我们通常会将其转
- 我们在k8s集群成功搭建了Prometheus服务。今天,我们将在springboot2.x中使用prometheus记录指标。一、我们需要
- 我公司最近升级程序经常报出更新失败问题,究其原因,原来是更新时,他们可能又打开了正在被更新的文件,导致更新文件时,文件被其它进程占用,无法正
- Android选择图片的两种方式:第一种:单张选取通过隐式启动activity,跳转到相册选择一张返回结果关键代码如下:发送请求:priva
- 读取文件流时,经常会遇到乱码的现象,造成乱码的原因当然不可能是一个,这里主要介绍因为文件编码格式而导致的乱码的问题。首先,明确一点,文本文件
- 如果发现maven项目里面src/main/resources下的配置文件或src/main/java下的xml配置文件未能同步至targe
- 霓虹是用来描绘图像的轮廓,勾画出颜色变化的边缘,加强其过度效果,使图像产生轮廓发光的效果。主要步骤:1、根据当前像素与其右方和下方像素的梯度
- 简介对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等。虽然我们可以用一个固定的组件来做为AppBa
- 前言最近新整了个博客网站,同事在gitee上找的,还不错,gitee上的地址在这里:拾壹博客管理系统。别人的业务,再好也有不满足自己的地方,
- 二进制、八进制和十六进制向十进制转换都是非常容易的,就是“按权相加”。所谓“权”,也即“位权”。例如,十进制第1位的位权为100=1,第2位
- 工具类-java精确到小数点后6位验证要求,必须精确到小数点后6位,但是后面都是0的话,double会省略0,正则验证不通过,所以有了下面解
- Java中对象与C++中对象的放置安排的对比概要:Java中,所有的对象都存放在堆(Heap,一种通用的内存池)中;而对象的引用是存放在堆栈
- 1、如何解决服务之间的通信问题?[1]HTTP REST方式 使用http协议进行数据传递 json格式数据[2]RPC方式 远程过程调用
- 目录1.前言2.不同进制的特点3.进制之间的转换3.1 二进制转十进制:3.2 十进制转二进制:3.3 二进制转八进制:3.4 十六进制转二
- 目前系统集成短信似乎是必不可少的部分,由于各种云平台都提供了不同的短信通道,这里我们增加多租户多通道的短信验证码,并增加配置项,使系统可以支
- java 中链表的定义与使用方法Java实现链表主要依靠引用传递,引用可以理解为地址,链表的遍历多使用递归,这里我存在一个疑问同一个类的不同