Material Design技術(shù)分享

Material design 的核心思想是把物理世界的體驗帶進屏幕。去掉現(xiàn)實中的雜質(zhì)和隨機性,保留其最原始純凈的形態(tài)刮便、空間關(guān)系、變化與過渡绽慈,配合虛擬世界的靈活特性恨旱,還原最貼近真實的體驗抄肖,達到簡潔與直觀的效果。
Material design引入了z軸的概念窖杀,z軸垂直于屏幕漓摩,用來表現(xiàn)元素的層疊關(guān)系。z值(海拔高度)越高入客,元素離界面底層(水平面)越遠管毙,投影越重。這里有一個前提桌硫,所有的元素的厚度都是1dp夭咬。所有元素都有默認的海拔高度,對它進行操作會抬升它的海拔高度铆隘,操作結(jié)束后卓舵,它應(yīng)該落回默認海拔高度。同一種元素膀钠,同樣的操作掏湾,抬升的高度是一致的。

Toolbar簡單使用

Toolbar結(jié)構(gòu)
 <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>
Toolbar

AppBarLayout + CollapsingToolbarLayout + Toolbar的使用

  1. 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
  1. AppBarLayout是一種支持響應(yīng)滾動手勢的app bar布局(比如工具欄滾出或滾入屏幕),CollapsingToolbarLayout則是專門用來實現(xiàn)子布局內(nèi)不同元素響應(yīng)滾動細節(jié)的布局封救,CollapsingToolbarLayout是不能獨立存在的砚蓬,它必須只能作為AppBarLayout 的子布局來使用崩掘。

  2. 與AppBarLayout組合的滾動布局(Recyclerview卜录、NestedScrollView等)需要設(shè)置app:layout_behavior="@string/appbar_scrolling_view_behavior"(上面代碼中NestedScrollView控件所設(shè)置的)缘滥。沒有設(shè)置的話,AppBarLayout將不會響應(yīng)滾動布局的滾動事件搓彻。

  3. 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%可見,那么它將完全展開畦浓。
  1. 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就和原來顯示的一樣了废累。

展開狀態(tài)

折疊狀態(tài)

TabLayout懸停

項目中有時候會遇到這樣的UI設(shè)計需求邓梅,標題 + 頭部布局 + 可滑動切換的tab頁 + ViewPager(里面的Fragment是可滑動的列表)。

可以利用AppBarLayout + CollapsingToolbarLayout可折疊的特性邑滨,把頭部布局折疊起來日缨,呈現(xiàn)出TabLayout在標題欄下方懸停的效果。
使用AppBarLayout + CollapsingToolbarLayout把頭部布局包裹起來掖看,這樣 整個頭部布局都可以折疊和展開殿遂,當頭部布局全部折疊時,TabLayout就懸停在標題下面乙各。

優(yōu)點:實現(xiàn)簡單墨礁,代碼量少。只需要寫XML文件就可以實現(xiàn)該效果耳峦,不需要額外寫代碼來處理滑動事件的沖突恩静。


TabLayout展開狀態(tài)

TabLayout懸停狀態(tài)

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

  1. 主要需要設(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;
        });
  1. 使用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();
        }
    }
底部導(dǎo)航欄

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è)滑菜單
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嫂丙,隨后出現(xiàn)的幾起案子娘赴,更是在濱河造成了極大的恐慌,老刑警劉巖跟啤,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诽表,死亡現(xiàn)場離奇詭異,居然都是意外死亡隅肥,警方通過查閱死者的電腦和手機关顷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來武福,“玉大人议双,你說我怎么就攤上這事∽狡” “怎么了平痰?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伍纫。 經(jīng)常有香客問我宗雇,道長,這世上最難降的妖魔是什么莹规? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任赔蒲,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舞虱。我一直安慰自己欢际,他們只是感情好,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布矾兜。 她就那樣靜靜地躺著损趋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪椅寺。 梳的紋絲不亂的頭發(fā)上浑槽,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天,我揣著相機與錄音返帕,去河邊找鬼桐玻。 笑死,一個胖子當著我的面吹牛荆萤,可吹牛的內(nèi)容都是我干的畸冲。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼观腊,長吁一口氣:“原來是場噩夢啊……” “哼邑闲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梧油,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤苫耸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后儡陨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褪子,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年骗村,在試婚紗的時候發(fā)現(xiàn)自己被綠了嫌褪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡胚股,死狀恐怖笼痛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琅拌,我是刑警寧澤缨伊,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站进宝,受9級特大地震影響刻坊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜党晋,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一谭胚、第九天 我趴在偏房一處隱蔽的房頂上張望徐块。 院中可真熱鬧,春花似錦灾而、人聲如沸胡控。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铜犬。三九已至舞终,卻和暖如春轻庆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敛劝。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工余爆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人夸盟。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓蛾方,卻偏偏與公主長得像,于是被迫代替她去往敵國和親上陕。 傳聞我的和親對象是個殘疾皇子桩砰,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361