package com.example.swipedelete.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
/**
* 【Item侧滑删除菜单】
* 继承自ViewGroup,实现滑动出现删除等选项的效果,
* 思路:跟随手势将item向左滑动,
* 在onMeasure时 将第一个Item设为屏幕宽度
* 【解决屏幕上多个侧滑删除菜单】:内设一个类静态View类型变量 ViewCache,存储的是当前正处于右滑状态的CstSwipeMenuItemViewGroup,
* 每次Touch时对比,如果两次Touch的不是一个View,那么令ViewCache恢复普通状态,并且设置新的CacheView
* 只要有一个侧滑菜单处于打开状态, 就不给外层布局上下滑动了
* <p/>
* 平滑滚动使用的是Scroller,20160811,最新平滑滚动又用属性动画做了,因为这样更酷炫(设置加速器不同)
* <p/>
* 20160824,fix 【多指一起滑我的情况】:只接第一个客人(使用一个类静态布尔变量)
* other:
* 1 菜单处于侧滑时,拦截长按事件
* 2 解决侧滑时 点击 的冲突
* 3 通过 isIos 变量控制是否是IOS阻塞式交互,默认是打开的。
* 4 通过 isSwipeEnable 变量控制是否开启右滑菜单,默认打开。(某些场景,复用item,没有编辑权限的用户不能右滑)
* 5 2016 09 29 add,,通过开关 isLeftSwipe支持左滑右滑
* 6 2016 10 21 add , 增加viewChache 的 get()方法,可以用在:当点击外部空白处时,关闭正在展开的侧滑菜单。
* 7 2016 10 22 fix , 当父控件宽度不是全屏时的bug。
* 2016 10 22 add , 仿QQ,侧滑菜单展开时,点击除侧滑菜单之外的区域,关闭侧滑菜单。
* 8 2016 11 03 add,判断手指起始落点,如果距离属于滑动了,就屏蔽一切点击事件。
* 9 2016 11 04 fix 长按事件和侧滑的冲突。
* Created by zhangxutong .
* Date: 16/04/24
*/
public class SwipeMenuLayout extends ViewGroup {
private static final String TAG = "zxt";
private boolean isSwipeEnable = true;//右滑删除功能的开关,默认开
private int mScaleTouchSlop;//为了处理单击事件的冲突
private int mMaxVelocity;//计算滑动速度用
private int mPointerId;//多点触摸只算第一根手指的速度
private int mHeight;//自己的高度
private int mMaxWidth;//父控件留给自己的最大的水平空间
/**
* 右侧菜单宽度总和(最大滑动距离)
*/
private int mRightMenuWidths;
/**
* 滑动判定临界值(右侧菜单宽度的40%) 手指抬起时,超过了展开,没超过收起menu
*/
private int mLimit;
//private Scroller mScroller;//以前item的滑动动画靠它做,现在用属性动画做
//上一次的xy
private PointF mLastP = new PointF();
//2016 10 22 add , 仿QQ,侧滑菜单展开时,点击除侧滑菜单之外的区域,关闭侧滑菜单。
//增加一个布尔值变量,dispatch函数里,每次down时,为true,move时判断,如果是滑动动作,设为false。
//在Intercept函数的up时,判断这个变量,如果仍为true 说明是点击事件,则关闭菜单。
private boolean isUnMoved = true;
//2016 11 03 add,判断手指起始落点,如果距离属于滑动了,就屏蔽一切点击事件。
//up-down的坐标,判断是否是滑动,如果是,则屏蔽一切点击事件
private PointF mFirstP = new PointF();
private boolean isUserSwiped;
//存储的是当前正在展开的View
private static SwipeMenuLayout mViewCache;
//防止多只手指一起滑我的flag 在每次down里判断, touch事件结束清空
private static boolean isTouching;
private VelocityTracker mVelocityTracker;//滑动速度变量
private android.util.Log LogUtils;
private boolean isIos = true;//IOS类型的开关
private boolean iosInterceptFlag = false;//IOS类型下,是否拦截事件的flag
//20160929add 左滑右滑的开关
private boolean isLeftSwipe = true;
public SwipeMenuLayout(Context context) {
this(context, null);
}
public SwipeMenuLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwipeMenuLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public boolean isSwipeEnable() {
return isSwipeEnable;
}
/**
* 设置侧滑功能开关
*
* @param swipeEnable
*/
public void setSwipeEnable(boolean swipeEnable) {
isSwipeEnable = swipeEnable;
}
public boolean isIos() {
return isIos;
}
/**
* 设置是否开启IOS阻塞式交互
*
* @param ios
*/
public SwipeMenuLayout setIos(boolean ios) {
isIos = ios;
return this;
}
public boolean isLeftSwipe() {
return isLeftSwipe;
}
/**
* 设置是否开启左滑出菜单,设置false 为右滑出菜单
*
* @param leftSwipe
* @return
*/
public SwipeMenuLayout setLeftSwipe(boolean leftSwipe) {
isLeftSwipe = leftSwipe;
return this;
}
/**
* 返回ViewCache
*
* @return
*/
public static SwipeMenuLayout getViewCache() {
return mViewCache;
}
private void init(Context context) {
mScaleTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mMaxVelocity = ViewConfiguration.get(context).getScaledMaximumFlingVelocity();
//初始化滑动帮助类对象
//mScroller = new Scroller(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Log.d(TAG, "onMeasure() called with: " + "widthMeasureSpec = [" + widthMeasureSpec + "], heightMeasureSpec = [" + heightMeasureSpec + "]");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//add by zhangxutong 2016 10 22 for 最大宽度根据父控件计算出,如果没有父控件用屏幕宽度
ViewParent parent = getParent();
if (parent != null && parent instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) parent;
mMaxWidth = viewGroup.getMeasuredWidth() - viewGroup.getPaddingLeft() - viewGroup.getPaddingRight();
} else {
mMaxWidth = getResources().getDisplayMetrics().widthPixels;
}
mRightMenuWidths = 0;//由于ViewHolder的复用机制,每次这里要手动恢复初始值
int childCount = getChildCount();
//add by 2016 08 11 为了子View的高,可以matchParent(参考的FrameLayout 和LinearLayout的Horizontal)
final boolean measureMatchParentChildren = MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
boolean isNeedMeasureChildHeight = false;
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
if (childView.getVisibility() != GONE) {
//measureChild(childView, widthMeasureSpec, heightMeasureSpec);
measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0);
final MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
mHeight = Math.max(mHeight, childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
if (measureMatchParentChildren && lp.height == Lay
没有合适的资源?快使用搜索试试~ 我知道了~
Android 仿QQ侧滑删除—一个满足ListView、RecyclerView以及其他View通用的侧滑删除
共52个文件
xml:23个
java:9个
png:5个
5星 · 超过95%的资源 需积分: 34 692 下载量 142 浏览量
2016-11-07
11:47:10
上传
评论 3
收藏 135KB ZIP 举报
温馨提示
仿QQ侧滑删除,使用简单,满足ListView、RecyclerView以及其他View通用的侧滑删除
资源推荐
资源详情
资源评论
收起资源包目录
SwipeDelete.zip (52个子文件)
SwipeDelete
gradlew 5KB
settings.gradle 16B
SwipeDelete.iml 942B
.idea
libraries
junit_4_12.xml 477B
hamcrest_core_1_3.xml 526B
support_vector_drawable_23_4_0.xml 641B
support_v4_23_4_0.xml 904B
appcompat_v7_23_4_0.xml 762B
animated_vector_drawable_23_4_0.xml 646B
support_annotations_23_4_0.xml 497B
runConfigurations.xml 564B
misc.xml 3KB
compiler.xml 686B
workspace.xml 180KB
gradle.xml 829B
.name 11B
encodings.xml 159B
modules.xml 359B
copyright
profiles_settings.xml 76B
gradle
wrapper
gradle-wrapper.properties 231B
gradle-wrapper.jar 52KB
local.properties 500B
gradlew.bat 2KB
gradle.properties 872B
.gitignore 105B
app
src
androidTest
java
com
example
swipedelete
ApplicationTest.java 366B
test
java
com
example
swipedelete
ExampleUnitTest.java 330B
main
AndroidManifest.xml 682B
res
mipmap-hdpi
ic_launcher.png 3KB
mipmap-xxxhdpi
ic_launcher.png 10KB
mipmap-xhdpi
ic_launcher.png 5KB
mipmap-mdpi
ic_launcher.png 2KB
drawable
layout
item_layout.xml 2KB
activity_main.xml 475B
values-w820dp
dimens.xml 364B
values
colors.xml 214B
strings.xml 77B
styles.xml 394B
dimens.xml 216B
mipmap-xxhdpi
ic_launcher.png 8KB
java
com
example
swipedelete
view
SwipeMenuLayout.java 26KB
SwipeDeleteView.java 23KB
utils
CommonAdapter.java 3KB
ViewHolder.java 6KB
ListViewAdapter.java 3KB
MainActivity.java 4KB
TestBean.java 479B
libs
app.iml 9KB
.gitignore 8B
build.gradle 650B
proguard-rules.pro 663B
build.gradle 521B
共 52 条
- 1
风一样的男人zzz
- 粉丝: 64
- 资源: 15
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页