栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

考拉Android全局滑动返回及联动效果的实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

考拉Android全局滑动返回及联动效果的实现

}
if (mTranslucentState == INIT) {
convertActivityToTranslucent(activity, null);
} else if (mTranslucentState == CHANGE_STATE_FAIL) {
return false;
}

try {
Method method = Activity.class.getDeclaredMethod(“convertFromTranslucent”);
method.setAccessible(true);
method.invoke(activity);
mTranslucentState = CHANGE_STATE_SUCCEED;
return true;
} catch (Throwable t) {
mTranslucentState = CHANGE_STATE_FAIL;
PreferencesUtils.saveInt(TRANSLUCENT_STATE, CHANGE_STATE_FAIL);
return false;
}
}

static void convertActivityToTranslucent(Activity activity, final TranslucentListener listener) {
if (mTranslucentState == CHANGE_STATE_FAIL) {
if (listener != null) {
listener.onTranslucent();
}
return;
}

try {
Class[] classes = Activity.class.getDeclaredClasses(); Class translucentConversionListenerClazz = null;
for (Class clazz : classes) {
if (clazz.getSimpleName().contains(“TranslucentConversionListener”)) {
translucentConversionListenerClazz = clazz;
}
}

MyInvocationHandler myInvocationHandler = new MyInvocationHandler(listener);
Object obj = Proxy.newProxyInstance(Activity.class.getClassLoader(),
new Class[] { translucentConversionListenerClazz }, myInvocationHandler);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Method getActivityOptions = Activity.class.getDeclaredMethod(“getActivityOptions”);
getActivityOptions.setAccessible(true);
Object options = getActivityOptions.invoke(activity);

Method method = Activity.class.getDeclaredMethod(“convertToTranslucent”,
translucentConversionListenerClazz, ActivityOptions.class);
method.setAccessible(true);
method.invoke(activity, obj, options);
} else {
Method method =
Activity.class.getDeclaredMethod(“convertToTranslucent”, translucentConversionListenerClazz);
method.setAccessible(true);
method.invoke(activity, obj);
}
mTranslucentState = CHANGE_STATE_SUCCEED;
} catch (Throwable t) {
mTranslucentState = CHANGE_STATE_FAIL;
PreferencesUtils.saveInt(TRANSLUCENT_STATE, CHANGE_STATE_FAIL);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (listener != null) {
listener.onTranslucent();
}
}
}, 100);
}
}
}

让activity变不透明的方法比较简单;让activity变透明的方法参数里传入了一个listener接口 ,主要是当antivity变透明后会回调,因为这个接口也在activity里,而且是私有的,所以我们只能通过动态代理去获取这个回调。最后如果版本大于等于5.0,还需要再传入一个ActivityOptions参数。

在实际开发中,这两个方法在android 5.0以上是有效的,在5.0以下需要当android:windowIsTranslucent为true时才有效,这样又回到了之前的问题activity切换动画异常。

**最终决解方法:**setContentView之前就调用 convertActivityFromTranslucent方法,让activity背景变黑,这样activity切换效果就正常。

**总结:**在style中设置android:windowIsTranslucent为true ,setContentView之前就调用 convertActiv Android开源项目《ali1024.coding.net/public/P7/Android/git》 ityFromTranslucent方法,当触发右滑时调用convertActivityToTranslucent,通过动态代理获取activity变透明后的回调,在回调后允许开始滑动。

二. 让BaseActivity继承SwipeBackActivity(SwipeBackActivity讲解)

先直接看代码,比较少

public abstract class SwipeBackActivity extends CoreBaseActivity {

private SwipeBackLayout mSwipeBackLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isSwipeBackDisableForever()) {
TranslucentHelper.convertActivityFromTranslucent(this);
mSwipeBackLayout = new SwipeBackLayout(this);
}
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
if (!isSwipeBackDisableForever()) {
mSwipeBackLayout.attachToActivity(this);
mSwipeBackLayout.setOnSwipeBackListener(new SwipeBackLayout.onSwipeBackListener() {
@Override
public void onStart() {
onSwipeBackStart();
}

@Override
public void onEnd() {
onSwipeBackEnd();
}
});
}
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!isSwipeBackDisableForever() && hasFocus) {
getSwipeBackLayout().recovery();
}
}


protected void onSwipeBackStart() {}


protected void onSwipeBackEnd() {}


public void setSwipeBackEnable(boolean enable) {
if (mSwipeBackLayout != null) {
mSwipeBackLayout.setSwipeBackEnable(enable);
}
}

public boolean isSwipeBackDisableForever() {
return false;
}

public SwipeBackLayout getSwipeBackLayout() {
return mSwipeBackLayout;
}
}

SwipeBackActivity中包含了一个SwipeBackLayout对象

在onCreate方法中:
1.activity转化为不透明。
2.new了一个SwipeBackLayout。

