android中仿qq最新版抽屉,Android实现3种侧滑效果(仿qq侧滑、抽屉侧滑、普通侧滑)...

本文详细介绍了如何在Android中实现三种不同的侧滑菜单效果:普通侧滑、抽屉侧滑以及QQ5.0风格的侧滑。通过自定义HorizontalScrollView,结合属性动画,实现了菜单的平滑滑动和内容视图的动态缩放。示例代码包括关键布局、自定义视图类以及触摸事件处理,帮助开发者理解和实现侧滑菜单功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己实现了一下侧滑的三种方式(注释都写代码里了)

本文Demo下载地址:Andriod侧滑

本文实现所需框架:nineoldandroids下载地址:nineoldandroids

1.普通侧滑:

主要是基于HorizontalScrollView做的:示例代码如下

主要布局:

xmlns:gaoyu="http://schemas.android.com/apk/res/gaoyu.com.myapplication"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/activity_qqsideslip"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="gaoyu.com.myapplication.sideslip.QQSideslipActivity">

android:id="@+id/SlMenu_sideslip"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

gaoyu:rightPadding="100dp">

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:orientation="horizontal">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/sliding">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="onClick_sideslip_qq"

android:text="切换菜单" />

菜单的布局

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:layout_centerInParent="true">

android:layout_width="fill_parent"

android:layout_height="wrap_content">

android:id="@+id/iv_sideslip1"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_marginTop="20dp"

android:layout_marginBottom="20dp"

android:layout_marginLeft="20dp"

android:src="@drawable/icon"/>

android:layout_centerVertical="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toRightOf="@+id/iv_sideslip1"

android:layout_marginLeft="20dp"

android:text="第一个item"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content">

android:id="@+id/iv_sideslip2"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_marginTop="20dp"

android:layout_marginBottom="20dp"

android:layout_marginLeft="20dp"

android:src="@drawable/icon"/>

android:layout_centerVertical="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toRightOf="@+id/iv_sideslip2"

android:layout_marginLeft="20dp"

android:text="第二个item"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content">

android:id="@+id/iv_sideslip3"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_marginTop="20dp"

android:layout_marginBottom="20dp"

android:layout_marginLeft="20dp"

android:src="@drawable/icon"/>

android:layout_centerVertical="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toRightOf="@+id/iv_sideslip3"

android:layout_marginLeft="20dp"

android:text="第三个item"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content">

android:id="@+id/iv_sideslip4"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_marginTop="20dp"

android:layout_marginBottom="20dp"

android:layout_marginLeft="20dp"

android:src="@drawable/icon"/>

android:layout_centerVertical="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toRightOf="@+id/iv_sideslip4"

android:layout_marginLeft="20dp"

android:text="第四个item"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content">

android:id="@+id/iv_sideslip5"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_marginTop="20dp"

android:layout_marginBottom="20dp"

android:layout_marginLeft="20dp"

android:src="@drawable/icon"/>

android:layout_centerVertical="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toRightOf="@+id/iv_sideslip5"

android:layout_marginLeft="20dp"

android:text="第五个item"/>

定义view类

public class SlidingMenu_qq extends HorizontalScrollView {

private LinearLayout mWapper;

private ViewGroup mMenu;

private ViewGroup mContent;

//menu的宽度

private int mMenuWidth;

//屏幕的宽度(内容区的宽度就是屏幕宽度)

private int mScreenWdith;

//菜单与右边的距离50dp

private int mMenuRightPidding = 50;

//调用一次

private boolean once;

//标识状态

private boolean isOPen;

/**

* 未使用自定义属性时调用

* 由于设置了attr所以...

*

* @param context

* @param attrs

*/

public SlidingMenu_qq(Context context, AttributeSet attrs) {

//调用三个参数的构造方法

this(context, attrs, 0);

//获取屏幕宽度(窗口管理器)

/*WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

//展示度量

DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

mScreenWdith = outMetrics.widthPixels;

//把dp转换成px

mMenuRightPidding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics());

*/

}

/**

* 当实现自定义属性时会执行三个参数的方法

*

* @param context

* @param attrs

* @param defStyleAttr

*/

public SlidingMenu_qq(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

//获取自定义的属性

TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu_qq, defStyleAttr, 0);

//自定义属性个数

int n = a.getIndexCount();

for (int i = 0; i < n; i++) {

int attr = a.getIndex(i);

switch (attr) {

case R.styleable.SlidingMenu_qq_rightPadding:

//设置默认值是50dp

mMenuRightPidding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics()));

break;

}

}

