玩过地图的都知道,有这么一个场景,搜索某些地点,然后界面上半部分是地图,下半部分是列表,然后还可以滑动,大概也就这样子,今天我们就用协调者布局来实现这一功能,效果是这样子的:
其实,这个需求并不难实现,特别是有了前面的协调者布局应用(1),我们可以在那基础上做些修改,还是直接上布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.activity.demo.MyCoordinatorActivity2">
<include layout="@layout/layout_base_item_header1"/>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@color/colorPrimary">
<LinearLayout
android:id="@+id/headLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_scrollFlags="scroll"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/want_go_item_text_red_color"/>
</LinearLayout>
<TextView
android:id="@+id/openTV"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="@dimen/tabHeight"
android:gravity="center"
android:background="@color/white"
android:textSize="16sp"
android:layout_gravity="bottom"
android:textColor="@color/THEME_BLUE"
android:text="点击展开"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="@dimen/tabHeight"
android:background="@color/color_white"
app:tabSelectedTextColor="@color/THEME_BLUE">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
基本上与前一篇的布局类似,不同的是要实现头部完全展开(地图嘛),所以AppBarLayout我们不再设定固定高度,而是用match_parent,其它没什么好说的,接下来我们上代码:
public class MyCoordinatorActivity2 extends BaseActivity {
@BindView(R.id.openTV)
TextView openTV;
@BindView(R.id.tabLayout)
TabLayout tabLayout;
@BindView(R.id.appBarLayout)
AppBarLayout appBarLayout;
@BindView(R.id.recyclerview)
RecyclerView recyclerview;
private boolean isFirst = true;
private int middleDistance;
private AppBarLayout.Behavior appBarLayoutBehavior;
@Override
protected int attachLayoutRes() {
return R.layout.activity_my_coordinator2;
}
@Override
protected void initViews() {
setPageTitle("协调者布局");
setBackIV();
List<String> stringList = new ArrayList<>();
for (int i = 0; i < 32; i++) {
if (i <= 8) {
tabLayout.addTab(tabLayout.newTab());
tabLayout.getTabAt(i).setText("tab" + i);
}
stringList.add(String.valueOf(i));
}
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerview.setLayoutManager(linearLayoutManager);
recyclerview.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
MyDemoAdapter myDemoAdapter = new MyDemoAdapter(android.R.layout.simple_list_item_1, stringList);
recyclerview.setAdapter(myDemoAdapter);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//该方法在初始化appBarLayout绘制过程会调用两次,需根据焦点进行区分
if (isFirst) {
if (appBarLayout.hasWindowFocus()) {
//只有当appBarLayout绘制完毕且获取到焦点后调用该代码才能生效
//设置滑动到中间位置
middleDistance = -appBarLayout.getTotalScrollRange() / 2;
//appBarLayout.offsetTopAndBottom(middleDistance);在这里用这个方法可以,但在外部不行
CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior();
appBarLayoutBehavior = (AppBarLayout.Behavior) behavior;
appBarLayoutBehavior.setTopAndBottomOffset(middleDistance);//设置滑动到中间位置
isFirst = false;
}
} else {
//非初始化滑动才进行可见与不可见的切换
if (verticalOffset == 0) {
openTV.setVisibility(View.VISIBLE);
tabLayout.setVisibility(View.GONE);
} else {
openTV.setVisibility(View.GONE);
tabLayout.setVisibility(View.VISIBLE);
}
}
LogUtil.loge("距离:" + verticalOffset + "," + appBarLayout.hasWindowFocus() + "," + isFirst);
/*CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior();
AppBarLayout.Behavior appBarLayoutBehavior = (AppBarLayout.Behavior) behavior;
appBarLayoutBehavior.setTopAndBottomOffset(-400);*/
//appBarLayoutBehavior.onNestedPreScroll(coordinatorLayout,appBarLayout,recyclerview,0,100,new int[]{0,0},ViewCompat.TYPE_TOUCH);
}
});
}
@Override
protected void updateViews(boolean isRefresh) {
}
@OnClick(R.id.openTV)
public void onViewClicked() {
appBarLayoutBehavior.setTopAndBottomOffset(middleDistance);//设置滑动到中间位置
openTV.setVisibility(View.GONE);
tabLayout.setVisibility(View.VISIBLE);
}
}
其实该需求的难点在于,上面说了AppBarLayout的高度设置为match_parent,那么进入该activity时,如何让其折叠了一半呢,这也是笔者花的时间较多的地方,方法肯定是用代码控制,但过程还是遇到不少问题,具体详见代码注释吧。
网友评论