MaterialDesign系列文章(九)AppBarLayout的使用

不怕跌倒,所以飛翔

這個控件要是講解的話我真不知道該寫點什么,就直接參考依然范特稀西的文章直接實現個簡書首頁的效果,然后簡單的講一下就好了...

簡書首頁的效果

今天就帶大家實現一下這個效果(也算是一個實踐吧)!!!

首先分析一下這個頁面效果:

  • 頂部是一個Banner
  • 中間是一個RecycleView實現的列表(橫向的那個)
  • 一個搜索的條目
  • 底部是一個RecycleView實現的列表

主要知識點:(如果你對此知識點了解的話可以掠過這篇文章了):

  • app:layout_scrollFlags這個標簽的使用;
  • app:layout_behavior 這個標簽的使用;

實現過程:

1.布局實現

首先是頁面的實現過程(這里因為主要是講MaterialDesign所以這些不是本文講述的重點,所以貼上代碼,兄弟們自己看看就行了,不懂得可以給我留言...)

布局文件
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.hejin.materialdesign.JianShuActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white">

        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            app:layout_scrollFlags="scroll"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll"/>

        <EditText
            android:id="@+id/et_search"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_margin="10dp"
            android:background="@drawable/edti_text_shape"
            android:gravity="center"
            android:hint="搜索簡述的內容和朋友"
            android:textColor="#334455"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_bottom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

這里主要用到的控件在上面都寫了,但是在這里又包含本文的重點,所以這里得著重講一下

app:layout_scrollFlags="scroll"這個標簽得作用

可選內容:

  • scroll View會跟隨滾動時間一起發生移動(想滾動就必須設置這個)
  • enterAlways 當向下移動時,立即顯示View(比如Toolbar)。
  • exitUntilCollapsed 向上滾動時收縮View,但可以固定Toolbar一直在上面。
  • enterAlwaysCollapsed 當你的View已經設置minHeight屬性又使用此標志時,你的View只能以最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。

上面這些內容你們會覺得很晦澀難懂,所以我決定花些時間說明一下

scroll 如果你想讓這個控件滾動得話就必須設置得一個屬性,比如那上面這個布局來說吧,當你在ViewPager中設置這個屬性得時候說明這個控件會隨著你得手勢進行滑動,否則它不會進行滑動,只有RecycleView能進行滑動(但是我發下一個問題,就是在AppBarLayout中如果第一個控件沒有設置這個屬性的時候,不管后面的控件是否設置這個屬性都會導致后面的控件不能進行滑動,所以這里大家注意一下!!!)

enterAlways 如果你向下滑動的時候,會先把設置這個Flag的控件先跟隨滑動顯示出來,然后在慢慢顯是底部的滑動控件,還是那上面的例子說明下:當你的ViewPager同時設置scrollenterAlways兩個屬性的話(用|分割,可以進行多個設置)每次當你向上滑動的時候會先滑動頂部的ViewPager然后在響應底部的RecycleView的滑動事件,但是當你向下滑動的時候,會先把ViewPager滑動出來,然后在響應RecycleView的滑動事件.

enterAlwaysCollapsed ** 這個屬性類似于一種折疊效果,這個屬性要enterAlwaysandroid:minHeight**一起配合使用才有效果的,還是拿上面的例子說明:當你向上滑動的時候先會在設置minHeight這段區域響應滑動,然后響應RecycleView的滑動,當向下滑動的時候,也是會先響應minHeight的滑動,然后在響應RecyceView的滑動

exitUntilCollapsed 這個屬性和上面的類似,也要設置minHeight,還是拿上面的頁面舉例,當你上滑的是偶ViewPager會先響應滑動事件,但是會停在minHeight的高度,然后RecycleView響應滑動,當你向下滑動的時候RecycleView會先響應滑動,然后ViewPager從minHeight的高度開始響應滑動.說簡單了就是屏幕上方會留一塊區域.

這里提供幾種供你嘗試一下看一下效果你就理解了:

  • app:layout_scrollFlags="scroll"
  • app:layout_scrollFlags="scroll|enterAlways"
  • app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
  • app:layout_scrollFlags="scroll|exitUntilCollapsed"
    基本上就是上面這幾種方式,試一下看一下效果就明白了!

