CoordinatorLayout用法

本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());
    }
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值