Design Support Library控件的簡(jiǎn)單使用

Material Design

是由Google推出的全新的設(shè)計(jì)語言憎兽,谷歌表示撑蚌,這種設(shè)計(jì)語言旨在為手機(jī)麦撵、平板電腦刽肠、臺(tái)式機(jī)和“其他平臺(tái)”提供更一致溃肪、更廣泛的“外觀和感覺”。Material Design的核心思想是把物理世界中的體驗(yàn)帶入屏幕之中再配合虛擬世界的靈活特性音五,達(dá)到最貼近真實(shí)的體驗(yàn)惫撰。作為Android開發(fā)人員,我們也是有必要了解它的一些基礎(chǔ)控件的使用方法躺涝。好了那么下面我們就開始學(xué)習(xí)吧厨钻。

ToolBar

我們都知道ActionBar,生成一個(gè)默認(rèn)的Android項(xiàng)目后頂部的標(biāo)題欄就是ActionBar坚嗜,因?yàn)锳ctionBar只能位于活動(dòng)的頂部并且不能實(shí)現(xiàn)Material Design的效果夯膀,Google已經(jīng)不建議我們使用ActionBar,那么我們?nèi)绾稳コ夭允撸扛捻?xiàng)目主體不就行了诱建。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zxl.domain.materialdemo5">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

更改app:theme如下:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>
去除標(biāo)題欄.png

好了ActionBar去掉了,但是我還想要標(biāo)題欄啊银室,別著急涂佃,我們不是還有Toolbar嘛。
首先在布局文件里添加toolbar并指定背景色蜈敢。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <android.support.v7.widget.Toolbar
        android:id="@+id/tl"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        ></android.support.v7.widget.Toolbar>
</FrameLayout>

MainActivity代碼如下:

public class MainActivity extends AppCompatActivity {
    Toolbar toolbar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar=findViewById(R.id.tl);
        setSupportActionBar(toolbar);
    }
}

代碼很簡(jiǎn)單辜荠,就是將ActionBar替換成了ToolBar,運(yùn)行效果如下:


ActionBar替換成ToolBar.png

好像不太對(duì)勁吧抓狭?這標(biāo)題欄上的文字怎么成黑的了伯病?我明明記得以前都是白色的啊,其實(shí)這與app主題的設(shè)置有關(guān)系否过,andorid默認(rèn)的主題是背景色是淺的午笛,陪襯顏色是深的,這也就是文字是深色的緣故苗桂,我們只要給toolbar指定一個(gè)深色主題就好了

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <android.support.v7.widget.Toolbar
        android:id="@+id/tl"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        ></android.support.v7.widget.Toolbar>
</FrameLayout>

但這樣好會(huì)有問題药磺,那就是Toolbar中的菜單按鈕中的菜單欄文字也會(huì)變?yōu)楹谏@又與我們平常見到的不一致了煤伟,所以還需要給彈出的菜單欄單獨(dú)設(shè)置主題樣式癌佩。

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

上面的話可能有些不好理解,所以自己敲一遍是很重要的便锨,這會(huì)讓你加深理解围辙。
好了現(xiàn)在toolbar已經(jīng)可以和ActionBar一樣顯示了,現(xiàn)在在給toolbar加上一些菜單項(xiàng)

首先在res下新建menu文件夾并新建menu_toolbar

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/menu1" android:icon="@mipmap/menu" android:title="menu1" app:showAsAction="always"></item>
     <item android:id="@+id/menu2" android:icon="@mipmap/menu" android:title="menu2" app:showAsAction="ifRoom"></item>
     <item android:id="@+id/menu3" android:icon="@mipmap/menu" android:title="menu3" app:showAsAction="never"></item>
</menu>

現(xiàn)在解釋一下showAsAction屬性放案,always表示會(huì)一直出現(xiàn)在標(biāo)題欄上姚建,ifRoom表示如果標(biāo)題欄放得下則顯示在標(biāo)題欄上否則就顯示在菜單中,never表示顯示在菜單中吱殉。

