Material Design學習總結

Snackbar

  1. Snackbar 是一種輕量級的彈出框,有一個Title,並且比Toast多一個有點擊功能的按鈕;通常顯示在屏幕的底部並在屏幕所有層的最上方,包括浮動操作按鈕。它會在超時後自動消失。

  2. 代碼實現<項目:c12materialtest>:

         Snackbar.make(view, "Data delete", Snackbar.LENGTH_SHORT)
                 .setAction("Undo", new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
                         Toast.makeText(MainActivity.this, "Data restore", Toast.LENGTH_SHORT).show();
                     }
                 }).show();
    

    在這裏插入圖片描述

  3. 注意:Snackbar的make方法的第一個參數是Snackbar的父控件,是一個View類型的參數;第一個參數是 Snackbar 的 Title;setAction 中設置按鈕的點擊事件;

TextlnputLayout

  1. TextInputLayout 控件是一個容器,它跟ScrollView一樣只接受一個子元素,並且這個子元素是 EditText
  2. 按照常規的< EditText>做法,使用 “hint” 在我們未輸入時會顯示出來,輸入的時候就會消失;如圖<項目:myapplication200122>:
    在這裏插入圖片描述
  3. 使用 TextlnputLayout 設置的hint值不在原本的EditText中,而是浮在上方,當我們將焦點移動到輸入password的輸入框時輸入框上浮的文字回到原本的EditText中並伴有動畫;代碼如下所示:
添加依賴:
在 app 目錄下的 build.gradle 中添加“   implementation 'com.android.support:design:28.0.0'<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/account_til"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <EditText
        android:id="@+id/account_edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入賬號"
        android:paddingLeft="10dp" />
</com.google.android.material.textfield.TextInputLayout>
當然在代碼中;String account = accountTIL.getEditText().getText().toString();

在這裏插入圖片描述
此外還可以通過: passwordTIL.setError("賬號或密碼錯誤");
代替 Toast 來提示密碼錯誤
在這裏插入圖片描述
存在的問題,輸入了賬號密碼,hint值沒有消失?下面是理想效果。
在這裏插入圖片描述

TabLayout

實現選項卡的動態滑動效果<項目:myapplication200122>。
在這裏插入圖片描述

  1. 添加依賴:

    implementation ‘androidx.cardview:cardview:1.0.0’
    implementation ‘androidx.recyclerview:recyclerview:1.2.0-alpha01’

  2. 主界面佈局

	<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".tablayout_test.TabLayoutTest">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.example.myapplication200122.TitleLayout
            android:id="@+id/tab_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabIndicatorColor="#ADBE107E"
            app:tabMode="scrollable" />
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/tab_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

	</LinearLayout>
	注意:app:tabMode="scrollable",Tab的模式爲 可滑動的”。設置 app:tabMode="fixed",表示固定不可滑動的
  1. Java代碼
    MainActivity

    /*
     * 設定標題內容;
     * 創建相應的 TabLayout 和 Fragment,
     * 設置 ViewPager 適配器和 TabLayout 適配器,
     * 將TabLayout 和 ViewPager關聯起來
     * /
    public class TabLayoutTest extends AppCompatActivity {
    
        private ViewPager mViewPager;
        private TabLayout mTabLayout;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_tab_layout);
            mViewPager = findViewById(R.id.tab_viewpager);
            initViewPager();
        }
    
        private void initViewPager() {
            mTabLayout = findViewById(R.id.tabs);
    
            List<String> titles = new ArrayList<>();
            titles.add("推薦");
            titles.add("要聞");
            titles.add("新思想");
            titles.add("北京");
            titles.add("綜合");
            titles.add("直播中國");
    
            for (int i = 0; i < titles.size(); i++) {
                mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(i)));
            }
    
            List<Fragment> fragments = new ArrayList<>();
            for (int i = 0; i < titles.size(); i++) {
                fragments.add(new ListFragment());
            }
            /**
             * 自定義的 adapter
             */
            FragmentAdapter mFragmentAdapter = new FragmentAdapter(getSupportFragmentManager(),fragments,titles);
    
            /**
             * 給 ViewPager 設置適配器
             */
            mViewPager.setAdapter(mFragmentAdapter);
            /**
             * 將 TabLayout 和 ViewPager 關聯起來
             */
            mTabLayout.setupWithViewPager(mViewPager);
            /**
             * 給 TabLayout 設置適配器
             */
            mTabLayout.setTabsFromPagerAdapter(mFragmentAdapter);
        }
    }
    

    adapter

     /**
      * 根據不同的 position 來返回不同的Fragment;
      * 根據不同的position來返回不同的title
      */
    public class FragmentAdapter extends FragmentStatePagerAdapter {
        private List<Fragment> mFragments;
        private List<String> mTitles;
    
        public FragmentAdapter(@NonNull FragmentManager fm, List<Fragment> fragments, List<String> titles) {
            super(fm);
            mFragments = fragments;
            mTitles = titles;
        }
    
        @NonNull
        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
    
        @Override
        public int getCount() {
            return mFragments.size();
        }
    
        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return mTitles.get(position);
        }
    }
    

    ListFragment

    /**
     * 系統有 ListFragment ;但這是自己的;作爲每個Tab的界面;用RecyclerView來代替ListView
     */
    public class ListFragment extends androidx.fragment.app.Fragment {
        private RecyclerView mRecyclerView;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            mRecyclerView = (RecyclerView) inflater.inflate( R.layout.list_fragment,container, flase);
            return mRecyclerView;
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(mRecyclerView.getContext()));
            mRecyclerView.setAdapter(new RecyclerViewAdapter(getActivity()));
            }
        }
    

    爲什麼這麼醜?審美受限而已……
    爲什麼這麼醜?主要是審美受限……

