CoordinatorLayout+CollapsingToolbarLayout实现仿美团外卖,京东,安居客等搜索框上推及筛选项悬停(二)

CoordinatorLayout+CollapsingToolbarLayout实现仿美团外卖,京东,安居客等搜索框上推及筛选项悬停(二)

CoordinatorLayout+CollapsingToolbarLayout实现仿美团外卖,京东,安居客等搜索框上推及筛选项悬停(二)CoordinatorLayout+CollapsingToolbarLayout实现仿美团外卖,京东,安居客等搜索框上推及筛选项悬停(二)

如图:上一篇介绍了用NestedScrollView+TabLayout+RecyclerView方案实现搜索框上推,但是是以牺牲RecyclerView的性能为代价的,因此不是一个完美的方案。本文介绍使用系统的CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+TabLayout+RecyclerView来实现相同的功能,且可以用于正式项目。

思路分析:因为CollapsingToolbarLayout本身就是折叠布局,可以折叠内容。因此我们只需要实现搜索框的上推。而上一篇搜索框的上推是通过监听NestedScrollView的垂直方向滑动距离实现的。本篇通过监听AppBarLayout的滑动距离来实现。代码几乎可以一字不改的用上一篇的的代码就能实现搜索框上推,更加的简单。由于此篇太简单了,直接上代码

实现区域折叠,直接通过CollapsingToolbarLayout就可以实现,所以直接用xml就可以了,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00000000"
        app:elevation="0dp">

        <!--  app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" snap表示必须滑动到收缩或折叠否则会自动回弹-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <LinearLayout
                android:id="@+id/top"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_marginTop="100dp"
                android:gravity="center"
                android:background="#ccc"
                app:layout_collapseMode="parallax">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="这里是顶部可以折叠的内容区域"
                    android:textSize="16sp" />
            </LinearLayout>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="0dp"
                app:contentInsetEnd="0dp"
                app:contentInsetLeft="0dp"
                app:contentInsetStart="0dp"
                app:layout_collapseMode="pin"
                android:background="#fff"
                app:titleMargin="0dp">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <LinearLayout
                        android:id="@+id/title_bar"
                        android:layout_width="match_parent"
                        android:layout_height="50dp"
                        android:gravity="center_vertical">
                        <TextView
                            android:id="@+id/city_tv"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginStart="16dp"
                            android:layout_marginLeft="16dp"
                            android:layout_marginEnd="16dp"
                            android:drawablePadding="16dp"
                            android:text="重庆"
                            android:textStyle="bold" />

                        <View
                            android:id="@+id/mainTitle"
                            android:layout_width="0dp"
                            android:layout_height="35dp"
                            android:layout_weight="1"/>

                        <TextView
                            android:id="@+id/map_iv"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginStart="16dp"
                            android:layout_marginLeft="16dp"
                            android:paddingRight="16dp"
                            android:text="展开"
                            android:textStyle="bold" />
                    </LinearLayout>
                    <LinearLayout
                        android:id="@+id/search_lin"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:layout_marginLeft="16dp"
                        android:layout_marginRight="16dp"
                        android:layout_marginTop="50dp"
                        android:layout_marginBottom="10dp"
                        android:background="@drawable/main_search_bg"
                        android:layout_alignParentLeft="true">
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginLeft="18dp"
                            android:paddingTop="8dp"
                            android:paddingBottom="8dp"
                            android:text="找好铺"
                            android:textColor="#AFB4B9"
                            android:singleLine="true"
                            android:ellipsize="end" />
                    </LinearLayout>
                </RelativeLayout>
            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout_real"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ff0000"
            app:tabIndicatorColor="@color/colorPrimary"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="@color/colorPrimary" />
    </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>

收缩框上推,直接使用上一篇的代码,不清楚的可以看上一篇。这里只需要注意初始化搜索框的位置一定要等appbar绘制完成后, 否则获取的初始值会是0,即 appbar.post必不可少。

package com.tabscroll;

