学习区程序@IT·互联网

AppBarLayout 有毒,我有一粒解药,要不?(修改))

2016-08-26  本文已影响2878人  岁月留痕

以前将这篇稿子发到专题 《Android 开发经验谈》 和 《Android 开发知识》的时候,过了很久,《Android开发知识》审核没通过,《Android开发经验谈》被我自己撤回了。开始没明白原因,重新重新读了下文章,果然有问题,所以重新修改下。

上一次的错误

第一次发稿的时候,错误的将问题指向了view的高度,重新测试发现,当控件为隐藏的时候,高度为0,问题在margin高度

Paste_Image.png

问题:tabLayout会距离上面负几个dp

111.gif
怀疑:fitSystemWindow 设置的问题

求证:将顶部的元素节点的fitSystemWindow设置为true和false都没有效果,并且距离顶部负的地方在tabLayout显示动态一栏的前面,(开始没想到这点)

定位问题:元素是否滚动是由appBarLayout控制

求证:查看appBarLayout 代码,很容易就发现一段计算滚动范围的代码

/** * Returns the scroll range of all children. 
* * @return the scroll range in px */
public final int getTotalScrollRange() {  
  if (mTotalScrollRange != INVALID_SCROLL_RANGE) {   
     return mTotalScrollRange;  
  }   
 int range = 0;   
 for (int i = 0, z = getChildCount(); i < z; i++) {   
     final View child = getChildAt(i);   
     final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 
     final int childHeight = child.getMeasuredHeight();    
     final int flags = lp.mScrollFlags;   
     if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) {       
     // We're set to scroll so add the child's height    
        range += childHeight + lp.topMargin + lp.bottomMargin;   
         if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {        
        // For a collapsing scroll, we to take the collapsed height into account.      
          // We also break straight away since later views can't scroll beneath       
         // us        
        range -= ViewCompat.getMinimumHeight(child);      
          break;        
      }    
    } else {      
      // As soon as a view doesn't have the scroll flag, we end the range calculation.      
      // This is because views below can not scroll under a fixed view.            break;   
     }   
 }    
  return mTotalScrollRange = Math.max(0, range - getTopInset());
}

简单的翻译下:判断当前滚动范围是否=-1,如果是开始往下执行,遍历子元素,获取子元素的高度,判断该元素是否可以滚动,如果可以滚动加上该元素的高度和距离顶部以及底部的高度,如果子元素设置了exitUntilCollapsed,则减去该元素的最小高度。如果没有设置Scroll 则什么都不做

寻找解决方案

我的tab 栏上面的一个元素的确设置了滚动,还设置了距离顶部和底部的Margin,用模拟器debug 到这行发现代码没有判断是否隐藏,并且将margin值加到了range 中,
<code>
childHeight = 0;
lp.topMargin = 39
lp.bottomMargin = 42
</code>
问题就是应该就是margin惹得祸,将margin去掉后,果然好了,另外一种方法,在view上再嵌套一个父元素,在计算高度的时候,没计算子孙元素的margin

代码

为了让大家直观的看到这个错误,这里将问题代码简化后贴出

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    tools:context="wdwd.com.behave.MainActivity">
    <!--toolbar--> 
   <android.support.design.widget.AppBarLayout 
       android:layout_width="match_parent"
        android:layout_height="wrap_content"> 
       <android.support.v7.widget.Toolbar
            android:layout_width="match_parent" 
           android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways" 
           android:id="@+id/toolbar" /> 
       <TextView   
         android:id="@+id/tv_problem_view"
            android:layout_width="match_parent"
            android:background="@android:color/black" 
           app:layout_scrollFlags="scroll" 
           android:layout_marginBottom="10dip"
            android:layout_marginTop="40dip" 
           android:layout_height="wrap_content"  
          android:text="我是好人"   
         android:visibility="visible">  
      </TextView>    
    <TextView     
       android:layout_width="match_parent"  
          android:layout_height="41dip"
            android:text="alsdjfalksdfj"/>
    </android.support.design.widget.AppBarLayout>
 </android.support.design.widget.CoordinatorLayout>

大家可以试试将tv_problem_view设置为隐藏看看,本来底部停靠的文本还能往上滚动。

其他一些坑

CoordinaLayout的坑还么完,如果直接加Pulltorefresh 的话会出现拉一半就刷新的问题,这个问题网上能搜到解决方案,监听appbarLayoutOffsetChange事件。

coordinatorLayout 的子scrollview必须实现NestedChild,实际使用中发现在部分手机上有问题,结果全换成了recyclerview,webview网上找了段代码,虽然能嵌套滑动,但是没惯性,时间有限没深入研究,希望有知道的同学分享,大家一起进步。

这里捎带提下md的tablayout,因为这期也用到了,md的tablayout很强大,强大在哪里,支持固定宽度,通俗讲显示一屏,加权重,也支持scrollable,超出屏幕滑动,但是用过的肯定知道tablayout不定自定义下面指示器的 红色部分的宽度,我用的是简书里的hackware 大神写的magiclayout。

上一篇下一篇

猜你喜欢

热点阅读