罗敬威的博客

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  最近看到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"

    

 

posted on 2015-09-20 19:42  luojinwei  阅读(845)  评论(0编辑  收藏  举报