調(diào)用onCreateOptionsMenu(Menu menu)方法加載菜單文件掸冤。

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

效果如下:


添加菜單的Toolbar.png

感覺這和ActionBar沒什么區(qū)別啊厘托,是的,如果單單只是用ToolBar的話確實(shí)沒有什么明顯的效果贩虾,但ToolBar與其他控件組合便會(huì)有一些“神奇”的效果催烘。ToolBar先說到這里。

NavigationView

側(cè)滑菜單在應(yīng)用中很常見缎罢,一種簡(jiǎn)單的方法就是包裹上一層DrawerLayout伊群,自己再去寫側(cè)滑欄的布局,Material Design提供了NavigationView來實(shí)現(xiàn)側(cè)滑欄的效果〔呔現(xiàn)在就來使用一下吧舰始。

首先導(dǎo)入Design Support庫(kù)

implementation 'com.android.support:design:26.1.0'

在MainActivity的布局文件中包裹上DrawerLayout并添加NavigationView控件。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.v7.widget.Toolbar
        android:id="@+id/tl"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        ></android.support.v7.widget.Toolbar>
</FrameLayout>
    <android.support.design.widget.NavigationView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:headerLayout="@layout/nav_head"
        app:menu="@menu/nav_menu"
        android:layout_gravity="start"
        ></android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

其中headerLayout為側(cè)滑欄頂部布局咽袜,這里我就放了一張圖片丸卷,menu為菜單項(xiàng)和上面toolbar設(shè)置菜單文件一樣,這里不再贅述询刹。注意不要忘記添加layout_gravity谜嫉,這里的作用是說明側(cè)滑欄從哪一側(cè)拉出,默認(rèn)為left凹联,也就是左側(cè)拉出沐兰,這里使用的是start,表示跟隨系統(tǒng)語言的行文方式(中文蔽挠,英文在左邊住闯,阿拉伯文在右邊...)。效果如下:


側(cè)滑欄.png

額圖片顏色去哪了澳淑?其實(shí)這里是有一個(gè)統(tǒng)一的默認(rèn)顏色比原,如果你不喜歡換點(diǎn)就是了。現(xiàn)在我們就換一下杠巡。

public class MainActivity extends AppCompatActivity {
    Toolbar toolbar;
    NavigationView nav;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar=findViewById(R.id.tl);
        setSupportActionBar(toolbar);
        nav=findViewById(R.id.nav);
        //這里傳入null即可恢復(fù)菜單欄里icon的顏色
        nav.setItemIconTintList(null);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_toolbar,menu);
        return true;
    }
}
顏色恢復(fù)了.png

至于NavigationView的其他功能相信聰明的你一定比我這個(gè)小白要厲害的多量窘,自學(xué)肯定不在話下。

現(xiàn)在還有一個(gè)小問題氢拥,用戶怎么知道從左邊拉出菜單還是從右邊拉出菜單蚌铜,可能用戶連有側(cè)滑欄存在這個(gè)事實(shí)都不一定知道,那怎么辦呢兄一?Material Design建議實(shí)在標(biāo)題欄最左側(cè)加入一個(gè)導(dǎo)航按鈕,用戶可以點(diǎn)擊該按鈕拉出側(cè)滑欄识腿。

public class MainActivity extends AppCompatActivity {
    Toolbar toolbar;
    NavigationView nav;
    DrawerLayout drawerLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar=findViewById(R.id.tl);
        setSupportActionBar(toolbar);
        nav=findViewById(R.id.nav);
        drawerLayout=findViewById(R.id.dl);
        //這里傳入null即可恢復(fù)菜單欄里icon的顏色
        nav.setItemIconTintList(null);
        //注意這里的ActionBar其實(shí)就是我們?cè)O(shè)置的ToolBar
        ActionBar supportActionBar = getSupportActionBar();
        //顯示HomeAsUp按鈕
        supportActionBar.setDisplayHomeAsUpEnabled(true);
        //設(shè)置小圖標(biāo)
        supportActionBar.setHomeAsUpIndicator(R.mipmap.menu);
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                //跟隨系統(tǒng)語言行文方向拉出側(cè)滑欄
                drawerLayout.openDrawer(Gravity.START);
        }
        return true;
    }
}

