Material Design CoordinatorLayout+AppBarLayout+Toolbar

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tony499074462/article/details/95451871

1.CoordinatorLayout 简介

CoordinatorLayout遵循Material 风格,包含在 support Library中,结合AppbarLayout, CollapsingToolbarLayout等 可 产生各种炫酷的折叠悬浮效果

它作为最上层的View
它作为一个 容器与一个或者多个子View进行交互

2.AppBarLayout

在这里插入图片描述
它是继承与LinearLayout的,默认 的 方向 是Vertical,它就是一个继承自LinearLayout的自定义vew而已,它有很多的自定义属性,最常用的就是 滑动属性 app:layout_scrollFlags

在这里插入图片描述
AppBarLayout的直接子控件可以设置的属性:layout_scrollFlags(滚动模式)
1.scroll|exitUntilCollapsed: 如果AppBarLayout的直接子控件设置该属性,该子控件可以滚动,向上滚动NestedScrollView出父布局(一般为CoordinatorLayout)时,会折叠到顶端,向下滚动时NestedScrollView必须滚动到最上面的时候才能拉出该布局

2.scroll|enterAlways:只要向下滚动该布局就会显示出来,只要向上滑动该布局就会向上收缩

3.scroll|enterAlwaysCollapsed:向下滚动NestedScrollView到最底端时该布局才会显示出来

4.scroll|snap:表示一个吸附效果,可以确保childView不会滑动停止在中间的状态

5.如果不设置该属性,则该布局不能滑动

AppBarLayout 的这些自定义属性是直接作用在它的直接子view上的,怎么理解了?

 <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
 
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
 
 
    </android.support.design.widget.AppBarLayout>

就是AppBarLayout作为父容器包裹子view Toolbar,并在Toolbar里面设置滑动属性值 app:layout_scrollFlags="scroll|enterAlways"
当然你也可以设置其它的滑动属性值看看效果

需要注意的是 AppBarLayout又必须作为CoordinatorLayout的直接子View,否则它的大部分功能将不会生效,要想产生滑动效果,则必须把屏幕填充满才可以,所以还需要用到RecyclerView才行,

并且 RecyclerView也有属性需要设置,这样才会有正常的效果

app:layout_behavior="@string/appbar_scrolling_view_behavior" 

下面我们就把他们结合起来使用看看效果

布局文件

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
 
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
 
    </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>

布局思路

在这里插入图片描述

Activity文件

public class CoordinatorLayoutActivity extends AppCompatActivity
{
    private ArrayList<String> mData;
    private RecyclerView recyclerView;
    private NormalAdapter normalAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coordinator_layout);
        intData();
        //如果不设置,则不会出现标题
        Toolbar tbAtToolbar = findViewById(R.id.tb_at_toolbar);
        //不设置会显示label的属性,也可以在清单文件中进行配置
        //tbAtToolbar.setTitle("");
        setSupportActionBar(tbAtToolbar);

        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null)
        {
            //设置Toolbar home键可点击
            actionBar.setDisplayHomeAsUpEnabled(true);
            //设置Toolbar home键图标
            //actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer_am);
        }
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(normalAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.toobalr, menu);
        return true;
    }

    private void intData()
    {
        recyclerView=findViewById(R.id.recyclerView);
        mData=new ArrayList<>();
        for (int i=0;i<100;i++)
        {
            mData.add("我是第"+i+"数据");
        }
        normalAdapter=new NormalAdapter(mData,CoordinatorLayoutActivity.this);
    }
}

注意 Toolbar 必须由 AppBarLayout 包裹才会产生滑动效果
当 滑动属性为 app:layout_scrollFlags="scroll|enterAlways"时,可以看到向上滑动 RecyclerView滑动多少距离,Toolbar就会滑动多少距离,向下滑动时,不管RecyclerView的数据是否滑动到第一行,Toolbar都会立马滑动出现

在这里插入图片描述

我们把滑动属性改为 scroll|snap 可以看到 RecyclerView滑动多少距离,Toolbar就会滑动多少距离,上下都是一样的

在这里插入图片描述

AppBarLayout 继承于LinearLayout 它可以包含任何控件,不仅仅只限于Toolbar

我们修改上面代码,让它包含一个ImageView看看效果,并为其设置滑动属性
app:layout_scrollFlags=“scroll|enterAlways”
注意必须设置滑动属性 不然ImageView它不会滑动的

修改我们的布局文件

 <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/tb_at_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimary"
            android:visibility="gone"// 隐藏Toolbar
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:gravity="center"
                android:text="我是标题"
                android:textColor="#FFFFFF" />

        </android.support.v7.widget.Toolbar>

        <ImageView android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="?attr/colorPrimary"
            android:scaleType="fitXY"
            android:src="@mipmap/tangyan"
            app:layout_scrollFlags="scroll|enterAlways"/>


    </android.support.design.widget.AppBarLayout>

在这里插入图片描述

那如果我们想要实现下面这种效果了?

在这里插入图片描述