//释放一下

a.recycle();

//获取屏幕宽度(窗口管理器)

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

//展示度量

DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

mScreenWdith = outMetrics.widthPixels;

}

/**

* new 一个TextView时传一个上下文

*

* @param context

*/

public SlidingMenu_qq(Context context) {

//调用两个参数的构造方法

super(context, null);

}

/**

* 设置HorizontalScrollView子VIew的宽和高

* 设置HorizontalScrollView自己的宽和高

*

* @param widthMeasureSpec

* @param heightMeasureSpec

*/

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

//设置循环之调用一次

if (!once) {

//HorizontalScrollView 内部只能有一个元素 所以直接get(0)就行就是那个Linerlayout mWapper

mWapper = (LinearLayout) getChildAt(0);

//获取mWapper里的第一个元素menu

mMenu = (ViewGroup) mWapper.getChildAt(0);

//获取mWapper里的第二个元素content

mContent = (ViewGroup) mWapper.getChildAt(1);

//菜单和内容宽度

mMenuWidth = mMenu.getLayoutParams().width = mScreenWdith - mMenuRightPidding;

mContent.getLayoutParams().width = mScreenWdith;

//由于子对象被设置了,mWapper就先不用了

once = true;

}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

/**

* 通过设置偏移量 将menu隐藏

* @param changed

* @param l

* @param t

* @param r

* @param b

*/

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

//限制多次调用

if (changed) {

//x为正滚动条向右 内容向左(移动mMenuWidth 正好将菜单隐藏)

this.scrollTo(mMenuWidth, 0);

}

}

/**

* 判断将菜单滑出来多少了

*

* @param ev

* @return

*/

@Override

public boolean onTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_UP:

//隐藏在左边的宽度

int scrollX = getScrollX();

if (scrollX >= mMenuWidth / 2) {

//scrollTo也行但是动画效果不好 (隐藏)

this.smoothScrollTo(mMenuWidth, 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 = true;

}

/**

* 关闭菜单

*/

public void closeMenu() {

//正在打开

if (!isOPen) return;

this.smoothScrollTo(mMenuWidth, 0);

isOPen = false;

}

/**

* 切换菜单

*/

public void toggle(){

if (isOPen){

closeMenu();

}else {

openMenu();

}

}

}

2.抽屉侧滑(添加此方法)

/**

* 实现抽屉滑动

* l隐藏在左边的宽度

* 后边是变化梯度

*/

@Override

protected void onScrollChanged(int l, int t, int oldl, int oldt) {

super.onScrollChanged(l, t, oldl, oldt);

float scale = l*1.0f/mMenuWidth;//1~0梯度的值

//调用属性动画

ViewHelper.setTranslationX(mMenu,mMenuWidth*scale);

}

3.qq5.0侧滑,实现这个方法

/**

* 实现仿qq5.0

* l等于隐藏在左边的宽度(越来越小)

* 后边是变化梯度

*/

@Override

protected void onScrollChanged(int l, int t, int oldl, int oldt) {

super.onScrollChanged(l, t, oldl, oldt);

float scale = l * 1.0f / mMenuWidth;//1~0梯度的值

//调用属性动画

//菜单的缩放操作

float leftScale = 1.0f-scale*0.3f;

//透明度

float leftAlpha = 0.6f + 0.4f*(1-scale);

ViewHelper.setTranslationX(mMenu, mMenuWidth * scale*0.8f);

ViewHelper.setScaleX(mMenu,leftScale);

ViewHelper.setScaleY(mMenu,leftScale);

ViewHelper.setAlpha(mMenu,leftAlpha);

//内容区域不断缩小

float rightScale = 0.7f+0.3f*scale;

//横向纵向缩放(不更改缩放中心点就全隐藏了)

ViewHelper.setPivotX(mContent,0);

ViewHelper.setPivotY(mContent,mContent.getHeight()/2);

ViewHelper.setScaleX(mContent,rightScale);

ViewHelper.setScaleY(mContent,rightScale);

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值