这里真正的问题是如何在应用栏高度改变时正确调整
RelativeLayout
的大小。在查看如何做到这一点之前,我们需要对XML布局进行更改。
来自
AppBarLayout文档:
AppBarLayout还需要一个单独的可滚动兄弟,以便知道何时滚动。
由于
RelativeLayout
不符合“可滚动兄弟”的条件,因此我们需要将其包含在一个诸如“NestedScrollView”之类的兄弟中。以下是更新后的XML文件:
activity_main.xml
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayoutProfile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="220dp"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="The text on the top"
android:textSize="32sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="The text on the bottom"
android:textSize="32sp" />
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
我可能对XML进行了一些其他更改,以使其在我的环境中正常工作,但除了插入
NestedScrollView
之外,不应有任何实质性的更改。
RelativeLayout
的大小更改将在代码中设置,并由
AppBarLayout.OnOffsetChangedListener触发。我们将根据应用程序栏的垂直偏移量计算并更改
RelativeLayout
的大小。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RelativeLayout mRelativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRelativeLayout = findViewById(R.id.relativeLayout);
final AppBarLayout appBarLayout = findViewById(R.id.appBar);
final int screenHeight = getResources().getDisplayMetrics().heightPixels;
appBarLayout.post(new Runnable() {
@Override
public void run() {
adjustRelLayoutHeight(mRelativeLayout, screenHeight - appBarLayout.getBottom());
}
});
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
adjustRelLayoutHeight(mRelativeLayout, screenHeight - appBarLayout.getBottom());
}
});
}
private void adjustRelLayoutHeight(RelativeLayout layout, int newHeight) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) layout.getLayoutParams();
lp.height = newHeight;
layout.setLayoutParams(lp);
}
private static final String TAG = "MainActivity";
}
这里是结果:
![enter image description here](https://istack.dev59.com/T6bQt.gif)
更新:以下是另一种方法,使用ViewTreeObserver.OnPreDrawListener()
,避免了额外的绘制。然而,效果是相同的:
MainActivity.java(另一种方法)
public class MainActivity extends AppCompatActivity {
private RelativeLayout mRelativeLayout;
private int mCoordinatorHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRelativeLayout = findViewById(R.id.relativeLayout);
final AppBarLayout appBarLayout = findViewById(R.id.appBar);
final CoordinatorLayout coordinatorLayout =
(CoordinatorLayout) findViewById(R.id.coordinatorLayoutProfile);
coordinatorLayout.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
coordinatorLayout.getViewTreeObserver().removeOnPreDrawListener(this);
mCoordinatorHeight = coordinatorLayout.getHeight();
adjustRelLayoutHeight(mRelativeLayout, mCoordinatorHeight - appBarLayout.getBottom());
return false;
}
});
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
adjustRelLayoutHeight(mRelativeLayout, mCoordinatorHeight - appBarLayout.getBottom());
}
});
}
private void adjustRelLayoutHeight(RelativeLayout layout, int newHeight) {
if (newHeight <= 0) {
return;
}
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) layout.getLayoutParams();
if (lp.height != newHeight) {
lp.height = newHeight;
layout.setLayoutParams(lp);
}
}
private static final String TAG = "MainActivity";
}