时间:2020-11-10 16:17:43 | 栏目:Android代码 | 点击:次
自己实现了一下侧滑的三种方式(注释都写代码里了)
本文Demo下载地址:Andriod侧滑
本文实现所需框架:nineoldandroids下载地址:nineoldandroids
1.普通侧滑:
主要是基于HorizontalScrollView做的:示例代码如下
主要布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 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"> <!--xmlns:gaoyu自定义命名空间 原有到res+包名--> <gaoyu.com.myapplication.sideslip.SlidingMenu_qq android:id="@+id/SlMenu_sideslip" android:layout_width="wrap_content" android:layout_height="fill_parent" gaoyu:rightPadding="100dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <include layout="@layout/sideslip_menu" /> <!--这个LinearLayout就是content--> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/sliding"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick_sideslip_qq" android:text="切换菜单" /> </LinearLayout> </LinearLayout> </gaoyu.com.myapplication.sideslip.SlidingMenu_qq> </RelativeLayout>
菜单的布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerInParent="true"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView 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"/> <TextView 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"/> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView 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"/> <TextView 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"/> </RelativeLayout><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView 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"/> <TextView 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"/> </RelativeLayout><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView 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"/> <TextView 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"/> </RelativeLayout><RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView 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"/> <TextView 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"/> </RelativeLayout> </LinearLayout> </RelativeLayout>
定义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); }
更多学习内容,可以点击《Android侧滑效果汇总》学习。