這里要說明的是HomeAsUp按鈕原本是一個(gè)返回上一個(gè)頁(yè)面功能按鈕出革,通過修改icon圖標(biāo)和onOptionsItemSelected()對(duì)它的功能進(jìn)行修改實(shí)現(xiàn)拉出側(cè)滑欄的效果。

好了現(xiàn)在側(cè)滑欄也有了渡讼,現(xiàn)在我想實(shí)現(xiàn)像新聞app那樣點(diǎn)擊選項(xiàng)卡切換頁(yè)面的效果怎么辦骂束?TabLayout就可以實(shí)現(xiàn)這樣的效果耳璧。

TabLayout

Tablayout繼承自HorizontalScrollView,用作頁(yè)面切換指示器展箱,因使用簡(jiǎn)便功能強(qiáng)大而廣泛使用在App中≈伎荩現(xiàn)在我們就學(xué)習(xí)下如何使用吧。

首先我們想象頁(yè)面切換的步驟混驰,當(dāng)我們點(diǎn)擊一個(gè)選項(xiàng)卡就切換到對(duì)應(yīng)的頁(yè)面去攀隔,頁(yè)面的切換我們可以使用ViewPager來實(shí)現(xiàn),只要將TabLayout與View建立起聯(lián)系就可以了栖榨。

在布局文件里添加TabLayout

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/dl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.v7.widget.Toolbar
        android:id="@+id/tl"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        ></android.support.v7.widget.Toolbar>
    <android.support.design.widget.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        ></android.support.design.widget.TabLayout>
</FrameLayout>

設(shè)置選項(xiàng)卡名稱

 public void initTab(){
        //選項(xiàng)卡名稱
        String[] tabs=new String[]{"英超","中超","挪超","西甲","德甲","法甲","意甲","中甲","荷甲","英冠"};
            for (int i=0;i<tabs.length;i++){
                //設(shè)置選項(xiàng)卡名稱
               tabLayout.addTab(tabLayout.newTab().setText(tabs[i]));
            }

    }

顯示效果如下:


tablayout.png

可以看出TabLayout與ToolBar重疊在了一起昆汹,原因很簡(jiǎn)單因?yàn)樗麄兌际荈rameLayout的子控件,哪有人可能會(huì)說了我用LinearLayout不就行了婴栽,當(dāng)然是可以的满粗,但我們想要的是"心連著心永遠(yuǎn)在一起",這時(shí)候就需要AppBarLayout的幫助了。

AppBarLayout

AppBarLayout 繼承自LineaLayout愚争,所以在設(shè)計(jì)布局時(shí)可以參考LinearLayout的布局方式進(jìn)行布局映皆,AppBarLayout是在LinearLayou上加了一些材料設(shè)計(jì)的概念,它可以讓你定制當(dāng)某個(gè)可滾動(dòng)View的滾動(dòng)手勢(shì)發(fā)生變化時(shí)轰枝,其內(nèi)部的子View實(shí)現(xiàn)何種動(dòng)作捅彻。說白了就是例如當(dāng)RecyclerView或者被NestedScrollView包裹的控件滑動(dòng)滑動(dòng)時(shí)被AppBarLayout包裹的子View能夠跟著一起滑動(dòng),而這些都是系統(tǒng)已經(jīng)實(shí)現(xiàn)好的狸膏,只要在布局文件中聲明就好沟饥。當(dāng)然這一切還需要一個(gè)控件的配合,它就是CoordinatorLayout湾戳,這個(gè)我們會(huì)在后面進(jìn)行說明贤旷。

