Android에서 ios 사이드스케이팅을 따라 activity를 종료합니다.

16003 단어
최근에 ios의 대부분 페이지가 옆으로 미끄러져서 이전 페이지에서 퇴출될 수 있다는 것을 발견하여 스스로 연구해 보았다
먼저 사이드 슬라이딩을 감청하는 클래스를 만들었습니다
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;

public class SwipeBackController {
    private static final String TAG = SwipeBackController.class.getSimpleName();
    public static final int ANIMATION_DURATION = 300;//      
    public static final int DEFAULT_TOUCH_THRESHOLD = 60;//                 

//    private WeakReference mActivityWR;

    private int mScreenWidth;
    private int mTouchSlop;

    private boolean isMoving = false;
    private float mInitX;
    private float mInitY;

    private ViewGroup decorView;//     
    private ViewGroup contentView;//content  
    private ViewGroup userView;//       

    private ArgbEvaluator evaluator;
    private ValueAnimator mAnimator;
    private VelocityTracker mVelTracker;

    public SwipeBackController(final Activity activity) {
        mScreenWidth = activity.getResources().getDisplayMetrics().widthPixels;
        mTouchSlop = ViewConfiguration.get(activity).getScaledTouchSlop();
        evaluator = new ArgbEvaluator();

        decorView = (ViewGroup) activity.getWindow().getDecorView();
        decorView.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00ffffff")));
        contentView = (ViewGroup) activity.findViewById(android.R.id.content);
        userView = (ViewGroup) contentView.getChildAt(0);

        mAnimator = new ValueAnimator();
        mAnimator.setDuration(ANIMATION_DURATION);
        mAnimator.setInterpolator(new DecelerateInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int x = (Integer) valueAnimator.getAnimatedValue();
                if (x >= mScreenWidth) {
                    activity.finish();
                }

                handleView(x);
                handleBackgroundColor(x);
            }
        });
    }

    public void handleView(int x) {
        userView.setTranslationX(x);
    }
    /**
     *           
     * @param x
     */
    private void handleBackgroundColor(float x) {
        int colorValue = (int) evaluator.evaluate(x / mScreenWidth,
                Color.parseColor("#dd000000"), Color.parseColor("#00000000"));
        contentView.setBackgroundColor(colorValue);
        Log.d(TAG, "x is " + x);
    }

    public boolean processEvent(MotionEvent event) {
        getVelocityTracker(event);

        if (mAnimator.isRunning()) {
            return true;
        }

        int pointId = -1;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mInitX = event.getRawX();
                mInitY = event.getRawY();
                pointId = event.getPointerId(0);
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isMoving) {
                    float dx = Math.abs(event.getRawX() - mInitX);
                    float dy = Math.abs(event.getRawY() - mInitY);
                    if (dx > mTouchSlop && dx > dy && mInitX < DEFAULT_TOUCH_THRESHOLD) {
                        isMoving = true;
                    }
                }
                if (isMoving) {
                    handleView((int) event.getRawX());
                    handleBackgroundColor(event.getRawX());
                }

                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                int distance = (int) (event.getRawX() - mInitX);

                mVelTracker.computeCurrentVelocity(1000);
                //  x      
                float velocityX = mVelTracker.getXVelocity(pointId);

                Log.d(TAG, "mVelocityX is " + velocityX);
                if (isMoving && Math.abs(userView.getTranslationX()) >= 0) {
                    if (velocityX > 1000f || distance >= mScreenWidth / 4) {
                        mAnimator.setIntValues((int) event.getRawX(), mScreenWidth);
                    } else {
                        mAnimator.setIntValues((int) event.getRawX(), 0);
                    }
                    mAnimator.start();
                    isMoving = false;
                }

                mInitX = 0;
                mInitY = 0;

                recycleVelocityTracker();
                break;
        }
        return true;
    }

    /**
     *        
     *
     * @return
     */
    private VelocityTracker getVelocityTracker(MotionEvent event) {
        if (mVelTracker == null) {
            mVelTracker = VelocityTracker.obtain();
        }
        mVelTracker.addMovement(event);
        return mVelTracker;
    }

    /**
     *        
     */
    private void recycleVelocityTracker() {
        if (mVelTracker != null) {
            mVelTracker.clear();
            mVelTracker.recycle();
            mVelTracker = null;
        }
    }
}

종료할 activity의 코드는 다음과 같습니다
public class Main2Activity extends AppCompatActivity {
    private SwipeBackController swipeBackController;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main2);

        swipeBackController = new SwipeBackController(this);
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (swipeBackController.processEvent(ev)) {
            return true;
        } else {
            return super.onTouchEvent(ev);
        }
    }
}

홈 페이지가 Request Window Feature(Window.FEATURE NO TITLE)라는 줄 코드는 set ContentView 앞에 써야 합니다. 그렇지 않으면 오류가 발생합니다. 믿지 않으시면 한번 시도해 보십시오.
포석이 이렇습니다.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    tools:context="${relativePackage}.${activityClass}"
    >
    <ImageView
        android:id="@+id/imv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffff9f"/>
    <TextView
        android:layout_marginTop="20dp"
        android:id="@+id/txt"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="30dp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:textColor="@android:color/black"
        android:text="           "/>

RelativeLayout>

이 때 종료할 때 검은색이고 보기 좋지 않은 것을 발견할 수 있습니다. 목록 파일에서 종료할 activity 테마를 투명하게 설정해야 합니다.
<activity
            android:name=".Main2Activity"
            android:theme="@android:style/Theme.Translucent" />

만약 당신이 신문을 실행하고 이 주제가 없다는 것을 발견한다면 그것은 당신이 사용하지 않는 import android를 설명하는 것입니다.app.액티비티 이 가방의 액티비티.
그럼 import android를 쓰려면support.v7.app.AppCompatActivity 이것은 투명 테마를 사용자 정의해야 합니다
우선res의values의color 파일에 투명한 색을 넣어야 합니다
<color name="transparent">#00000000

그리고values의 스타일에 사용자 정의 테마를 추가합니다
마지막으로 목록 파일에서 사용자 정의 테마를 호출합니다
<activity
            android:name=".Main2Activity"
            android:theme="@style/TranslucentFullScreenTheme" />

demo 주소:http://download.csdn.net/download/dang321580/10222180
여기서는 기본적으로 실현할 수 있으니 문제가 있으면 메시지를 남겨도 된다

좋은 웹페이지 즐겨찾기