其实相对于前 一个例子,只是把 摆放RecyclerView 的位置替换成ViewPager而已,为了有页面导航器的效果,再使用 TabLayout而已,而TabLayout 在我们滑动的时候最终会停靠在 最顶部,是因为我们没有设置其layout_scrollFlags,即TabLayout是静态的

在这里插入图片描述
在这里插入图片描述

贴上全部代码

主 布局文件

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/tb_at_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:visibility="gone"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:gravity="center"
                android:text="我是标题"
                android:textColor="#FFFFFF" />

        </android.support.v7.widget.Toolbar>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="?attr/colorPrimary"
            android:scaleType="fitXY"
            android:src="@mipmap/tangyan"
            app:layout_scrollFlags="scroll|snap" />


        <android.support.design.widget.TabLayout
            android:id="@+id/toolbar_tab"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_gravity="bottom"
            android:background="#ffffff"
            android:fillViewport="false"
            app:tabIndicatorColor="@color/colorAccent"
            app:tabIndicatorHeight="2.0dp"
            app:tabSelectedTextColor="@color/colorAccent"
            app:tabTextColor="#151515">

            <!--指示器颜色-->
            <!-- app:tabIndicatorColor="#0835f8"-->

            <!--tab条目中字体颜色-->
            <!--app:tabSelectedTextColor="#0835f8"-->

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@mipmap/v5" />
            <!--布局选择器-->
            <!--android:icon="@drawable/tab_selector"-->
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="头条" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="社交" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="直播" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="嘿嘿" />


        </android.support.design.widget.TabLayout>


    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/main_vp_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    <!--在CoordinatorLayout中只要是能滑动控件的都需要设置layout_behavior-->
    <!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->


</android.support.design.widget.CoordinatorLayout>

Activity

public class CoordinatorLayoutActivity extends AppCompatActivity
{
    private ViewPager viewPager;
    private TabLayout tabLayout;
    private ArrayList<Fragment>     fragments = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coordinator_layout);
        intData();
        //如果不设置,则不会出现标题
        Toolbar tbAtToolbar = findViewById(R.id.tb_at_toolbar);
        //不设置会显示label的属性,也可以在清单文件中进行配置
        //tbAtToolbar.setTitle("");
        setSupportActionBar(tbAtToolbar);

        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null)
        {
            //设置Toolbar home键可点击
            actionBar.setDisplayHomeAsUpEnabled(true);
            //设置Toolbar home键图标
            //actionBar.setHomeAsUpIndicator(R.drawable.ic_drawer_am);
        }

        //相互绑定,这样可以防止图标被替换
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener
                (tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener
                (viewPager));

        initFragments();

        viewPager.setAdapter(new FragmentsAdapter(getSupportFragmentManager(), fragments));
        viewPager.setOffscreenPageLimit(5);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.toobalr, menu);
        return true;
    }

    private void initFragments() {
        fragments.add(new MovieFragment());
        fragments.add(new MovieFragment());
        fragments.add(new MovieFragment());
        fragments.add(new MovieFragment());
        fragments.add(new MovieFragment());
    }

    private void intData()
    {
        tabLayout = findViewById(R.id.toolbar_tab);
        viewPager = findViewById(R.id.main_vp_container);
    }
}

FragmentsAdapter

public class FragmentsAdapter extends FragmentPagerAdapter
{

    private ArrayList<Fragment> fragments;

    String[] titles=new String[]{"","头条","社交","直播","约吗"};

    public FragmentsAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles[position];
    }
}

MovieFragment

public class MovieFragment extends Fragment
{
    private RecyclerView recyclerView;
    private NormalAdapter normalAdapter;
    private ArrayList<String> mData;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_rv, container, false);
        recyclerView=view.findViewById(R.id.rv_fr_list);
        mData=new ArrayList<>();
        for (int i=0;i<100;i++)
        {
            mData.add("我是第"+i+"数据");
        }
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        normalAdapter=new NormalAdapter(mData,getActivity());
        recyclerView.setAdapter(normalAdapter);
        return view;
    }

}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/srl_fr_refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_fr_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </android.support.v4.widget.SwipeRefreshLayout>


</LinearLayout>

NormalAdapter

public class NormalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
    private Context mContext;
    private ArrayList<String> mData;

    public NormalAdapter(ArrayList<String> mData, Context context)
    {
        this.mData = mData;
        this.mContext = context;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType)
    {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        return new RecyclerViewItemHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position)
    {
        RecyclerViewItemHolder recyclerViewHolder = (RecyclerViewItemHolder) viewHolder;
        recyclerViewHolder.tv_name.setText(mData.get(position));
    }

    @Override
    public int getItemCount()
    {
        return mData.size();
    }

    /**
     * 正常条目的item的ViewHolder
     */
    private class RecyclerViewItemHolder extends RecyclerView.ViewHolder
    {

        public TextView tv_name;

        public RecyclerViewItemHolder(View itemView)
        {
            super(itemView);
            tv_name = itemView.findViewById(R.id.tv_name);
        }
    }
}
展开阅读全文

没有更多推荐了,返回首页