那我們現(xiàn)在在布局文件中添加AppBarLayout作為ToolBar和TabLayout的父控件。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/dl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <android.support.v7.widget.Toolbar
        android:id="@+id/tl"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        ></android.support.v7.widget.Toolbar>
    <android.support.design.widget.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        ></android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>
</FrameLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/nav"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:headerLayout="@layout/nav_head"
        app:menu="@menu/nav_menu"
        android:layout_gravity="start"
        ></android.support.design.widget.NavigationView>

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

現(xiàn)在我們看來看一下運(yùn)行后的效果:


使用AppBarLayout后.png

其實(shí)到現(xiàn)在為止我們還是利用的LinearLayout的特性讓TabLayout位于ToolBar的下邊砾脑。

ViewPager的創(chuàng)建和數(shù)據(jù)初始化如下:

 public void initViewPager(){
       List<Fragment> fragments=new ArrayList<>();
       for (int i=0;i<tabs.length;i++){
           FruitFragment fruitFragment=new FruitFragment();
           fragments.add(fruitFragment);
       }
       //viewPager設(shè)置設(shè)配器
       vp.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager(),fragments,tabs));
        //將viewpager與tablayout進(jìn)行綁定
        tabLayout.setupWithViewPager(vp);

    }

MyViewPagerAdapter

package com.zxl.domain.materialdemo5;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

/**
 * Created by jackal on 2019/2/15.
 */

public class MyViewPagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> list;
    private String[] titles;
    public MyViewPagerAdapter(FragmentManager fm, List<Fragment> list,String[] titles) {
        super(fm);
        this.list=list;
        this.titles=titles;
    }

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

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

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

FruitFragment

package com.zxl.domain.materialdemo5;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by jackal on 2019/2/15.
 */

public class FruitFragment extends Fragment {
    RecyclerView rc;
    private List<Fruit> fruits;
    private static final int[] imageIds=new int[]{R.mipmap.apple,R.mipmap.banana,R.mipmap.cherry,R.mipmap.lemon,R.mipmap.watermelon};
    private static final String[] fruitNames=new String[]{"蘋果","香蕉","櫻桃","檸檬","西瓜"};
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_fruit, container, false);
        rc=view.findViewById(R.id.rc);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //初始化RecyclerView數(shù)據(jù)
        initData();
        //初始化RecyclerView
        initView();
    }

    public void initData(){
         fruits=new ArrayList<>();
         for (int i=0;i<30;i++){
             //隨機(jī)生成30個(gè)水果
             Random random=new Random();
             int index = random.nextInt(imageIds.length);
             Fruit fruit=new Fruit(fruitNames[index],imageIds[index]);
             fruits.add(fruit);
         }
    }

    public void initView(){
         rc.setLayoutManager(new GridLayoutManager(getContext(),2));
         rc.setAdapter(new MyRecyclerViewAdapter(getContext(),fruits));
    }


}

MyRecyclerViewAdapter

package com.zxl.domain.materialdemo5;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by jackal on 2019/2/15.
 */

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder>{
    private Context context;
    private List<Fruit> list;
    public  MyRecyclerViewAdapter(Context context,List<Fruit> list){
         this.context=context;
         this.list=list;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_fruit, parent, false);
        MyViewHolder holder=new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
         holder.iv.setImageResource(list.get(position).getImageId());
         holder.tv.setText(list.get(position).getName());
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder{
        ImageView iv;
        TextView tv;
        public MyViewHolder(View itemView) {
            super(itemView);
            iv=itemView.findViewById(R.id.iv);
            tv=itemView.findViewById(R.id.tv);
        }
    }
}

Fruit

package com.zxl.domain.materialdemo5;

/**
 * Created by jackal on 2019/2/15.
 */

