一:把折叠效果换成只有滑动到服务顶部再下滑才让顶部分类显示出来
mRecyclerView.getLocationOnScreen(location); Logger.e("onScrollStateChanged----------------》Screen x is " + location[0] + " Screen y is " + location[1]); if (location[1] == COMPLETELY_STRETCH_HEIGHT) { mRefreshLayout.setPullDownRefreshEnable(true); } else { mRefreshLayout.setPullDownRefreshEnable(false); }
二:优化要求:在快速滑动时(不是手一拖一拖的那种,而是手指离开后的滑动,即SCROLL_STATE_SETTLING)不加载图片,停下来才加载
解决办法:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); //方案一:滑动时(指SCROLL_STATE_SETTLING状态下)暂停in progress的加载否则恢复加载, // Glide不支持暂停或恢复单个request的加载要么暂停所有,要么恢复所有 if (newState == RecyclerView.SCROLL_STATE_SETTLING) { requestManager.pauseRequests(); } else { requestManager.resumeRequests();//恢复加载时会加载R个item(R为用来复用的item个数) } //方案二:每次不滑动时只加载屏幕可见的item 比方案一更省流量, // 假设一屏容纳V个item,那么每次停下时少加载R-V个item图片 if (newState == RecyclerView.SCROLL_STATE_IDLE || newState == RecyclerView.SCROLL_STATE_DRAGGING) { loadVisibleItemImage(); }
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); Logger.e("onScrolled---------------->"); //下面为方案二所需代码 lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition(); firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
private void loadVisibleItemImage() { for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; i++) { ServiceView serviceView = (ServiceView) mRecyclerView.findViewWithTag(i);//onBindViewHolder里面进行的setTag if (serviceView != null) serviceView.setCover(); // Logger.e("current serviceView is " + serviceView); } }
方案一中之所以滑动时停止所有加载,停下来后恢复加载可以节省流量(这里加载完所有图的所需总流量没变,是指快速滑动到某位置前不会加载从而消耗没必要的流量),是因为停下来后,加载的最多也就N个item(N为用于复用的原始item个数)
而滑动时加载虽然加载的对象也是那N个,但是那N个是在不停加载的,只不过不停切换Url而已(网速好的情况下基本下滑的同时对应position的图已加载好),所以消耗的流量很大。
对于已加载好但滑过去了然后滑回来发现会有重新“加载”现象:即由先展示默认placeholder然后再变成应有的图片,这其实重新加载是必然的因为view是复用的(不信看微信朋友圈也有),之所以修改前不明显,那是因为之前滑动时可以加载,而且此时滑回去加载的是缓存所以速度极快,几乎看不到,而修改后滑动时不可加载,所以滑动时看到的是默认图片,只有停下来才开始加载缓存,这也是为何滑回去的话,虽然看似再次加载,却不耗流量的!!!!!!!(流量监测app可证明)
主页耗流量原因:之前人写的代码设置头像时上传的url就是原始图,而不是小图,所以主页头像是原始图,另外普通动态图虽然是显示的压缩图,但是相比微信我们的压缩图还很大,加之之前滑动时仍然加载,所以不断滑动翻页结果就发现流量飞跑!!!!!!!!!!!!!!!!!
1.获取View在屏幕中的位置使用view.getLocationOnScreen()或者getLocationInWindow()
2.对于可滑动的View(RecyclerView ,ListView,ScrollView),如果设置了滑动监听,那么初始化显示时会回调onScrolled(),不过不会回调onScrollStateChanged().不过前提是
其其自身宽/高要大于屏幕,否则即使用手去拖动onScrolled()也不会回调,即只有它能真正滑动时onScrolled()才会回调,不过它不能滑动时如果用手去拖还是会回调onScrollStateChanged()而且还会监听到完整的三种状态:DRAG,SETTLING,IDLE.(不过要注意拖动方向必须是由其头部指向尾部方向)
3.使用recyclerView.canScrollVertically(1/-1) canScrollHorizontally(1/-1)来判断RecyclerView是否滑动到底部/顶部
RecyclerView.canScrollVertically(1)的值表示是否能向上滚动,false表示已经滚动到底部
RecyclerView.canScrollVertically(-1)的值表示是否能向下滚动,false表示已经滚动到顶部
4.View的Visibility (VISIBILE,INVISIBILE,GONE) :View.getVisibility ==VISIBILE时并不一定 view对用户可见,例如:本次项目中放在CoordinateLayout中的顶部分类的RecyclerView 随着上滑退出屏幕后此时判断其Visibility仍然是VISIBILE。正如其语义——可见性,当为VISIBILE时只说明是可以被看见的,但是有时候可能被遮挡!
mContentView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { Rect rect = new Rect(); boolean isShown =mCategoryList.getGlobalVisibleRect(rect); // Logger.e("content view onScrollChanged width is "+isShown+mCategoryList.getMeasuredWidth()+"\nheight is "+mCategoryList.getMeasuredHeight()+"\n rect width is "+rect.width()+"\n rect height is"+rect.height()); if(isShown){ EventBus.getDefault().post("1"); }else { EventBus.getDefault().post("0"); } } }); // mContentView.setOnScrollChangeListener(new View.OnScrollChangeListener() { // @Override // public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { // Logger.e("content view onScrollChanged"); // } // });
@Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); // if(visibility==View.VISIBLE){ // Logger.e("onWindowVisibilityChanged-------->可见"+this); // }else if(visibility == INVISIBLE || visibility==GONE){ // Logger.e("onWindowVisibilityChanged-------->不可见"+this); // } }