import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CoodActivity extends AppCompatActivity {

    protected LinearLayout top;
    protected TextView cityTv;
    protected View mainTitle;
    protected TextView mapIv;
    protected LinearLayout titleBar;
    protected LinearLayout searchLin;
    protected Toolbar toolbar;
    protected TabLayout tablayoutReal;
    protected AppBarLayout appbar;
    protected RecyclerView recyclerView;
    protected CoordinatorLayout coordinator;

    private LinearLayoutManager manager;
    private String[] tabTxt = {"客厅", "卧室", "餐厅", "书房", "阳台", "儿童房"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_cood);
        initView();
    }

    private void initView() {
        top = (LinearLayout) findViewById(R.id.top);
        cityTv = (TextView) findViewById(R.id.city_tv);
        mainTitle = (View) findViewById(R.id.mainTitle);
        mapIv = (TextView) findViewById(R.id.map_iv);
        titleBar = (LinearLayout) findViewById(R.id.title_bar);
        searchLin = (LinearLayout) findViewById(R.id.search_lin);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        tablayoutReal = (TabLayout) findViewById(R.id.tablayout_real);
        appbar = (AppBarLayout) findViewById(R.id.appbar);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        coordinator = (CoordinatorLayout) findViewById(R.id.coordinator);

        for (int i = 0; i < tabTxt.length; i++) {
            tablayoutReal.addTab(tablayoutReal.newTab().setText(tabTxt[i]));
        }

        manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);
        recyclerView.setAdapter(new MyAdapter(this, tabTxt, 0));

        appbar.post(new Runnable() {
            @Override
            public void run() {
                translate();
            }
        });

        mapIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                recyclerView.smoothScrollToPosition(0);
                appbar.setExpanded(true);
            }
        });

    }

    private void translate() {
        appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {

            private ViewGroup.MarginLayoutParams searchLayoutParams = (ViewGroup.MarginLayoutParams) searchLin.getLayoutParams();
            private float searchLayoutNewTopMargin = 0f;
            private float searchLayoutNewLeftMargin = 0f;
            private float searchLayoutNewWidth = 0f;
            private float alpha = 0f;
            private float MIN_TOP_MARGIN = mainTitle.getTop();
            private float MAX_TOP_MARGIN = titleBar.getBottom();
            private float MAX_WIDTH = searchLin.getWidth();
            private float MIN_WIDTH = getScreenWidth() - cityTv.getRight() - 		 mapIv.getWidth() - dp2px(CoodActivity.this,16) * 2;
            private float MIN_LEFT_MARGIN = searchLin.getLeft();
            private float MAX_LEFT_MARGIN = cityTv.getRight() +  dp2px(CoodActivity.this,16) ;
            private float mDy;

            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

                mDy = -verticalOffset;
                searchLayoutNewTopMargin = MAX_TOP_MARGIN - mDy * 0.5f;
                if (searchLayoutNewTopMargin < MIN_TOP_MARGIN) {
                    searchLayoutNewTopMargin = MIN_TOP_MARGIN;
                }
                if (searchLayoutNewTopMargin > MAX_TOP_MARGIN) {
                    searchLayoutNewTopMargin = MAX_TOP_MARGIN;
                }
                searchLayoutNewLeftMargin = MIN_LEFT_MARGIN + mDy * 0.5f;
                if (searchLayoutNewLeftMargin > MAX_LEFT_MARGIN) {
                    searchLayoutNewLeftMargin = MAX_LEFT_MARGIN;
                }
                if (searchLayoutNewLeftMargin < MIN_LEFT_MARGIN) {
                    searchLayoutNewLeftMargin = MIN_LEFT_MARGIN;
                }

                searchLayoutNewWidth = MAX_WIDTH - mDy * 1.0f;
                if (searchLayoutNewWidth < MIN_WIDTH) {
                    searchLayoutNewWidth = MIN_WIDTH;
                }
                if (searchLayoutNewWidth > MAX_WIDTH) {
                    searchLayoutNewWidth = MAX_WIDTH;
                }
                searchLayoutParams.topMargin = (int) searchLayoutNewTopMargin;
                searchLayoutParams.leftMargin = (int) searchLayoutNewLeftMargin;
                searchLayoutParams.width = (int) searchLayoutNewWidth;
                searchLin.setLayoutParams(searchLayoutParams);
            }
        });
    }

    public  int dp2px(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, context.getResources().getDisplayMetrics());
    }

    public  int getScreenWidth() {
        WindowManager wm = (WindowManager) CoodActivity.this.getApplication().getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) return -1;
        Point point = new Point();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            wm.getDefaultDisplay().getRealSize(point);
        } else {
            wm.getDefaultDisplay().getSize(point);
        }
        return point.x;
    }



}

源码下载:https://download.csdn.net/download/hzmming2008/15433788

上一篇:java文件进行打包生成jar脚本


下一篇:微信网页授权