app:layout_behavior="@string/appbar_scrolling_view_behavior"至于這個我準備后續單獨些一片文章去講解,這里只要記住只要設置了這個屬性的話,會使設置這個屬性的控件在AppBarLayout的下面,而不是在它上面(因為CoordinatorLayout是繼承ViewGroup的而不是繼承LinearLayout的)

2.一些相應的類的實現

適配器(3個):

ViewPager的適配器

lass JianShuVPAdapter extends PagerAdapter {

    private Context mContext;

    public JianShuVPAdapter(Context context) {
        mContext = context;
    }

    @Override
    public int getCount() {
        return 5;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView mIv = new ImageView(mContext);
        if (position % 2 == 0) {
            mIv.setImageResource(R.mipmap.meizhi);
        } else {
            mIv.setImageResource(R.mipmap.photo);
        }
        mIv.setScaleType(ImageView.ScaleType.CENTER_CROP);
        container.addView(mIv);
        return mIv;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }
}

RecycleView的兩個適配器

class JianShuTabRVAdapter extends RecyclerView.Adapter<JianShuTabRVAdapter.TabHolder> {

    private Context mContext;
    private LayoutInflater mInflater;

    public JianShuTabRVAdapter(Context context) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public TabHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = mInflater.inflate(R.layout.item_jianshu_tab, parent, false);
        return new TabHolder(itemView);
    }

    @Override
    public void onBindViewHolder(TabHolder holder, int position) {
        switch (position) {
            case 0:
                holder.mTvBg.setBackgroundResource(R.drawable.label_shape);
                holder.mTvBg.setText("小說精選");
                break;
            case 1:
                holder.mTvBg.setBackgroundResource(R.drawable.label_shape2);
                holder.mTvBg.setText("攝影游記");
                break;
            case 2:
                holder.mTvBg.setBackgroundResource(R.drawable.label_shape3);
                holder.mTvBg.setText("漫畫手繪");
                break;
            case 3:
                holder.mTvBg.setBackgroundResource(R.drawable.label_shape4);
                holder.mTvBg.setText("簽約作者");
                break;
            default:
                holder.mTvBg.setBackgroundResource(R.drawable.label_shape);
                holder.mTvBg.setText("你猜我猜");
                break;
        }
    }

    @Override
    public int getItemCount() {
        return 5;
    }

    class TabHolder extends RecyclerView.ViewHolder {
        private TextView mTvBg;

        public TabHolder(View itemView) {
            super(itemView);
            mTvBg = itemView.findViewById(R.id.tv_bg);
        }
    }
}
class JianShuItemRVAdapter extends RecyclerView.Adapter <JianShuItemRVAdapter.ItemTab>{

    private Context mContext;
    private LayoutInflater mInflater;

    public JianShuItemRVAdapter(Context context) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public ItemTab onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = mInflater.inflate(R.layout.item_jianshu,parent,false);
        return new ItemTab(itemView);
    }

    @Override
    public void onBindViewHolder(ItemTab holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 10;
    }


    class ItemTab extends RecyclerView.ViewHolder{
        public ItemTab(View itemView) {
            super(itemView);
        }
    }
}

主頁面

public class JianShuActivity extends AppCompatActivity {

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

        initViewPager();
        initRecycleView();
    }


    /**
     * author :  賀金龍
     * create time : 2017/11/7 10:40
     * description : 初始化ViewPager
     */
    private void initViewPager() {
        ViewPager vp = (ViewPager) findViewById(R.id.vp);
        vp.setAdapter(new JianShuVPAdapter(this));
    }

    /**
     * author :  賀金龍
     * create time : 2017/11/7 10:49
     * description : 初始化頂部和底部的RecycleView
     */
    private void initRecycleView() {
        RecyclerView rvTab = (RecyclerView) findViewById(R.id.rv_tab);
        RecyclerView rvItem = (RecyclerView) findViewById(R.id.rv_bottom);

        rvTab.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        rvTab.setAdapter(new JianShuTabRVAdapter(this));

        rvItem.setLayoutManager(new LinearLayoutManager(this));
        rvItem.setAdapter(new JianShuItemRVAdapter(this));
    }
}

2017年09月11日補充:
如果ToolBar想要聯動得話,必須要嵌套在AppBarLayout中去,否則不會有效果的(其實具體為什么我還真的不知道)!


這一系列文章的地址,希望對大家有幫助

項目地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容