NavigationView

抽屜菜單界面<項目:c12materialtest>佈局文件的根佈局是DrawerLayout;菜單也寫在NavigationView裏。
佈局文件如下:

```java
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Coordinatorlayout 是一個加強版的 FrameLayout;可監聽 其所有<子>控件的各種事件,
    以解決類似 SnackBar 遮住 FloaActionButton-->
    
        <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- AppBarLayout 是一個 垂直方向 LinearLayout 解決 RecyclerView 遮住了 ToolBar      -->
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <!-- app:layout_scrollFlags="scroll|enterAlways|snap"
            scroll 表示RecyclerView向上滾動時,ToolBar 會跟着一起向上滾動並實現隱藏
            enterAlways 表示RecyclerView向下滾動時,ToolBar 會跟着一起向下滾動並重新顯示
            snap 表示ToolBar 沒有完全顯示或隱藏時,根據當前滾動距離選擇隱藏或顯示 -->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:layout_anchor="@+id/appBarLayout"
                app:layout_anchorGravity="center"

                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        </com.google.android.material.appbar.AppBarLayout>
        <!-- SwipeRefreshLayout 實現下拉刷新功能 -->
        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipe_frash"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:elevation="8dp"
            android:src="@drawable/ic_done" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    <!--    app:headerLayout 引入頭佈局<圖片部分>-->
    <!--app:menu 引入菜單佈局-->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
```

nav_menu.xml

```java
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_call"
            android:icon="@drawable/nav_call"
            android:title="Call" />
        <item
            android:id="@+id/nav_friends"
            android:icon="@drawable/nav_friends"
            android:title="Friends" />
        <item
            android:id="@+id/nav_location"
            android:icon="@drawable/nav_location"
            android:title="Location" />
        <item
            android:id="@+id/nav_mail"
            android:icon="@drawable/nav_mail"
            android:title="Mail" />
        <item
            android:id="@+id/nav_task"
            android:icon="@drawable/nav_task"
            android:title="Task" />

    </group>
	<!--    通過爲item添加子菜單來實現帶有頭部的分組效果-->
    <item android:title="其他">
        <menu>
            <item android:title="設置"
                android:icon="@drawable/ic_dashboard"/>
            <item android:title="關於我們"
                android:icon="@drawable/ic_dashboard"/>

        </menu>
    </item>
</menu>
```

在這裏插入圖片描述
Java代碼:

```java
setNavigationItemSelectedListener()方法來設置當導航項被點擊時的回調;
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home: //HomeAsUp 按鈕的id永遠都是android.R.id.home
                mDrawerLayout.openDrawer(GravityCompat.START);  //將滑動菜單展示出來
                break;
                ......
    
/**
 * 設置監聽器;當用戶 點擊了 任意菜單項時,就會回調 onNavigationItemSelected();
 */
 navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
 @Override
 public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
	 mDrawerLayout.closeDrawers();
     return true;
 }
```

CoordinatorLayout

CoordinatorLayout中最經典的設計就是的Behavior;下次見;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章