大屏幕时代的到来,目前大部分的APP都支持侧滑关闭Activity及切换Activity的动画效果,这些效果极大的提高了用户体验。比如苹果的safari中的滑动返回操作。
我也参考了github上面的 ikew0ng/SwipeBackLayout项目写了一个自己的swipebacklayout。在源码的基础上,添加了一些注释,并没有对源码做出太大改动。
项目github地址:https://github.com/CameloeAnthony/SwipeBackActivity
下面对源码进行学习和分析:
(1)使用swipebackActivitity ,如图,只需要继承SwipeBackActivity,
并且注意在manifest文件中定义theme,添加如下属性:
(2)来看看swipeBackActivity是怎么实现的:
package nsu.edu.com.library;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
/**
* all the subClass extends from this class to use swipe-back function
*/
public class SwipeBackActivity extends AppCompatActivity implements SwipeBackActivityBase {
private SwipeBackActivityHelper mHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHelper = new SwipeBackActivityHelper(this);
mHelper.onActivityCreate();
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mHelper.onPostCreate();
}
@Override
public View findViewById(int id) {
View v = super.findViewById(id);
if (v == null && mHelper != null)
return mHelper.findViewById(id);
return v;
}
@Override
public SwipeBackLayout getSwipeBackLayout() {
return mHelper.getSwipeBackLayout();
}
@Override
public void setSwipeBackEnable(boolean enable) {
getSwipeBackLayout().setEnableGesture(enable);
}
@Override
public void scrollToFinishActivity() {
Utils.convertActivityToTranslucent(this);
getSwipeBackLayout().scrollToFinishActivity();
}
}
可以看到只需要对SwipeBackActivityBase 进行实现,其实主要的操作是由SwipeBackActivityHelper 的对象完成的。它主要完成了SwipeBackActivity在onCreate,onPostCreate,以及findViewById,都将操作传递给了SwipeBackActivityHelper 的对象。那么接下来看看它是怎么实现的。
(3)来看看SwipeBackActivityHelper 是怎么实现的。
package nsu.edu.com.library;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
/**
*
*/
public class SwipeBackActivityHelper {
private Activity mActivity;
private SwipeBackLayout mSwipeBackLayout;
public SwipeBackActivityHelper(Activity activity) {
mActivity = activity;
}
@SuppressWarnings("deprecation")
public void onActivityCreate() {
mActivity.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mActivity.getWindow().getDecorView().setBackgroundDrawable(null);
mSwipeBackLayout = (SwipeBackLayout) LayoutInflater.from(mActivity).inflate(
R.layout.swipeback_layout, null);
mSwipeBackLayout.addSwipeListener(new SwipeBackLayout.SwipeListener() {
@Override
public void onScrollStateChange(int state, float scrollPercent) {
}
@Override
public void onEdgeTouch(int edgeFlag) {
Utils.convertActivityToTranslucent(mActivity);
}
@Override
public void onScrollOverThreshold() {
}
});
}
public void onPostCreate() {
mSwipeBackLayout.attachToActivity(mActivity);
}
public View findViewById(int id) {
if (mSwipeBackLayout != null) {
return mSwipeBackLayout.findViewById(id);
}
return null;
}
public SwipeBackLayout getSwipeBackLayout() {
return mSwipeBackLayout;
}
}
其中进行的操作:
在activity调用onCreate之后会调用这的onActivityCreated,里面主要进行的操作是初始化SwipeBackLayout,并且将window的背景置为透明,然后设置SwipeBackLayout的滑动监听;
在activity的onPostCreate中也会调用这里的onPostCreate,将activity设置给SwipeBackLayout对象的attachToActivity;
findViewById方法也是将操作进一步传递给SwipeBackLayout的对象。
(4)下面就来看看SwipeBackLayout的实现,也是整个项目的重点:
package nsu.edu.com.library;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.util.ArrayList;
import java.util.List;
public class SwipeBackLayout extends FrameLayout {
/**
* Minimum velocity that will be detected as a fling
*/
private static final int MIN_FLING_VELOCITY = 400; // dips per second
private static final int DEFAULT_SCRIM_COLOR = 0x99000000;