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/password_til"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:errorEnabled="true"
        android:layout_margin="10dp"
        app:hintTextAppearance="R.style.hintAppearence"
        android:focusable="false"
        app:counterEnabled="true"
        app:counterMaxLength="10"
        android:focusableInTouchMode="false"
        android:hint="请输入密码">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword"
            android:paddingLeft="10dp" />
    </com.google.android.material.textfield.TextInputLayout>
    
    //代码中;String password= password_til.getEditText().getText().toString();
    
    TextInputLayout password_til = findViewById(R.id.password_til);
    password_til.setPasswordVisibilityToggleEnabled(true);
    //设置 浮动标签样式
    password_til.setHintTextAppearance(R.style.hintAppearence);
    

    在这里插入图片描述
    此外还可以通过: passwordTIL.setError("账号或密码错误");
    代替 Toast 来提示密码错误
    注:对 EditText 的监听还是需要添加 EditText 的监听器,在其中做 setError;
    在这里插入图片描述
    存在的问题,输入了账号密码,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

  1. 抽屉菜单界面<项目:c12materialtest>布局文件的根布局是DrawerLayout;菜单也写在NavigationView里。

  2. 布局文件如下:

    <?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>
    
  3. nav_menu.xml

    <?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代码:

    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;下次见;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liusaisaiV1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值