上文说到,一个单独的页面实现毛玻璃
但是目前,这种方案放在了recyclerview中,就会有性能问题了,为什么?recyclerview因为其加载数据的缓存性质,会同时加载多个view,如果所有view都在做动态毛玻璃,那性能开销可想而知。
!!!代码地址在文末!!!
环境:
1、win10 androidstudio4.4.0
2、jdk 1.8
场景:
recyclerview使用了linearlayoutmanager,pagersnaphelper分页滑动。
思路:
如果减少性能开销?有一下方法:
(一)用户滑动recyclerview的时候,暂停动态毛玻璃
(二)毛玻璃控件失去焦点的时候,暂停毛玻璃
(三)非当前页显示时,暂停毛玻璃
实现:
(一)通过定义一些对象,分别记录当前用户的滑动位置,滑动状态(滑动中,停止滑动)等。再结合毛玻璃在recyclerview中的位置,进行比对实现。核心代码如下:
if(getmAdapterPos() == LibPicBlurDragConstant.getInstance().getDragPos()){
if(LibPicBlurDragConstant.getInstance().isDrag()){
return false;
}
}
上面代码的意思就是,如果拖动位置和当前毛玻璃控件位置相等且拖动中,就暂停毛玻璃行为。
(二)失去监听的判断,通过以下代码即可捕获:
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
Log.d(TAG, "onWindowFocusChanged hasWindowFocus: " + hasWindowFocus + " mIdentify: " + mIdentify);
if (hasWindowFocus) {
setCanBlur(true);
} else {
setCanBlur(false);
}
}
(三)由于毛玻璃的位置,是通过windowlocation方法获取的,所以,只要得出离屏位置,即可得出是否在当前页面。注意!!!
调用该库中,需要自定义一个父类布局(recyclerview场景),替换为原来的Window DecoreView,因为这里涉及的是一个动态绘制显示的问题,所以要替换。核心代码如下:
离屏位置判断:
final int[] locations = new int[2];
// parentView.getLocationOnScreen(locations);
// Log.d(TAG, "checkScreenLocation " + mIdentify + " parentSc: " + locations[1] + " parentHe: " + parentView.getMeasuredHeight());
getLocationOnScreen(locations);
int childScreenHeight = locations[1];
// Log.d(TAG, "checkScreenLocation " + mIdentify + " childSc: " + locations[1] + " childHe: " + getMeasuredHeight());
//离屏位置----------------------------------------------------------
if (childScreenHeight <= 0) {
//上一页
return false;
}
if (childScreenHeight >= parentView.getMeasuredHeight()) {
return false;
}
//离屏位置----------------------------------------------------------
自定义decoreview设置:
protected View getActivityDecorView() {
if(mCusDecorView!=null){
return mCusDecorView;
}
Context ctx = getContext();
for (int i = 0; i < 4 && !(ctx instanceof Activity) && ctx instanceof ContextWrapper; i++) {
ctx = ((ContextWrapper) ctx).getBaseContext();
}
if (ctx instanceof Activity) {
return ((Activity) ctx).getWindow().getDecorView();
} else {
return null;
}
}
public void setmCusDecorView(View mCusDecorView) {
this.mCusDecorView = mCusDecorView;
}