안 드 로 이 드 에서 Swipe Back 이 오른쪽 슬라이더 효 과 를 실현 합 니 다.
그래서 자신 이 Activity 와 Fragment 를 계승 하고 SwipeBackActivity 와 SwipeBackFragment 를 파생 시 켜 이런 효과 에 대한 실현,즉 이 두 가지 유형 만 계승 하면 된다.
효 과 는 다음 과 같다.
Fragment
Frgament 의 효 과 는 Activity 보다 약간 간단 하 다.왜냐하면 Activity 는 dectorView 를 고려 해 야 하기 때문이다.
미끄럼 을 지원 하 는 컨트롤 SwipeLayout 입 니 다.핵심 적 인 사 고 는 기 존의 컨트롤 을 미끄럼 을 지원 하 는 컨트롤 에 추가 하 는 것 입 니 다.SwipeLayout 는 제스처 속 도 를 계산 하 는 데 주의해 야 합 니 다.소스 코드 는 다음 과 같 습 니 다.
package com.ui.jerry.swipebackdemo;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.Toast;
public class SwipeLayout extends LinearLayout {
public static final String TAG = "SwipeLayout";
private View mEmptyView;
private View mContentView;
private int mLeftEdge;
private int mWidth;
private int mMaxScrollX;
private Scroller mScroller;
private VelocityTracker mVelocityTracker = null;
private int mMaxFlingVelocity;
private int mLastX;
ViewGroup.LayoutParams childParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
private Context mContext;
public static final int DURATION = 1500; //
public static final int OPEN_ANIM_DURATION = 1000;
public static int SNAP_VELOCITY = 600; //
private OnFinishListener mOnFinishListener;
public SwipeLayout(Context context) {
this(context, null);
}
public SwipeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
public void setOnFinishListener(OnFinishListener mOnFinishListener) {
this.mOnFinishListener = mOnFinishListener;
}
void init() {
mScroller = new Scroller(mContext);
mMaxFlingVelocity = ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity();
mWidth = DisplayUtils.getScreenWidth(mContext) * 2;
mMaxScrollX = mWidth / 2;
mLeftEdge = mMaxScrollX - mMaxScrollX / 3;
setOrientation(LinearLayout.HORIZONTAL);
childParams.width = DisplayUtils.getScreenWidth(mContext);
mEmptyView = LayoutInflater.from(mContext).inflate(R.layout.view_translate, null);
addView(mEmptyView, childParams);
}
public void setContentView(View contentView) {
if (mContentView != null) {
removeView(mContentView);
}
mContentView = contentView;
addView(contentView, childParams);
postDelayed(new Runnable() {
@Override
public void run() {
openActivityAnimation();
}
}, 200);
}
/**
*
*
* @return
*/
private VelocityTracker getVelocityTracker() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
return mVelocityTracker;
}
/**
*
*/
private void recycleVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
//1.
getVelocityTracker();
//2.
mVelocityTracker.addMovement(ev);
int pointId = -1;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// , , , ACTION_DOWN
// clearScrollHis();
mLastX = (int) ev.getX();
pointId = ev.getPointerId(0);
break;
case MotionEvent.ACTION_MOVE:
int nextScrollX = (int) (mLastX - ev.getX() + getScrollX());
if (scrollTo(nextScrollX)) {
mLastX = (int) ev.getX();
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
//3.
mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
// x y
float vX = mVelocityTracker.getXVelocity(pointId);
Log.i(TAG, "mVelocityX:" + vX);
//
if (vX > SNAP_VELOCITY) {
scrollToLeft();
} else if (vX < -SNAP_VELOCITY) {
scrollToRight();
} else {
snapToDestation();
}
//4.
recycleVelocityTracker();
break;
}
return true;
}
private void openActivityAnimation() {
clearScrollHis();
mScroller.startScroll(getScrollX(), 0, mMaxScrollX - getScrollX(), 0, OPEN_ANIM_DURATION);
invalidate();// invalidate() computeScroll() , ,
}
public void closeActivityAnimation() {
clearScrollHis();
mScroller.startScroll(getScrollX(), 0, -getScrollX(), 0, OPEN_ANIM_DURATION);
invalidate();// invalidate() computeScroll() , ,
}
private void clearScrollHis() {
if (mScroller != null) {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
}
}
/**
*
*/
private void snapToDestation() {
int scrollX = getScrollX();
if (scrollX > 0 && scrollX <= mLeftEdge) {
smoothScrollTo(0);
} else if (scrollX > mLeftEdge) {
smoothScrollTo(mMaxScrollX);
}
}
/**
*
*
* @param x
* @return
*/
public boolean scrollTo(int x) {
if (x < 0) {
scrollTo(0, 0);
} else if (x > mMaxScrollX) {
scrollTo(mMaxScrollX, 0);
} else {
scrollTo(x, 0);
}
return true;
}
public void scrollToRight() {
smoothScrollTo(mMaxScrollX);
}
public void scrollToLeft() {
smoothScrollTo(0);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
Log.d(TAG, "left:" + l);
if (l == 0) {
Log.d(TAG, "OnFinish");
Toast.makeText(mContext, "Finished", Toast.LENGTH_SHORT).show();
if(mOnFinishListener!=null){
mOnFinishListener.onFinish();
}
}
}
public void smoothScrollTo(int fx) {
if (fx < 0) {
smoothScrollTo(0, 0);
} else if (fx > mMaxScrollX) {
smoothScrollTo(mMaxScrollX, 0);
} else {
smoothScrollTo(fx, 0);
}
}
// //
public void smoothScrollTo(int fx, int fy) {
int dx = fx - getScrollX();
int dy = fy - getScrollY();
smoothScrollBy(dx, dy);
}
//
public void smoothScrollBy(int dx, int dy) {
// mScroller
mScroller.startScroll(getScrollX(), 0, dx, dy, Math.abs(dx * DURATION / mMaxScrollX));
invalidate();// invalidate() computeScroll() , ,
}
@Override
public void computeScroll() {
// mScroller
if (mScroller.computeScrollOffset()) {
// View scrollTo()
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
// ,
postInvalidate();
}
super.computeScroll();
}
/**
* fragment activity
*/
public interface OnFinishListener{
void onFinish();
}
}
이상 은 본문의 전체 내용 이 므 로 여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.