在onPostCreate方法中:
1.attachToActivity主要是插入SwipeBackLayout、窗口背景设置……
2.设置了滑动返回开始和结束的监听接口,建议在滑动返回开始时,把PopupWindow给dismiss掉。

onWindowFocusChanged 方法中
如果是hasFocus == true,就recovery()这个SwipeBackLayout,这个也是因为下层activity有联动效果而移动了SwipeBackLayout,所以需要recovery()下,防止异常情况。

isSwipeBackDisableForever 方法是一个大开关,默认返回false,在代码中复写后返回 true,则相当于直接继承了SwipeBackActivity的父类。

setSwipeBackEnable 方法是一个小开关,设置了false之后就暂时不能滑动返回了,可以在特定的时机设置为true,就恢复滑动返回的功能。

**总结说明:**下层activity设置了setSwipeBackEnable 为 false,上层activity滑动时还是可以联动的,比如MainActivity。而isSwipeBackDisableForever 返回true就不会联动了,而且一些仿PopupWindow的activity需要复写这个方法,因为activity需要透明。

三、滑动助手类的使用和滑动返回布局类的实现(SwipeBackLayout讲解)

直接贴SwipeBackLayout源码:


private onSwipeBackListener mListener;

public SwipeBackLayout(Context context) {
super(context);
init(context);
}

public SwipeBackLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

public SwipeBackLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}

private void init(Context context) {
mViewDragHelper = SwipeBackLayoutDragHelper.create(SwipeBackLayout.this, new ViewDragCallback());
mViewDragHelper.setEdgeTrackingEnabled(SwipeBackLayoutDragHelper.EDGE_LEFT);
mViewDragHelper.setMinVelocity(MIN_FLING_VELOCITY);
mViewDragHelper.setMaxVelocity(MIN_FLING_VELOCITY * 2);
try {
mShadowDrawable = context.getResources().getDrawable(R.drawable.swipeback_shadow_left);
} catch (Exception ignored) {
}
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
try {
if (!mIsSwipeBackEnable) {
super.onLayout(changed, left, top, right, bottom);
return;
}
mIsLayout = true;
if (mContentView != null) {
mContentView.layout(mContentLeft, 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》开源 top, mContentLeft + mContentView.getMeasuredWidth(),
mContentView.getMeasuredHeight());
}
mIsLayout = false;
} catch (Exception e) {
super.onLayout(changed, left, top, right, bottom);
}
}

@Override
public void requestLayout() {
if (!mIsLayout || !mIsSwipeBackEnable) {
super.requestLayout();
}
}

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
try {
//绘制阴影
if (mContentPercent > 0
&& mShadowDrawable != null
&& child == mContentView
&& mViewDragHelper.getViewDragState() != SwipeBackLayoutDragHelper.STATE_IDLE) {
child.getHitRect(mContentViewRect);
mShadowWidth = mShadowDrawable.getIntrinsicWidth();
mShadowDrawable.setBounds(mContentViewRect.left - mShadowWidth, mContentViewRect.top,
mContentViewRect.left, mContentViewRect.bottom);
mShadowDrawable.draw(canvas);
}
return super.drawChild(canvas, child, drawingTime);
} catch (Exception e) {
return super.drawChild(canvas, child, drawingTime);
}
}

@Override
public void computeScroll() {
mContentPercent = 1 - mScrollPercent;
if (mViewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (!mIsSwipeBackEnable) {
return false;
}
try {
return mViewDragHelper.shouldInterceptTouchEvent(event);
} catch (ArrayIndexOutOfBoundsException e) {
return super.onInterceptTouchEvent(event);
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if (!mIsSwipeBackEnable) {
return false;
}
try {
mViewDragHelper.processTouchEvent(event);
return true;
} catch (Exception e) {
return super.onTouchEvent(event);

Android核心知识点

面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验。

下面这份PDF是我翻阅了差不多3个月左右一些Android大博主的博客从他们那里取其精华去其糟泊所整理出来的一些Android的核心知识点,全部都是精华中的精华,我能面试到现在2-2资深开发人员跟我整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。

不管是Android基础还是Java基础以及常见的数据结构,这些是无原则地必须要熟练掌握的,尤其是非计算机专业的同学,面试官一上来肯定是问你基础,要是基础表现不好很容易被扣上基础不扎实的帽子,常见的就那些,只要你平时认真思考过基本上面试是没太大问题的。

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。

[外链图片转存中…(img-yDKPktyf-1650452398617)]

不管是Android基础还是Java基础以及常见的数据结构,这些是无原则地必须要熟练掌握的,尤其是非计算机专业的同学,面试官一上来肯定是问你基础,要是基础表现不好很容易被扣上基础不扎实的帽子,常见的就那些,只要你平时认真思考过基本上面试是没太大问题的。

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/820411.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号