最近看到UC浏览器上的向右滑动删除activity,觉得这个退出动画挺酷的,自己在网上找了点资料,简单实现了一波。废话不多说,直接看代码。
这个是核心的代码:子类继承这个activity就可以了。
1 package com.itljw.slidingfinishactivity; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.content.Intent; 6 import android.graphics.Canvas; 7 import android.graphics.drawable.Drawable; 8 import android.os.Bundle; 9 import android.util.AttributeSet; 10 import android.view.MotionEvent; 11 import android.view.View; 12 import android.widget.RelativeLayout; 13 import android.widget.Scroller; 14 15 public abstract class BaseSlidingActivity extends Activity { 16 17 private GroupView slideGroupView; // 包裹布局的View 18 private View slideLayoutView; // 布局 19 private Scroller mScroller; // 滑动类 20 private Drawable mShadowDrawable; // 阴影 21 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 27 initView(); // 初始化 28 29 setContentView(setView()); // 设置布局 30 31 } 32 33 /** 34 * 初始化 35 */ 36 private void initView() { 37 slideGroupView = new GroupView(this); 38 mScroller = new Scroller(this); 39 mShadowDrawable = getResources().getDrawable(R.drawable.shape_left); 40 } 41 42 /** 43 * 设置布局 44 * @return 45 */ 46 private View setView() { 47 48 slideLayoutView = View.inflate(this, getLayoutID(), null); 49 50 // 设置参数信息 51 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 52 RelativeLayout.LayoutParams.MATCH_PARENT); 53 54 slideLayoutView.setLayoutParams(params); 55 slideGroupView.setLayoutParams(params); 56 57 slideGroupView.addView(slideLayoutView); // 将布局添加进GroupView 58 return slideGroupView; // 返回GroupView 59 } 60 61 @Override 62 public void startActivity(Intent intent) { 63 super.startActivity(intent); 64 overridePendingTransition(R.anim.base_slide_right_in, R.anim.base_slide_remain); 65 } 66 67 68 @Override 69 public void onBackPressed() { 70 super.onBackPressed(); 71 overridePendingTransition(0, R.anim.base_slide_right_out); 72 } 73 74 @Override 75 public void finish() { 76 // TODO Auto-generated method stub 77 super.finish(); 78 overridePendingTransition(R.anim.keep, R.anim.keep); 79 } 80 81 82 /** 83 * 包裹布局的View 84 */ 85 private class GroupView extends RelativeLayout { 86 87 private int screenWidth; // 屏幕宽度 88 private int startX = -1; // 按下的点 89 private int lastX; // 移动点 90 private int tempX; // 临时记录点的位置 91 private int minDistance = 10; // 最小距离 92 private int duration = 500; // 时间 93 private boolean isFinish; // 是否结束 94 95 public GroupView(Context context) { 96 this(context, null); 97 } 98 99 public GroupView(Context context, AttributeSet attrs) { 100 this(context, attrs, 0); 101 // TODO Auto-generated constructor stub 102 } 103 104 public GroupView(Context context, AttributeSet attrs, int defStyleAttr) { 105 super(context, attrs, defStyleAttr); 106 107 System.out.println("init"); 108 } 109 110 @Override 111 protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 112 113 // 画阴影 114 mShadowDrawable.setBounds(getLeft() - 10,0,getLeft(),getHeight()); 115 mShadowDrawable.draw(canvas); 116 117 return super.drawChild(canvas, child, drawingTime); 118 } 119 120 /** 121 * 触摸事件的处理 122 * @param event 123 * @return 124 */ 125 @Override 126 public boolean onTouchEvent(MotionEvent event) { 127 128 switch (event.getAction()){ 129 case MotionEvent.ACTION_DOWN: // 当手指按下的时候调用此方法 130 131 startX = tempX = (int) event.getRawX(); 132 133 break; 134 135 case MotionEvent.ACTION_MOVE: // 当手指移动的时候调用此方法 136 137 if(startX == -1){ // 避免没有响应到down事件的情况 138 startX = (int) event.getRawX(); 139 } 140 141 lastX = (int) event.getRawX(); 142 143 int deltax = tempX - lastX; // x轴方向上的偏移量 144 145 if(lastX - startX > minDistance){ // 当偏移量大于最小移动距离 向右滑动 146 this.scrollBy(deltax,0); 147 } 148 149 tempX = lastX; 150 151 break; 152 153 case MotionEvent.ACTION_UP: 154 155 // 判断当前移动的位置是否超过屏幕的一半 156 if(this.getScrollX() <= -screenWidth / 2){ 157 // 超过屏幕的一半 滑动到右边 158 159 mScroller.startScroll(this.getScrollX(),0,-(screenWidth + this.getScrollX()),0,duration); 160 postInvalidate(); // 刷新 161 162 isFinish = true; 163 164 }else{ 165 // 回弹 166 mScroller.startScroll(this.getScrollX(),0,-this.getScrollX(),0,duration); 167 postInvalidate(); // 刷新 168 169 isFinish = false; 170 } 171 172 break; 173 174 } 175 176 177 return true; 178 } 179 180 @Override 181 public void computeScroll() { 182 183 if(mScroller.computeScrollOffset()){ 184 // 滑动还没有结束 185 int currX = mScroller.getCurrX(); 186 int currY = mScroller.getCurrY(); 187 this.scrollTo(currX,currY); // 滑动 188 189 postInvalidate(); 190 191 // 滑动结束 192 if(mScroller.isFinished() && isFinish){ 193 finish(); 194 } 195 196 197 } 198 199 200 } 201 202 @Override 203 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 204 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 205 206 screenWidth = this.getMeasuredWidth(); // 获取屏幕的宽度 207 208 } 209 } 210 211 /** 212 * 获取布局id 213 * 214 * @return 215 */ 216 public abstract int getLayoutID(); 217 218 }
这个Activity中首先是让子类去实现getLayoutID(),返回布局id,然后用一个自定义的GroupView来包裹布局,这么做的目的是因为ScrollBy(),scrollTo()这几个函数主要作用的是View里面的内容,然后主要处理的是OnTouchEvent事件,记录按下的点和移动的点,通过scrollBy对View进行拖动,在Action_UP事件中,判断当前的位置,根据当前的位置来确定是向右滑动finish掉界面还是回弹界面。
阴影shape:
1 <?xml version="1.0" encoding="utf-8"?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android"> 3 4 <gradient 5 android:endColor="#55000000" 6 android:startColor="#00000000" 7 android:centerColor="#11000000"/> 8 </shape>
注意:activity的主题要设置为android:theme="@android:style/Theme.Translucent.NoTitleBar"
时间: 2024-10-26 13:07:55