public class Fruit {
    private String name;
    private int imageId;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }

    public Fruit(String name,int imageId){
        this.name=name;
        this.imageId=imageId;
    }
}

item_fruit.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    >
    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        />
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="123"
        android:textSize="20sp"
        android:gravity="center_horizontal"
        />
</LinearLayout>

實(shí)現(xiàn)效果如下所示:


ViewPager與Tablayout實(shí)現(xiàn)頁(yè)面切換.png

這是怎么回事盅藻?怎么RecyclerView的上部顯示不全畅铭?我明明是讓RecyclerView(其實(shí)應(yīng)該是ViewPager里的Fragment的布局里只有一個(gè)RecyclerView,而它占據(jù)了整個(gè)屏幕)占用整個(gè)屏幕的假残。原因是這樣的AppBarLayout將ToolBar和TabLayout整合在一起作為了標(biāo)題欄,那么標(biāo)題欄默認(rèn)實(shí)在頂部的阳惹,所以會(huì)導(dǎo)致RecyclerView部分被遮擋眶俩。那怎么解決呢莹汤?讓RecyclerView避開標(biāo)題欄?其實(shí)Material Design已經(jīng)為我們解決了這個(gè)問題颠印,就是使用CoordinatorLayout纲岭,通過CoordinatorLayout告訴ViewPager,大兄弟頂上有一個(gè)AppBarLayout嗽仪,你往下移動(dòng)一下被荒勇,這個(gè)過程是通過app:layout_behavior="@string/appbar_scrolling_view_behavior"來實(shí)現(xiàn)。這也就引出了CoordinatorLayout闻坚,現(xiàn)在我們來介紹一下CoordinatorLayout沽翔。

CoordinatorLayout

CoordinatorLayout是Android Design Support Library中比較難的控件。顧名思義窿凤,它是用來組織其子
View 之間協(xié)作的一個(gè)父 View仅偎。CoordinatorLayout 默認(rèn)情況下可被理解為一個(gè)FrameLayout,它的布局方式默認(rèn)是一層一層疊上去的雳殊。

當(dāng)我們?cè)赩iewPager里添加入 app:layout_behavior="@string/appbar_scrolling_view_behavior"時(shí)橘沥,ViewPager會(huì)隨著AppBarLayout的狀態(tài)變化而進(jìn)行移動(dòng)。效果如下:


ViewPager與Tablayout實(shí)現(xiàn)頁(yè)面切換(正常版).png

一切都完好如初夯秃。RecyclerView也可以正常顯示了座咆。那么如果想在向上滑動(dòng)時(shí)隱藏ToolBar,則可以在ToolBar上加上app:layout_scrollFlags="scroll"仓洼,這樣在向上滑動(dòng)時(shí)ToolBar會(huì)隨著滑動(dòng)而隱藏介陶。向下滑到底端時(shí)ToolBar會(huì)重新出現(xiàn)。

其實(shí)layout_scrollFlags作用在ToolBar上作用就是可滑動(dòng)的控件滑動(dòng)時(shí)ToolBar也隨著做出相應(yīng)的改變色建。比如說設(shè)置為scroll時(shí)哺呜,ToolBar會(huì)隨著向上滑動(dòng)也一起向上滑動(dòng)直至隱藏起來,enteralways會(huì)讓ToolBar隨著向下滑動(dòng)而一塊向下滑動(dòng)直至顯示某残。snap則會(huì)根據(jù)現(xiàn)在滑動(dòng)的距離自動(dòng)判斷是隱藏還是顯示玻墅。如果現(xiàn)在我想要的是標(biāo)題欄在沒有滑動(dòng)時(shí)是一個(gè)樣子澳厢,隨著滑動(dòng)折疊成另外一個(gè)樣子該怎么做呢?其實(shí)再給ToolBar加上一層CollapsingToolbarLayout就好了裸扶。

CollapsingToolbarLayout

