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>
好了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)行效果如下:
好像不太對(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;
}
效果如下:
感覺這和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)語言的行文方式(中文蔽挠,英文在左邊住闯,阿拉伯文在右邊...)。效果如下:
額圖片顏色去哪了澳淑?其實(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;
}
}
至于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與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)行后的效果:
其實(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)效果如下所示:
這是怎么回事盅藻?怎么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)。效果如下:
一切都完好如初夯秃。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)交給"爸爸"眉反。
效果如下:
原諒我選的圖片是黑色背景導(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"
>
標(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"
/>
效果如下:
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();
}
效果如下:
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表示圓角弧度
效果如下:
總結(jié)
今天主要是學(xué)習(xí)了Material Design Support 庫(kù)中的常用控件智什,總體來說不難旱眯,希望我的這篇文章能夠?qū)δ阌兴鶐椭?br> PS:感覺今天一個(gè)白天什么也沒做删豺,全在寫文章了呀页,這也是我的第三篇簡(jiǎn)書文章蓬蝶,也是我寫過的最長(zhǎng)的一篇,感覺大篇幅的廢話連篇只是想讓大家能看的明白培愁,也是對(duì)自己知識(shí)的一次總結(jié)。本來想拆開來寫但是作為一個(gè)Demo感覺還是寫在一起才好私股。