• 38、Android--Material Design


    Material Design

    Material Design是由Google推出的全新的设计语言,谷歌表示,这种设计语言旨在为手机、平板电脑、台式机和“其他平台”提供更一致、更广泛的“外观和感觉”。

    谷歌推出Android 5.0之际,在带来了更加详细的Material Design设计规范的同时也推出了全新的Android

    Design Support Library,这个兼容库很容易和之前的 Android Support Library 22.1混淆。它们都是兼容库,二者的区别是这个库多了一些Material Design设计风格的控件。

    SbackBar

    SnackBar显示在屏幕的底部,包含 了文字信息与一个可选的操作按钮。它在指定时间结束之后自动消失。

    public class MainActivity extends AppCompatActivity {
        private RelativeLayout mRootContainer;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mRootContainer = findViewById(R.id.rl_root_container);
            findViewById(R.id.btn_snack_bar)
                    .setOnClickListener(v -> {
                         showSnackBar();
                    });
        }
    
        private void showSnackBar() {
            Snackbar.make(mRootContainer, "标题", Snackbar.LENGTH_LONG)
                    .setAction("点击事件", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(MainActivity.this, "Toast", Toast.LENGTH_SHORT).show();
                        }
                    }).setDuration(Snackbar.LENGTH_LONG)
                    .show();
        }
    }
    

    SnackBar的make方法第一个参数是View类型,传入的是SnackBar的父控件。

    TextlnputLayout

    TextInputLayout控件是一个容器,它跟ScrollView一样只接受一个子元素,并且这个子元素是 EditText。

    简单示例

    代码如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/rl_root_container"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:id="@+id/et_username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="username"
                android:maxLength="25"
                android:maxLines="1"/>
        </com.google.android.material.textfield.TextInputLayout>
    
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp">
            <EditText
                android:id="@+id/et_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="password"
                android:maxLength="25"
                android:maxLines="1"/>
        </com.google.android.material.textfield.TextInputLayout>
    </LinearLayout>
    

    这是一个登录页面的简单实例。

    如果对TextInputLayout输入框以及输入框上方的hint提示颜色不满意,则还可以在style.xml文件中对

    colorAccent属性进行修改

    错误提示

    TextInputLayout还可以通过如下两个api来设置错误信息的友好提示:

    TextInputLayout.setErrorEnabled(boolean enabled) // 打开和隐藏错误提示
    TextInputLayout.setError("") // 设置错误提示文本    
    

    FloatingActionButton

    它是一个负责显示界面基本操作的圆形按钮。其使用起来非常便捷,可以把它当作一个Button,代码如

    下所示:

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:src="@mipmap/ic_launcher"
        android:clickable="true"
        android:backgroundTint="#3F51B5"
        android:elevation="3dp"
        app:pressedTranslationZ="6dp"/>
    

    app:backgroundTint来设定背景填充色。

    app:elevation用来设置正常状态的阴影大小,

    app:pressedTranslationZ 用来设置点击时阴影的大小。

    TabLayout

    Tablayout继承自HorizontalScrollView,可以用作顶部标签效果、底部导航栏效果。一般多与ViewPager一起使用。

    TabHost效果

    1. Activity的布局文件如下:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/rl_root_container"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabIndicatorHeight="2dp"
            app:tabMode="fixed"
            app:tabIndicatorColor="#0a0"
            app:tabSelectedTextColor="#0a0"/>
    
        <androidx.viewpager.widget.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:scrollbars="none"/>
    </LinearLayout>
    
    1. Activity的代码如下:
    public class MainActivity extends AppCompatActivity {
        private TabLayout tabLayout;
        private ViewPager viewPager;
        private List<PageFragment> mPageFragments;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tabLayout = findViewById(R.id.tab_layout);
            viewPager = findViewById(R.id.view_pager);
            mPageFragments = new ArrayList<>();
    
            // Init ViewPager
            for (int i = 0; i < 5; i++) {
                mPageFragments.add(new PageFragment("标题" + i, "内容" + i));
            }
            viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
            tabLayout.setupWithViewPager(viewPager);
        }
    
        class ViewPagerAdapter extends FragmentPagerAdapter{
            public ViewPagerAdapter(@NonNull FragmentManager fm) {
                super(fm);
            }
    
            @NonNull
            @Override
            public Fragment getItem(int position) {
                return mPageFragments.get(position);
            }
    
            @Override
            public int getCount() {
                return mPageFragments.size();
            }
    
            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                return mPageFragments.get(position).getTitle();
            }
        }
    }
    
    1. 最后是Fragment的代码:
    public class PageFragment extends Fragment {
        private TextView tvContent;
        private String title, content;
        public PageFragment(String title, String content) {
            this.title = title;
            this.content = content;
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_page, container, false);
            tvContent = view.findViewById(R.id.tv_content);
            tvContent.setText(content);
            return view;
        }
    
        public String getTitle() {
            return title;
        }
    }
    

    效果如下图所示:

    NavigationView 来可以实现抽屉菜单界面。和普通的侧拉菜单实现方式一样,所有的东西还是都放在一个DrawerLayout中,用NavigationView来替代我们此前自定义的控件。

    Activity布局文件代码

    <?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/rl_root_container"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity"
        android:fitsSystemWindows="true">
        <com.google.android.material.navigation.NavigationView
            android:id="@+id/navigation"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/navigation_header_container"
            app:menu="@menu/drawer_view">
        </com.google.android.material.navigation.NavigationView>
    </androidx.drawerlayout.widget.DrawerLayout>
    

    注意:左侧菜单必须要设置android:layout_gravity="start",否则报错。

    使用到的navigation_header_container.xml如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:background="#660000ff"
        android:gravity="center_horizontal"
        android:layout_height="150dp">
        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:scaleType="fitXY"
            android:layout_gravity="center_vertical"
            android:src="@mipmap/ic_launcher_round"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:gravity="center_vertical"
            android:layout_marginTop="5dp"
            android:layout_gravity="center_vertical"
            android:text="legend"
            android:textSize="20sp"/>
    </LinearLayout>
    

    使用到的菜单文件drawer_view.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_home"
                android:icon="@mipmap/ic_launcher"
                android:title="首页"/>
            <item
                android:id="@+id/nav_message"
                android:icon="@mipmap/ic_launcher"
                android:title="事项"/>
            <item
                android:id="@+id/nav_music"
                android:icon="@mipmap/ic_launcher"
                android:title="音乐"/>
            <item
                android:id="@+id/nav_discussion"
                android:icon="@mipmap/ic_launcher"
                android:title="消息"/>
        </group>
    
        <item android:title="其他">
            <menu>
                <item
                    android:icon="@mipmap/ic_launcher_round"
                    android:title="设置"/>
                <item
                    android:icon="@mipmap/ic_launcher_round"
                    android:title="关于我们"/>
            </menu>
        </item>
    </menu>
    

    最后是Activity中代码的实现:

    public class MainActivity extends AppCompatActivity implements
            NavigationView.OnNavigationItemSelectedListener {
        private DrawerLayout mDrawerLayout;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mDrawerLayout = findViewById(R.id.rl_root_container);
            NavigationView navigationView = findViewById(R.id.navigation);
            navigationView.setNavigationItemSelectedListener(this);
            mDrawerLayout.openDrawer(GravityCompat.START);
        }
    
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            String title = item.getTitle().toString();
            Toast.makeText(this, title, Toast.LENGTH_SHORT).show();
            mDrawerLayout.closeDrawers();
            return true;
        }
    }
    

    CoordinatorLayout

    CoordinatorLayout是在 Google IO/15 大会发布的,遵循Material 风格,包含在 support Library中,结合AppbarLayout, CollapsingToolbarLayout等 可 产生各种炫酷的效果

    AppBarLayout

    如果我们想要实现折叠的ActionBar效果,在CoordinatorLayout中,AppBarLayout绝对是作为首选的控件。

    在正式介绍AppBarLayout的使用时,我们先来看看几个Flag,这几个Flag在AppBarLayout里面非常的重要。

    名称 作用
    SCROLL_FLAG_NO_SCROLL 0x0 将表示该View不能被滑动。也就是说不参与联动。
    SCROLL_FLAG_SCROLL 0x01 表示该View参与联动。具体效果需要跟其他Flag组合。
    SCROLL_FLAG_EXIT_UNTIL_COLLAPSED 0x02 表示当View被推出屏幕时,会跟着滑动,直到折叠到View的最小高度;同时只有在其他View(比如说RecyclerView)滑动到顶部才会展开。
    SCROLL_FLAG_ENTER_ALWAYS 0x02 不管是View是滑出屏幕还是滑进屏幕,该View都能立即响应滑动事件,跟随滑动。比如说,如果该View是折叠的,当RecyclerView向下滑动时,该View随时都能跟随展开;反之亦然。
    SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED 0x04 SCROLL_FLAG_ENTER_ALWAYS的基础上,该Flag增加了折叠到固定高度的限制。在View下拉过程中,首先会将该View显示minHeight的高度,RecyclerView在继续下拉(这里以RecyclerView为例)。注意,该Flag在SCROLL_FLAG_ENTER_ALWAYS前提下生效。
    SCROLL_FLAG_SNAP 0x08 该Flag表示View拥有吸附功能。比如说,当前滑动停止,View离底部更近,那么就会折叠;反之则会展开。

    这几个Flag非常的简单,我们来看看具体的使用,先来看看布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/rl_root_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <View
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#5FF"
                app:layout_scrollFlags="scroll|enterAlwaysCollapsed"/>
            <View
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#FF00FF"/>
        </com.google.android.material.appbar.AppBarLayout>
        <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.coordinatorlayout.widget.CoordinatorLayout>
    

    其中Activity的代码如下:

    public class MainActivity extends AppCompatActivity{
        private RecyclerView mRecyclerView;
        private List<String> mStrings = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mRecyclerView = findViewById(R.id.recycler_view);
            for (int i = 0; i < 30; i++) {
                mStrings.add("Item" + i);
            }
            CustomAdapter customAdapter = new CustomAdapter();
            mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
            mRecyclerView.setAdapter(customAdapter);
        }
    
        class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder>{
            @NonNull
            @Override
            public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_content, parent, false);
                ViewHolder viewHolder = new ViewHolder(itemView);
                return viewHolder;
            }
    
            @Override
            public void onBindViewHolder(@NonNull MainActivity.CustomAdapter.ViewHolder holder, int position) {
                holder.tvContent.setText(mStrings.get(position));
            }
    
            @Override
            public int getItemCount() {
                return mStrings.size();
            }
    
            class ViewHolder extends RecyclerView.ViewHolder {
                TextView tvContent;
                public ViewHolder(@NonNull View itemView) {
                    super(itemView);
                    tvContent = itemView.findViewById(R.id.tv_item_content);
                }
            }
        }
    }
    

    效果如下所示:

    CollapsingToolbarLayout

    CollapsingToolbarLayout主要是实现折叠布局的,我们来看看是怎么使用的。首先,我们来看看CollapsingToolbarLayout的几个Flag:

    名称 作用
    COLLAPSE_MODE_OFF 0 默认值,表示View不会有任何属性
    COLLAPSE_MODE_PIN 1 CollapsingToolbarLayout完全收缩之后,设置该Flag的View会保留在屏幕当中。
    COLLAPSE_MODE_PARALLAX 2 设置该Flag的View会跟内容滚动,可以通过setParallaxMultiplier方法来设置视图差比率,其中0表示毫无视图差,完全跟内容滚动同步;1表示View完全不动。默认的视图差为0.5。

    接下来我们看一个Demo:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/rl_root_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="300dp">
            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed">
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scaleType="centerCrop"
                    android:src="@mipmap/ic_launcher"
                    app:layout_collapseMode="parallax" />
    
                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:background="#5FF"
                    app:layout_collapseMode="pin" />
            </com.google.android.material.appbar.CollapsingToolbarLayout>
        </com.google.android.material.appbar.AppBarLayout>
        <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.coordinatorlayout.widget.CoordinatorLayout>
    

    其中Activity的代码同上个示例一样。

    使用CollapsingToolbarLayout时,我们需要注意的是:CollapsingToolbarLayout需要作为AppBarLayout子View。然后我们来看看相关的效果:

  • 相关阅读:
    phpstorm插件等相关推荐
    Item Pipeline
    没有返回值的构造函数是怎么完成赋值的?
    vue中如何实现点击变成全屏
    vue操作dom元素的三种方法
    陈同学整理的10个可以写到简历上C++项目
    从四个问题透析Linux下C++编译&链接
    C++隐式推导-auto关键词
    从今天起构建你的JavaScript世界
    vue中实现模态框弹出框动画(旋转弹出)
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14961631.html
Copyright © 2020-2023  润新知