CollapsingToolbarLayout生來就是為Toolbar服務(wù)的呵晨,通過它ToolBar可以獲得更多的變換,效果也會(huì)更加豐富季二。需要注意的是CollapsingToolbarLayout是一個(gè)FragmeLayout胯舷。

首先添加CollapsingToolbarLayout作為ToolBar的父控件和一個(gè)ImageView

 <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:background="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="enterAlways"
            >
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/nba"
                android:scaleType="fitXY"
                />
            <android.support.v7.widget.Toolbar
                android:id="@+id/tl"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                ></android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
    <android.support.design.widget.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        ></android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>

這里AppBarLayout是"爺爺",CollapsingToolbarLayout是"爸爸"逃顶,ToolBar是"兒子",兒子要聽"爸爸"的以政,所以以前加在"兒子"身上的主題,flag現(xiàn)在統(tǒng)統(tǒng)交給"爸爸"眉反。
效果如下:


CollapsingToolbarLayout.png

原諒我選的圖片是黑色背景導(dǎo)致menu都看不見了....大家可以看到圖片填充了整個(gè)標(biāo)題欄,這個(gè)可以理解應(yīng)為我們就是讓圖片填充整個(gè)標(biāo)題欄耿币,但是Title文字怎么到了左下方了十性?其實(shí)這是CollapsingToolbarLayout默認(rèn)讓Toolbar顯示在左下角劲适,如果你不喜歡可以通過 app:expandedTitleGravity來更改烹植,比如說改到右上方

 <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:background="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="enterAlways"
            app:expandedTitleGravity="right|top"
            >
改變expandedTitleGravity.png

標(biāo)題跑到了右上方,還有一個(gè)app:contentScrim="xxx"指的是用于指定CollapsingToolbarLayout趨于折疊狀態(tài)或者處于折疊狀態(tài)時(shí)標(biāo)題欄的背景色墩虹。這個(gè)就不在演示了败晴〖饫ぃ可是到這里還是沒有實(shí)現(xiàn)標(biāo)題欄的折疊,不過要做到這點(diǎn)也很簡(jiǎn)單纯路,加上app:layout_collapseMode=""驰唬,如果為pin則表示在折疊時(shí)不隱藏叫编,parallax表示在折疊時(shí)進(jìn)行隱藏。那么現(xiàn)在我想在滑動(dòng)時(shí)折疊圖片霞篡,而ToolBar不做改變就可以將ImageView的app:layout_collapseMode設(shè)置為parallax,ToolBar的設(shè)置成pin污淋,將CollapsingToolbarLayout的layout_scrollFlags設(shè)置成exitUntilCollapsed,表示當(dāng)在完成折疊之后CollapsingToolbarLayout會(huì)留在界面上。
缺圖片
完整的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/dl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="250dp"
            app:contentScrim="@color/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:expandedTitleGravity="right|top"
            >
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/nba"
                android:scaleType="fitXY"
                app:layout_collapseMode="parallax"
                />
            <android.support.v7.widget.Toolbar
                android:id="@+id/tl"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                ></android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
    <android.support.design.widget.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        ></android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        ></android.support.v4.view.ViewPager>

</android.support.design.widget.CoordinatorLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/nav"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:headerLayout="@layout/nav_head"
        app:menu="@menu/nav_menu"
        android:layout_gravity="start"
        ></android.support.design.widget.NavigationView>

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

好了絕大部分的知識(shí)已經(jīng)說完了着憨,現(xiàn)在還有幾個(gè)小的知識(shí)點(diǎn)需要再說明一下甲抖。

FloatingActionButton

沒什么好說的挫剑,他就是一個(gè)圓形的Button樊破,還帶了一點(diǎn)陰影顯得比較有立體感哲戚,使用方法和普通Button差不多顺少,不過在CollapsingToolbarLayout下可以通過 app:layout_anchor="@id/vp"和app:layout_anchorGravity="bottom|right"來制定它的錨點(diǎn)View和在該View的位置脆炎。

 <android.support.design.widget.FloatingActionButton
          android:layout_width="30dp"
          android:layout_height="30dp"
          android:src="@mipmap/menu"
          app:layout_anchor="@id/vp"
          app:layout_anchorGravity="bottom|right"
          android:elevation="8dp"
          android:layout_marginRight="10dp"
          android:layout_marginBottom="10dp"
          />

