这个功能实在是太常见了 。 今天给大家封装了 一个不错的 自定义 滑动删除的 View ,废话不多说了,直接上代码 。
再自定义View中会使用这个颜色,可以根据项目需求自己设置 。 名称 left_shadow.xml、。哎有人问为什么把名称都写下来呢 。有助于一些 小伙伴门的黏贴。
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!--颜色渐变范围--> <gradient android:endColor="#50000000" android:startColor="#00000000" /> </shape>
先来这个自定义View -----------------------------------------------
package com.example.myapplication.ui; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.Scroller; import com.example.myapplication.R; /** * Created by xujiajian on 2018/12/11. */ public class SlidingLayout extends FrameLayout { // 页面边缘阴影的宽度默认值 private static final int SHADOW_WIDTH = 16; private Activity mActivity; private Scroller mScroller; // 页面边缘的阴影图 private Drawable mLeftShadow; // 页面边缘阴影的宽度 private int mShadowWidth; private int mInterceptDownX; private int mLastInterceptX; private int mLastInterceptY; private int mTouchDownX; private int mLastTouchX; private int mLastTouchY; private boolean isConsumed = false; public SlidingLayout(Context context) { this(context, null); } public SlidingLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SlidingLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } private void initView(Context context) { mScroller = new Scroller(context); mLeftShadow = getResources().getDrawable(R.drawable.left_shadow); int density = (int) getResources().getDisplayMetrics().density; mShadowWidth = SHADOW_WIDTH * density; } /** * 绑定Activity */ public void bindActivity(Activity activity) { mActivity = activity; ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView(); View child = decorView.getChildAt(0); decorView.removeView(child); addView(child); decorView.addView(this); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean intercept = false; int x = (int) ev.getX(); int y = (int) ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: intercept = false; mInterceptDownX = x; mLastInterceptX = x; mLastInterceptY = y; break; case MotionEvent.ACTION_MOVE: int deltaX = x - mLastInterceptX; int deltaY = y - mLastInterceptY; // 手指处于屏幕边缘,且横向滑动距离大于纵向滑动距离时,拦截事件 if (mInterceptDownX < (getWidth() / 10) && Math.abs(deltaX) > Math.abs(deltaY)) { intercept = true; } else { intercept = false; } mLastInterceptX = x; mLastInterceptY = y; break; case MotionEvent.ACTION_UP: intercept = false; mInterceptDownX = mLastInterceptX = mLastInterceptY = 0; break; } return intercept; } @Override public boolean onTouchEvent(MotionEvent ev) { int x = (int) ev.getX(); int y = (int) ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mTouchDownX = x; mLastTouchX = x; mLastTouchY = y; break; case MotionEvent.ACTION_MOVE: int deltaX = x - mLastTouchX; int deltaY = y - mLastTouchY; if (!isConsumed && mTouchDownX < (getWidth() / 10) && Math.abs(deltaX) > Math.abs(deltaY)) { isConsumed = true; } if (isConsumed) { int rightMovedX = mLastTouchX - (int) ev.getX(); // 左侧即将滑出屏幕 if (getScrollX() + rightMovedX >= 0) { scrollTo(0, 0); } else { scrollBy(rightMovedX, 0); } } mLastTouchX = x; mLastTouchY = y; break; case MotionEvent.ACTION_UP: isConsumed = false; mTouchDownX = mLastTouchX = mLastTouchY = 0; // 根据手指释放时的位置决定回弹还是关闭 if (-getScrollX() < getWidth() / 2) { scrollBack(); } else { scrollClose(); } break; } return true; } /** * 滑动返回 */ private void scrollBack() { int startX = getScrollX(); int dx = -getScrollX(); mScroller.startScroll(startX, 0, dx, 0, 300); invalidate(); } /** * 滑动关闭 */ private void scrollClose() { int startX = getScrollX(); int dx = -getScrollX() - getWidth(); mScroller.startScroll(startX, 0, dx, 0, 300); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), 0); postInvalidate(); } else if (-getScrollX() >= getWidth()) { mActivity.finish(); } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); drawShadow(canvas); } /** * 绘制边缘的阴影 */ private void drawShadow(Canvas canvas) { mLeftShadow.setBounds(0, 0, mShadowWidth, getHeight()); canvas.save(); canvas.translate(-mShadowWidth, 0); mLeftShadow.draw(canvas); canvas.restore(); } }
接下来我们来看看如何调用吧 --------------------------------------
在BaseActivity的onCreate方法调用即可
//仿IOS侧滑关闭页面 if (enableRightSliding()) { SlidingLayout slidingLayout = new SlidingLayout(this); slidingLayout.bindActivity(this); }
/** * 子类重写这个方法true:允许向右滑动,false:禁止向右滑动 * * @return */ protected boolean enableRightSliding() { return true; }
设置一下 Mainfest对activity 是如何配置展示的 这个theme需要自定义 根据需求自定义去吧 !
算了 还是给一些小伙伴们 写一下基本的数据配置吧。 再Valuer style 下面的属性 就是如此简单哦~~
<style name="GalleryTheme" parent="GalleryBaseTheme"> <item name="windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowIsTranslucent">true</item> <!-- Customize your theme here. --> <item name="colorPrimaryDark">@color/theme_color</item> <item name="android:windowAnimationStyle">@style/Animation_Activity</item> <item name="colorAccent">@color/theme_color</item> </style> <style name="Animation_Activity" parent="@android:style/Animation.Activity"> <item name="android:activityOpenEnterAnimation">@anim/slide_right_in</item> <item name="android:activityOpenExitAnimation">@anim/slide_left_out</item> <item name="android:activityCloseEnterAnimation">@anim/slide_left_in</item> <item name="android:activityCloseExitAnimation">@anim/slide_right_out</item> </style>
最后一步 就是在Style下面也就是最重要的一步 就是在res文件下创建anim文件 。 来制作滑动动画。缺一不可哦!!!!
动画顺序就是按图片显示来创建的 小伙伴们细心点哦 !
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="400" android:fromXDelta="-100.0%p" android:toXDelta="0.0" /> </set>
--------------------------------------------------
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="400" android:fromXDelta="0.0" android:toXDelta="-100.0%p" /> </set>
--------------------------------------------------
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0%p" android:duration="400" /> </set>
--------------------------------------------------
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0%p" android:toXDelta="100%p" android:duration="400" /> </set>
当你看到这时本文就已经结束了 ,如果小伙伴们还觉得不错的话希望点个赞 ,关注一下 ,以后希望我们大家一起进步。