CoordinatorLayout用法

来源:互联网 发布:淘宝花呗开通条件 编辑:程序博客网 时间:2024/05/22 21:56

本Demo链接:http://download.csdn.net/download/g_ying_jie/10123364

先谈下我遇到的需求;fragment中装载viewpager、title标题栏、滑动导航栏,以及DrawerLayout;现在需要各自的滑动互不干扰,上滑隐藏title下滑呼出title。


一、fragment页面的xml布局

<android.support.v4.widget.DrawerLayout 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.CoordinatorLayout        android:id="@+id/coordinator_layout"        android:layout_width="match_parent"        android:layout_height="match_parent">        <android.support.design.widget.AppBarLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:fitsSystemWindows="true">            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:background="#30469b"                android:gravity="center"                android:text="书刊"                android:textColor="#ffffff"

app:layout_scrollFlags="scroll|enterAlways" />

<android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#30469b" app:tabGravity="fill" app:tabMode="fixed" app:tabSelectedTextColor="#ff0000" app:tabTextColor="#ffffff" /> </android.support.design.widget.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:scrollbars="none"

app:layout_behavior="@string/appbar_scrolling_view_behavior">

<android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> </android.support.design.widget.CoordinatorLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="heheh"/></android.support.v4.widget.DrawerLayout>
@注意很多案例的演示,标题栏都是使用的toolbar,但是不要被误导了,上滑隐藏不是toolbar实现的。是靠CoordinatorLayout监控子View的滑动通知给需要隐藏或显示的view,因此对应的behavior标注很重要不可出错

二、另一种更为复杂的布局,仿微云的效果,第一层是tablayout滑动导航,其中文档fragment包含一个搜索框和一个RadioGroup的点击导航。上滑隐藏搜索框,左右滑动切换tablayout,点击响应RadioGroup导航。这里还会出现tablayout来回滑动导致RadioGroup的子Fragment重复添加应用崩溃的问题,后面会谈到解决方法。


文档fragment页面的布局

<?xml version="1.0" encoding="utf-8"?><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/coordinator_layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:focusable="true"    android:focusableInTouchMode="true"    android:orientation="vertical">    <android.support.design.widget.AppBarLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@color/white"        android:fitsSystemWindows="true">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginBottom="15dp"            android:layout_marginLeft="12dp"            android:layout_marginRight="18dp"            android:orientation="horizontal"

app:layout_scrollFlags="scroll|enterAlways">

<EditText android:id="@+id/et" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" android:background="@drawable/bg_search" android:drawableLeft="@mipmap/search" android:drawablePadding="8dp" android:hint="请输入查询名称" android:imeOptions="actionSearch" android:inputType="text" android:padding="6dp" android:singleLine="true" android:textColorHint="@color/text_grey" /> <ImageView android:id="@+id/img_filter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:src="@mipmap/icon_sort" /> </LinearLayout> <RadioGroup android:id="@+id/rg" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" android:layout_marginLeft="40dp" android:layout_marginRight="40dp" android:background="@drawable/bg_recode_circle" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_all" style="@style/RadioButtonStyle" android:text="全部" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/stroke_grey" /> <RadioButton android:id="@+id/rb_doc" style="@style/RadioButtonStyle" android:text="DOC" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/stroke_grey" /> <RadioButton android:id="@+id/rb_xls" style="@style/RadioButtonStyle" android:text="XLS" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/stroke_grey" /> <RadioButton android:id="@+id/rb_ppt" style="@style/RadioButtonStyle" android:text="PPT" /> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="@color/stroke_grey" /> <RadioButton android:id="@+id/rb_pdf" style="@style/RadioButtonStyle" android:text="PDF" /> </RadioGroup> </android.support.design.widget.AppBarLayout> <FrameLayout android:id="@+id/main_fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/rg_foot"

app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

如上所示上滑隐藏下滑呼出效果已经实现,唯一要注意的是:

很多案例中负责滑动的子view都是recycleview,基本没有出现listview或者GridView的身影,原因就在于listview或者GridView的不具备recycleView的某些属性,不能够唤起父布局CoordinatorLayout去通知某个View做隐藏或者显示的动作。那么这一问题这么解决呢?Google提供了一个专门的属性去通知CoordinatorLayout子View的滑动状态。

android:nestedScrollingEnabled="true"       ------有些许遗憾的是该属性要求api 21以上也就是安卓5.0,否则无法生效。当然你可以用recycleview来替代。


现在探讨另一个问题:tablayout来回滑动导致fragment重复加载应用崩溃的问题。

有关viewpagerAdapter的缓存机制:http://blog.csdn.net/android_cyw/article/details/54632112 ;讲解的很细致,不甚了解的可以去看看

我们都知道tablayout大多是结合viewpager实现滑动导航,而viewpager的fragmentpageradapter(适用于viewpager装载fragment的情况)会缓存fragment,来回滑动fragment调用attach方法绘制视图导致内部报裹的fragment重新添加,但是缓存导致没有执行onDestroy和onDetach方法,重新add就会导致重复添加子fragment导致应用崩溃。下面通过改造适配器解决这一问题,该适配器还能解决viewpager来回滑动可能出现的fragment空白页的问题(当然使用FragmentPagerStateAdapter替换fragmentpageradapter应该也是可行的,但是缓存效果就没有了)

package com.dcg.explore.adapter;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.app.FragmentTransaction;import android.support.v4.view.PagerAdapter;import android.view.View;import android.view.ViewGroup;public class BooksVPAdapter extends PagerAdapter {    private Fragment[] fragments;    private FragmentManager fm;    public BooksVPAdapter(FragmentManager fm, Fragment[] fragments) {        this.fm = fm;        this.fragments = fragments;    }    @Override    public int getCount() {        return fragments == null ? 0 : fragments.length;    }    @Override    public boolean isViewFromObject(View view, Object object) {        return view == object;    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        Fragment fragment = fragments[position];        if (!fragment.isAdded()) {            FragmentTransaction ft = fm.beginTransaction();            ft.add(fragment, fragment.getClass().getName());            ft.commitAllowingStateLoss();            fm.executePendingTransactions();        }        View view = fragment.getView();        if (view != null && view.getParent() == null) {            container.addView(view);        }        return view;    }    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        container.removeView(fragments[position].getView());    }}