美文网首页
协调者布局CoordinatorLayout应用(2)

协调者布局CoordinatorLayout应用(2)

作者: 俗人浮生 | 来源:发表于2019-03-13 21:04 被阅读0次

    玩过地图的都知道,有这么一个场景,搜索某些地点,然后界面上半部分是地图,下半部分是列表,然后还可以滑动,大概也就这样子,今天我们就用协调者布局来实现这一功能,效果是这样子的:

    协调者布局应用
    其实,这个需求并不难实现,特别是有了前面的协调者布局应用(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时,如何让其折叠了一半呢,这也是笔者花的时间较多的地方,方法肯定是用代码控制,但过程还是遇到不少问题,具体详见代码注释吧。

    相关文章

      网友评论

          本文标题:协调者布局CoordinatorLayout应用(2)

          本文链接:https://www.haomeiwen.com/subject/wskxmqtx.html