感谢红橙Darren博主

布局文件中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"tools:context="com.app.rzm.test.TestSlidingViewActivity"><com.rzm.commonlibrary.views.SlidingViewapp:menuPaddingRight="100dp"app:menuParallax="true"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:background="#ffffff"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:layout_width="match_parent"android:text="我在侧边位置"android:textSize="50sp"android:layout_height="match_parent" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:background="@color/transparent"android:layout_height="match_parent"><TextViewandroid:layout_width="match_parent"android:text="我在主版位置"android:textSize="50sp"android:layout_height="match_parent" /></LinearLayout></LinearLayout></com.rzm.commonlibrary.views.SlidingView>
</LinearLayout>
package com.rzm.commonlibrary.views;import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;import com.rzm.commonlibrary.R;
import com.rzm.commonlibrary.utils.LogUtils;/*** Created by renzhenming on 2018/3/28.** SlidingView继承自HorizontalScrollView,所以在布局中使用的时候,需要设置一个唯一的子View,然后* 往这个子 view中添加侧边栏和主栏*/public class SlidingView extends HorizontalScrollView{private final String TAG = getClass().getSimpleName();//侧滑菜单的宽度private final int mMenuWidth;private final Context mContext;//默认的侧边栏滑出最大位置距离右边屏幕的距离private float mMenuPaddingRight = 100;//侧边菜单布局private View mMenuView;//主页内容布局,包括用户的contentView和我们添加的阴影效果private ViewGroup mContentView;//侧边栏menu是否打开private boolean mMenuOpened;//设置抽屉模式private boolean mParallaxMode;//手势监听器private GestureDetector mGestureDetector;//快速滑动打开收起侧边栏的敏感指数,越大敏感度越小,约不容易打开关闭//不能过大也能过小,private float mSensitivity = 1000;//设置阴影private ImageView mShadowIv;//视差模式下,默认的侧边栏缩进的距离相对于侧边栏宽度的比例private float mTransitionPercent = 0.8f;//阴影透明度能达到的最深颜色值private String mAlphaColor="#99000000";public SlidingView(Context context) {this(context,null);}public SlidingView(Context context, AttributeSet attrs) {this(context, attrs,-1);}public SlidingView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SlidingView);mMenuPaddingRight = typedArray.getDimension(R.styleable.SlidingView_menuPaddingRight, dp2px((int) mMenuPaddingRight));mParallaxMode = typedArray.getBoolean(R.styleable.SlidingView_menuParallax, mParallaxMode);//侧边栏的宽度mMenuWidth = (int) (getScreenWidth() - mMenuPaddingRight);typedArray.recycle();mGestureDetector = new GestureDetector(context, new GestureListener());}@Overridepublic boolean onTouchEvent(MotionEvent ev) {//如果需要GestureDetector处理,则由其处理if (mGestureDetector.onTouchEvent(ev)){return mGestureDetector.onTouchEvent(ev);}switch (ev.getAction()){case MotionEvent.ACTION_UP://这个位置指的是,当前这个view和手机屏幕左边届交点距离view最左侧的距离,这里最小为0,不会为负//当侧边栏滑出的过程中,scrollX呈递减的趋势,直到=0int scrollX = getScrollX();LogUtils.d(TAG,"scrollX:"+scrollX);if (scrollX > mMenuWidth/2){//滑出了一部分,但是还没有到宽度的1/2closeMenu();}else{openMenu();}return false;}return super.onTouchEvent(ev);}/*** 打开侧边栏*/private void openMenu() {smoothScrollTo(0,0);mMenuOpened = true;}/*** 关闭侧边栏*/private void closeMenu() {smoothScrollTo(mMenuWidth,0);mMenuOpened = false;}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);//默认设置侧滑菜单隐藏if (changed){//scrollTo 让当前屏幕左边界滑动到(mMenuWidth,0)这个坐标位置scrollTo(mMenuWidth, 0);}}@Overrideprotected void onFinishInflate() {super.onFinishInflate();//获取根viewViewGroup rootView = (ViewGroup) getChildAt(0);int childCount = rootView.getChildCount();if (childCount > 2){throw new IllegalStateException("you should add two child view at most");}//获取两个布局mMenuView = rootView.getChildAt(0);//给内容添加阴影效果mContentView = new FrameLayout(mContext);ViewGroup.LayoutParams contentParams = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);mContentView.setLayoutParams(contentParams);//获取原来的内容布局,并把原来的内容布局从LinearLayout中异常View oldContentView = rootView.getChildAt(1);rootView.removeView(oldContentView);//把原来的内容View 和 阴影加到我们新创建的内容布局中mContentView.addView(oldContentView);//创建阴影mShadowIv = new ImageView(mContext);mShadowIv.setBackgroundColor(Color.parseColor(mAlphaColor));mContentView.addView(mShadowIv);//把包含阴影的新的内容View 添加到 LinearLayout中rootView.addView(mContentView);//设置二者宽度mMenuView.getLayoutParams().width =  mMenuWidth;mContentView.getLayoutParams().width = getScreenWidth();}private float dp2px(int dp){return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,getResources().getDisplayMetrics());}/*** 屏幕宽度* @return*/public int getScreenWidth(){Resources resources = getResources();DisplayMetrics metrics = resources.getDisplayMetrics();return metrics.widthPixels;}private class GestureListener extends GestureDetector.SimpleOnGestureListener{// 处理手势快速滑动@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {//velocityX,velocityY都是朝坐标系正方向滑动为正,负方向为负,表示正方向上单位时间的速度//velocityX为正,表示单位时间内,LogUtils.d(TAG,"velocityX:"+velocityX+",velocityY:"+velocityY);if (mMenuOpened){if (velocityX < -mSensitivity){toggleMenu();return true;}}else{if (velocityX>mSensitivity){toggleMenu();return true;}}return super.onFling(e1, e2, velocityX, velocityY);}}/*** 切换菜单的状态*/private void toggleMenu() {if(mMenuOpened){closeMenu();LogUtils.d(TAG,"close");}else{openMenu();LogUtils.d(TAG,"open");}}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {super.onScrollChanged(l, t, oldl, oldt);// l 是 当前滚动的x距离 指的是当前view和屏幕左侧边界相交点距离view最左侧的距离LogUtils.e(TAG,"onScrollChanged:l===="+l);if (mParallaxMode) {//在onLayout中,默认会将这个SlidingView向左移动一个侧边栏宽度//这个时候onScrollChanged会被调用,这时候会执行这行代码,将侧边栏向x轴正方向移动一定比例的l宽度,实际上//也此时,侧边栏已经被放在了主也contentView的下边,此时,滑动contentView的时候,会达到一种视觉差异效果mMenuView.setTranslationX(l * mTransitionPercent);}//给内容添加阴影效果 - 计算梯度值float gradientValue = l * 1f / mMenuWidth;LogUtils.e(TAG,"gradientValue:"+gradientValue);//这是 1 - 0 变化的值//给内容添加阴影效果 - 给阴影的View指定透明度 0 - 1 变化的值float shadowAlpha = 1 - gradientValue;LogUtils.e(TAG,"shadowAlpha:"+shadowAlpha);mShadowIv.setAlpha(shadowAlpha);}}

04.自定义View(SlidingView仿QQ侧滑)相关推荐

  1. Android自定义View之仿QQ侧滑菜单实现

    最近,由于正在做的一个应用中要用到侧滑菜单,所以通过查资料看视频,学习了一下自定义View,实现一个类似于QQ的侧滑菜单,顺便还将其封装为自定义组件,可以实现类似QQ的侧滑菜单和抽屉式侧滑菜单两种菜单 ...

  2. 名片夹android布局代码,Android自定义布局实现仿qq侧滑部分代码

    自定义布局实现仿qq侧滑部分Android代码,供大家参考,具体内容如下 实现说明: 通过自定义布局实现: SlidingLayout继承于 HorizontalScrollView /** * Cr ...

  3. android仿qq布局,Android自定义布局实现仿qq侧滑部分代码

    自定义布局实现仿qq侧滑部分android代码,供大家参考,具体内容如下 实现说明: 通过自定义布局实现: slidinglayout继承于 horizontalscrollview /** * cr ...

  4. Android自定义View之仿QQ运动步数进度效果

    文章目录 前言 先看效果图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6e4ddec17933496ea4830fa08d8ffbe5.png?x-oss-pr ...

  5. 自定义View之仿QQ运动步数进度效果

    前言 今天接着上一篇来写关于自定义View方面的东西,我是近期在学习整理这方面的知识点,所以把相关的笔记都放到这个Android自定义View的专栏里了,方便自己下次忘记的时候能回来翻翻,今天的内容是 ...

  6. android 自定义view实现仿QQ运动步数进度效果

    最近公司在策划一个新的项目,原型还没出来,再说这公司人都要走没了,估计又要找工作了,所以必须要学习,争取每个写个关于自定义view方面的,这样几个月积累下来,也能学习到东西,今天就带来简单的效果,就是 ...

  7. 自定义 View 之仿 QQ 步数变动动画效果

    博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此   博主:威威喵  |  博客主页:https://blog.csdn.net/ ...

  8. Android自定义View实现仿QQ实现运动步数效果

    效果图: 1.attrs.xml中 <declare-styleable name="QQStepView"><attr name="outerColo ...

  9. Android仿QQ侧滑菜单

    先上效果图: GIF图有点模糊,源码已上传Github:Android仿QQ侧滑菜单 ####整体思路: 自定义ItemView的根布局(SwipeMenuLayout extends LinearL ...

最新文章

  1. 【列表】python编程列表解析
  2. C#编程(十六)----------匿名类型
  3. ubuntu登录界面循环登录
  4. centos vscode安装到指定目录_win10 WSL构建vscode+centos开发环境
  5. 南阳5--Binary String Matching(Kmp)
  6. Condition接口详解
  7. js函数中的参数的个数
  8. 输入一个英文句子,翻转句子中单词的顺序 例如输入“I am a student.”,则输出“student. a am I”。
  9. 有赞再推视频号流量扶持政策 单商家单月最高可获5万流量奖励
  10. sparksql 操作hive_三十六、图解SparkSQL运行原理
  11. 227 Puzzle
  12. qt 当前窗口句柄_QT获取Windows系统所有窗口句柄
  13. 数字三角形、数塔问题(DP)
  14. 人工智能项目商业价值,主要体现在哪几个方面?
  15. 什么是http及RFC?
  16. STC12C5A60S2输出时钟频率
  17. 从虚拟化前端Bug学习分析Kernel Dump
  18. html 输入框并行,Python:输入文本框并行捕获userinput到OpenCV Live网络摄像头图像...
  19. Chino with Triangle
  20. java 将ftl文件作为模板导出word文档

热门文章

  1. 【bzoj1507】[NOI2003]Editor
  2. .net连接DB2的异常SQL0666 - SQL query exceeds specified time limit or storage limit.错误处理
  3. Java中J.U.C扩展组件之Fork,join
  4. Spring延迟依赖注入ObjectFactory/ObjectProvider
  5. 页面搭建工具总结及扩展架构思考
  6. Spring Boot与Spring Cloud是什么关系?
  7. openssl内存分配,查看内存泄露
  8. Maven中如何配置WAR依赖WAR和JAR的多模块项目结构
  9. Python3笔记——IDE的选择
  10. IIS 7中ISAPI筛选器配置