以前將這篇稿子發(fā)到專題 《Android 開發(fā)經(jīng)驗(yàn)談》 和 《Android 開發(fā)知識(shí)》的時(shí)候,過了很久,《Android開發(fā)知識(shí)》審核沒通過,《Android開發(fā)經(jīng)驗(yàn)談》被我自己撤回了。開始沒明白原因,重新重新讀了下文章,果然有問題,所以重新修改下。
上一次的錯(cuò)誤
第一次發(fā)稿的時(shí)候,錯(cuò)誤的將問題指向了view的高度,重新測(cè)試發(fā)現(xiàn),當(dāng)控件為隱藏的時(shí)候,高度為0,問題在margin高度

問題:tabLayout會(huì)距離上面負(fù)幾個(gè)dp

懷疑:fitSystemWindow 設(shè)置的問題
求證:將頂部的元素節(jié)點(diǎn)的fitSystemWindow設(shè)置為true和false都沒有效果,并且距離頂部負(fù)的地方在tabLayout顯示動(dòng)態(tài)一欄的前面,(開始沒想到這點(diǎn))
定位問題:元素是否滾動(dòng)是由appBarLayout控制
求證:查看appBarLayout 代碼,很容易就發(fā)現(xiàn)一段計(jì)算滾動(dòng)范圍的代碼
/** * 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());
}
簡單的翻譯下:判斷當(dāng)前滾動(dòng)范圍是否=-1,如果是開始往下執(zhí)行,遍歷子元素,獲取子元素的高度,判斷該元素是否可以滾動(dòng),如果可以滾動(dòng)加上該元素的高度和距離頂部以及底部的高度,如果子元素設(shè)置了exitUntilCollapsed,則減去該元素的最小高度。如果沒有設(shè)置Scroll 則什么都不做
尋找解決方案
我的tab 欄上面的一個(gè)元素的確設(shè)置了滾動(dòng),還設(shè)置了距離頂部和底部的Margin,用模擬器debug 到這行發(fā)現(xiàn)代碼沒有判斷是否隱藏,并且將margin值加到了range 中,
<code>
childHeight = 0;
lp.topMargin = 39
lp.bottomMargin = 42
</code>
問題就是應(yīng)該就是margin惹得禍,將margin去掉后,果然好了,另外一種方法,在view上再嵌套一個(gè)父元素,在計(jì)算高度的時(shí)候,沒計(jì)算子孫元素的margin
代碼
為了讓大家直觀的看到這個(gè)錯(cuò)誤,這里將問題代碼簡化后貼出
<?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設(shè)置為隱藏看看,本來底部停靠的文本還能往上滾動(dòng)。
其他一些坑
CoordinaLayout的坑還么完,如果直接加Pulltorefresh 的話會(huì)出現(xiàn)拉一半就刷新的問題,這個(gè)問題網(wǎng)上能搜到解決方案,監(jiān)聽appbarLayoutOffsetChange事件。
coordinatorLayout 的子scrollview必須實(shí)現(xiàn)NestedChild,實(shí)際使用中發(fā)現(xiàn)在部分手機(jī)上有問題,結(jié)果全換成了recyclerview,webview網(wǎng)上找了段代碼,雖然能嵌套滑動(dòng),但是沒慣性,時(shí)間有限沒深入研究,希望有知道的同學(xué)分享,大家一起進(jìn)步。
這里捎帶提下md的tablayout,因?yàn)檫@期也用到了,md的tablayout很強(qiáng)大,強(qiáng)大在哪里,支持固定寬度,通俗講顯示一屏,加權(quán)重,也支持scrollable,超出屏幕滑動(dòng),但是用過的肯定知道tablayout不定自定義下面指示器的 紅色部分的寬度,我用的是簡書里的hackware 大神寫的magiclayout。