效果如下:


floatingActionButton.png

SnackBar

大家都知道吐司只能告訴用戶一些信息,而無法做到用戶與app的交互而SnackBar做到了這一點(diǎn)簇爆,通過setAction可以為用戶提供一個(gè)按鈕來進(jìn)行交互入蛆。

 public void initSnackBar(){
        Snackbar.make(fab,"你好",Snackbar.LENGTH_LONG).setAction("answer", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"吃了嗎",Toast.LENGTH_SHORT).show();
            }
        }).show();
    }

效果如下:


snackBar效果.png

CardView

CardView適用于實(shí)現(xiàn)卡片式布局效果的重要控件枫甲,由appcompat-v7庫(kù)提供想幻,實(shí)際上CardView也是一個(gè)FrameLayout脏毯,只是額外提供了圓角和陰影效果食店,看上去有立體的感覺吉嫩。一般CardView都用在ListView或RecyclerView的item布局中自娩。

引入CardView庫(kù)

 implementation 'com.android.support:cardview-v7:26.1.0'
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="10dp"
    android:orientation="vertical">
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="8dp"
        app:cardCornerRadius="4dp"
        >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"

        >
    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        />
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="123"
        android:textSize="20sp"
        android:gravity="center_horizontal"
        />
    </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

其中elevation表示陰影效果
cardCornerRadius表示圓角弧度
效果如下:


CardView效果.png

總結(jié)

今天主要是學(xué)習(xí)了Material Design Support 庫(kù)中的常用控件智什,總體來說不難旱眯,希望我的這篇文章能夠?qū)δ阌兴鶐椭?br> PS:感覺今天一個(gè)白天什么也沒做删豺,全在寫文章了呀页,這也是我的第三篇簡(jiǎn)書文章蓬蝶,也是我寫過的最長(zhǎng)的一篇,感覺大篇幅的廢話連篇只是想讓大家能看的明白培愁,也是對(duì)自己知識(shí)的一次總結(jié)。本來想拆開來寫但是作為一個(gè)Demo感覺還是寫在一起才好私股。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末倡鲸,一起剝皮案震驚了整個(gè)濱河市查坪,隨后出現(xiàn)的幾起案子偿曙,更是在濱河造成了極大的恐慌望忆,老刑警劉巖启摄,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傅是,死亡現(xiàn)場(chǎng)離奇詭異喧笔,居然都是意外死亡书闸,警方通過查閱死者的電腦和手機(jī)浆劲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蛉威,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚯嫌,“玉大人,你說我怎么就攤上這事栅盲√革” “怎么了拟烫?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵硕淑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我公条,道長(zhǎng)寂拆,這世上最難降的妖魔是什么纠永? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮炭序,結(jié)果婚禮上窗声,老公的妹妹穿的比我還像新娘笨觅。我一直安慰自己,他們只是感情好苍苞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冈欢,像睡著了一般涛癌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天坚俗,我揣著相機(jī)與錄音,去河邊找鬼恩闻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛剧董,可吹牛的內(nèi)容都是我干的幢尚。 我是一名探鬼主播破停,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼尉剩!你這毒婦竟也來了真慢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤理茎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后式撼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體美浦,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡币厕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腺兴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烟瞧,死狀恐怖砾赔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤炸渡,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布瘸味,位于F島的核電站毅贮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜革骨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望殖属。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)儒溉。三九已至蒲障,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間搀突,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工检盼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓凉翻,卻偏偏與公主長(zhǎng)得像势就,于是被迫代替她去往敵國(guó)和親坦仍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容