Material design 的核心思想是把物理世界的體驗帶進屏幕。去掉現(xiàn)實中的雜質(zhì)和隨機性,保留其最原始純凈的形態(tài)刮便、空間關(guān)系、變化與過渡绽慈,配合虛擬世界的靈活特性恨旱,還原最貼近真實的體驗抄肖,達到簡潔與直觀的效果。
Material design引入了z軸的概念窖杀,z軸垂直于屏幕漓摩,用來表現(xiàn)元素的層疊關(guān)系。z值(海拔高度)越高入客,元素離界面底層(水平面)越遠管毙,投影越重。這里有一個前提桌硫,所有的元素的厚度都是1dp夭咬。所有元素都有默認的海拔高度,對它進行操作會抬升它的海拔高度铆隘,操作結(jié)束后卓舵,它應(yīng)該落回默認海拔高度。同一種元素膀钠,同樣的操作掏湾,抬升的高度是一致的。
Toolbar簡單使用
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:contentInsetStartWithNavigation="0dp"
app:layout_collapseMode="pin"
app:logo="@drawable/ic_android_white_24dp"
app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:subtitle="subtitle"
app:title="title">
// Logo
toolbar.setLogo(R.drawable.ic_android_white_24dp);
// 主標題
toolbar.setTitle("Title");
// 副標題
toolbar.setSubtitle("subtitle");
//設(shè)置toolbar
setSupportActionBar(toolbar);
//左邊的小箭頭(注意需要在setSupportActionBar(toolbar)之后才有效果)
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
//返回按鈕的點擊事件
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
//菜單的點擊事件
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.action_search:
Toast.makeText(ToolbarActivity.this, "search", Toast.LENGTH_SHORT).show();
break;
case R.id.action_share:
Toast.makeText(ToolbarActivity.this, "share", Toast.LENGTH_SHORT).show();
break;
case R.id.action_setting:
Toast.makeText(ToolbarActivity.this, "setting", Toast.LENGTH_SHORT).show();
break;
case R.id.action_about:
Toast.makeText(ToolbarActivity.this, "about", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
});
設(shè)置Toolbar的theme肿嘲,可以讓彈窗不遮擋標題欄融击,處于標題欄的下方。
<item name="overlapAnchor">false</item>
AppBarLayout + CollapsingToolbarLayout + Toolbar的使用
- CollapsingToobbarLayout常用屬性:
- app:contentScrim設(shè)置折疊時工具欄布局的顏色雳窟,默認是colorPrimary的色值
- app:statusBarScrim設(shè)置折疊時狀態(tài)欄的顏色尊浪,默認是colorPrimaryDark的色值
- app:collapsedTitleGravity設(shè)置折疊時標題的對齊方式
- app:expandedTitleGravity設(shè)置展開時標題的對齊方式
- app:titleEnabled設(shè)置是否顯示標題
- app:toolbarId設(shè)置關(guān)聯(lián)的Toolbar的id
AppBarLayout是一種支持響應(yīng)滾動手勢的app bar布局(比如工具欄滾出或滾入屏幕),CollapsingToolbarLayout則是專門用來實現(xiàn)子布局內(nèi)不同元素響應(yīng)滾動細節(jié)的布局封救,CollapsingToolbarLayout是不能獨立存在的砚蓬,它必須只能作為AppBarLayout 的子布局來使用崩掘。
與AppBarLayout組合的滾動布局(Recyclerview卜录、NestedScrollView等)需要設(shè)置app:layout_behavior="@string/appbar_scrolling_view_behavior"(上面代碼中NestedScrollView控件所設(shè)置的)缘滥。沒有設(shè)置的話,AppBarLayout將不會響應(yīng)滾動布局的滾動事件搓彻。
AppBarLayout的子布局有5種滾動標識
- scroll:將此布局和滾動時間關(guān)聯(lián)如绸。這個標識要設(shè)置在其他標識之前嘱朽,沒有這個標識則布局不會滾動且其他標識設(shè)置無效旭贬。
- enterAlways:任何向下滾動操作都會使此布局可見。這個標識通常被稱為“快速返回”模式搪泳。只要向下滑動稀轨,布局就完全展開。
- enterAlwaysCollapsed:假設(shè)你定義了一個最小高度(minHeight)同時enterAlways也定義了岸军,那么view將在到達這個最小高度的時候開始顯示奋刽,并且從這個時候開始慢慢展開瓦侮,當滾動到頂部的時候展開完。向下滑動時佣谐,先顯示ToolBar肚吏,當內(nèi)容滑動都滑動完時,再顯示圖片狭魂。
- exitUntilCollapsed:當你定義了一個minHeight罚攀,此布局將在滾動到達這個最小高度的時候折疊。ToolBar不會被隱藏雌澄。
- snap:當一個滾動事件結(jié)束斋泄,如果視圖是部分可見的,那么它將被滾動到收縮或展開镐牺。例如炫掐,如果視圖只有底部25%顯示,它將折疊睬涧。相反募胃,如果它的底部75%可見,那么它將完全展開畦浓。
- CollapsingToolbarLayout的子布局有3種折疊模式摔认。CollapsingToobarLayout折疊后的高度就是Toorbar的高度。
- none:這個是默認屬性宅粥,布局將正常顯示参袱。布局會被滑動進去
- pin:CollapsingToolbarLayout折疊后,此布局將固定在頂部秽梅。
- parallax:CollapsingToolbarLayout折疊時抹蚀,此布局也會有視差折疊效果。當CollapsingToolbarLayout的子布局設(shè)置了parallax模式時企垦,我們還可以通過app:layout_collapseParallaxMultiplier設(shè)置視差滾動因子环壤,值為:0~1。
CollasToolbarLayout + TabLayout的使用
TabLayout沒有設(shè)置app:layout_collapseMode钞诡,在CollapsingToolbarLayout收縮時就不會消失郑现。
CollapsingToolbarLayout收縮時的高度是Toolbar的高度,所以我們需要把Toolbar的高度增加荧降,給TabLayout留出位置接箫,這樣收縮后TabLayout就不會和Toolbar重疊。
Toolbar的高度增加朵诫,title會相應(yīng)下移辛友。android:gravity="top"方法使Toolbar的title位于Toolbar的上方,然后通過app:titleMarginTop調(diào)整下title距頂部高度剪返,這樣Toolbar就和原來顯示的一樣了废累。
TabLayout懸停
項目中有時候會遇到這樣的UI設(shè)計需求邓梅,標題 + 頭部布局 + 可滑動切換的tab頁 + ViewPager(里面的Fragment是可滑動的列表)。
可以利用AppBarLayout + CollapsingToolbarLayout可折疊的特性邑滨,把頭部布局折疊起來日缨,呈現(xiàn)出TabLayout在標題欄下方懸停的效果。
使用AppBarLayout + CollapsingToolbarLayout把頭部布局包裹起來掖看,這樣 整個頭部布局都可以折疊和展開殿遂,當頭部布局全部折疊時,TabLayout就懸停在標題下面乙各。
優(yōu)點:實現(xiàn)簡單墨礁,代碼量少。只需要寫XML文件就可以實現(xiàn)該效果耳峦,不需要額外寫代碼來處理滑動事件的沖突恩静。
CardView的使用
CardView繼承自FramLayout。CardView常用屬性:
- app:cardCornerRadius設(shè)置四格圓角的半徑
- app:cardBackgroundColor設(shè)置背景色蹲坷,使用android:background設(shè)置無效
- app:cardElevation設(shè)置陰影
- app:cardMaxElevation:設(shè)置陰影最大高度
- android:foreground="?android:attr/selectableItemBackground"設(shè)置點擊的波紋效果
- app:contentPadding設(shè)備CardView內(nèi)容的padding驶乾,用android:padding設(shè)置無效
- app:cardUseCompatPadding,在Android 5.0及以下的系統(tǒng)中循签,CardView會添加一個額外的padding來繪制陰影级乐,但是在5.0以上的系統(tǒng)中是沒有這個padding的,是直接繪制陰影县匠。所以這個屬性只對5.0以上的系統(tǒng)起作用风科,如果設(shè)置為true,則會在卡片與卡片之間增加額外的padding乞旦。
- app:cardPreventCornerOverlap贼穆,是否設(shè)置卡片和卡片里面內(nèi)容的padding,只對5.0以下系統(tǒng)起作用兰粉,如果設(shè)置為false故痊,content與圓角會重疊,圓角被覆蓋玖姑。
BottomNavigationView
- 主要需要設(shè)置五個個屬性
- app:itemBackground背景顏色
- app:itemTextColor文字顏色
- app:menu指定菜單文件
- app:layout_behavior設(shè)置滑動行為愕秫,可以設(shè)置BottomNavigationView上滑消失,下滑顯示
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
style="@style/Widget.Design.BottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
app:elevation="@dimen/dp_16"
app:itemBackground="@color/viewBackground"
app:itemIconTint="@drawable/selector_nav_item_color"
app:itemTextColor="@drawable/selector_nav_item_color"
app:layout_behavior="com.example.think.widget.BottomNavigationBehavior"
app:menu="@menu/bottom_navigation_main"/>
BottomNavigationView可以設(shè)置一個OnNavigationItemSelectedListener用來響應(yīng)切換的動作
mBottomNavigation.setOnNavigationItemSelectedListener(item -> {
switch (item.getItemId()) {
case R.id.action_news:
mToolbar.setTitle(R.string.title_news);
NewsFragment newsFragment = NewsFragment.newInstance();
switchFragment(newsFragment, R.id.frame_layout);
break;
case R.id.action_photo:
mToolbar.setTitle(R.string.title_photo);
PictureFragment pictureFragment = PictureFragment.newInstance();
switchFragment(pictureFragment, R.id.frame_layout);
break;
case R.id.action_video:
mToolbar.setTitle(R.string.title_video);
VideoFragment videoFragment = VideoFragment.newInstance();
switchFragment(videoFragment, R.id.frame_layout);
break;
case R.id.action_media:
mToolbar.setTitle(R.string.title_media);
ChannelFragment channelFragment = ChannelFragment.newInstance();
switchFragment(channelFragment, R.id.frame_layout);
break;
default:
break;
}
return true;
});
- 使用BottomNavigationView的問題
當BottomNavigationView超過三個menu時(三個及三個以下是正常顯示的)焰络,只有選中的menu會顯示圖片和文字戴甩,其他的menu都只顯示圖片。且寬度不是均勻分布的舔琅,選中的menu寬度比其他的大等恐。
可以通過一個工具方法解決這個問題
public void disableShiftMode(BottomNavigationView navigationView) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
itemView.setShiftingMode(false);
itemView.setChecked(itemView.getItemData().isChecked());
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
DrawerLayout + NavigationView
DrawerLayout一般有兩個子布局洲劣,第一子布局是內(nèi)容布局备蚓,第二個子布局為側(cè)滑菜單的布局课蔬。也可以有三個布局,第一子布局是內(nèi)容布局郊尝,第二二跋、三個布局分別為左右的側(cè)滑菜單。
NavigationView流昏,可以自行填充頭部布局和菜單布局扎即,還可以再添加任意布局。
- app:headerLayout指定頭布局的布局文件
- app:menu指定目錄xml文件
-
android:layout_gravity况凉,一定要設(shè)置這個屬性谚鄙,start表示從左邊滑出,可以和Toolbar聯(lián)動刁绒。end表示從右邊滑出闷营,不能和Toolbar聯(lián)動。如果不設(shè)置這個屬性知市,NavigationView只是一個普通的布局傻盟。
側(cè)滑菜單