本博客的知识点源于《Android进阶之光》第二章

1.Material Design是什么2.常用控件2.1 Snackbar2.2 TextInputLayout2.21正则表达式1.限定符2.或运算符3.元字符4.其他符5.字符表6.正则表达式的作用2.3 TabLayout2.31ViewPager22.311Viewpager2与Fragment联动2.4NavigationView2.5 CoordinatorLayout2.51CoordinatorLayout实现Toolbar的隐藏效果2.52CoordinatorLayout结合CollapsingToolbarLayout实现Toolbar的折叠效果

1.Material Design是什么

说实话,看了这么久的Material Design我也不太清楚它是干嘛的,Material Design中文翻译过来是质感设计,我的理解就是在手机,平板,电脑等平台提供一致的体验

2.常用控件

2.1 Snackbar

一般用Snackbar我喜欢把它和FloatingButton一块用,在用Snackbar之前得先在build.gradle里面进行文件的配置,《Android进阶之光》里面用的是Android6还是5,那个早就过时了

我用的这个

implementation'com.android.support:design-snackbar:28.0.0-alpha1' 

但是好像说更高的版本用不了还是啥,用这个的话必须加一句

 //noinspection GradleCompatible

后面就好弄了 当按动FloatingActionButton的时候调用Snackbar

 @Override
  public void onClick(View v) {
      Snackbar.make(MainActivity.this,v,"是否删除",Snackbar.LENGTH_LONG).setAction("确定", new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              Toast.makeText(MainActivity.this,"删除掉了",Toast.LENGTH_SHORT).show();
          }
      }).show();
  }

2.2 TextInputLayout

TextInputLayout一般情况下是和EditText进行联动,把EditText包裹起来,

TextInputLayout 主要是作为 EditText 的容器,从而为 EditText 生成一个浮动的 Label,当用户点击 EditText 的时候,EditText 中的 hint 字符串会自动移到 EditText 的左上角

没啥可说的,有一点就是如果用

style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"

的话

AndroidManifest.xml要加上android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar.Bridge"

否则就会报错

2.21正则表达式

1.限定符
?表示它前面的字符出现0次或者1次
*表示它前面的字符出现0次或者n次
+表示它前面的字符出现1次或者n次
{}表示它前面的字符出现你想要的次数

例如:

{2}出现2次
{2,6}出现2-6次
{2,}出现2次及以上

匹配多个字符用'()'把匹配的多字符括起来

2.或运算符
(a|b)要么匹配a要么匹配b
3.元字符
\d数字字符
\w单词字符
\s空白字符
\D非数字字符
\W非单词字符
\S非空白字符
4.其他符
^匹配行首
匹配行尾
5.字符表

‘[]’表示要求匹配的字符只能取自它们,

[abc]+:匹配所有abc的字符

6.正则表达式的作用

正则表达式一般是和EditText联动,判断账号密码输的是否符合规范

例如,若账号是qq邮箱号码,则该正则表达式是这样的(我以自己的qq邮箱为例子):

[0-9]{10}@qq.com

2.3 TabLayout

TabLayout基本上和ViewPager2绑定在一起,当2者联动的时候,可以通过按上面TabLayout中对应的数字到达相应ViewPager2所包裹的Fragment。

为了防止把ViewPager2遗忘,把ViewPager2的东西也写一下

2.31ViewPager2

ViewPager2在不和Fragment联动的情况下,基本上和RecyclerView一样,就没啥好说的了

那就主要说一下ViewPager2Fragment联动

2.311Viewpager2与Fragment联动

首先是在MainActivity里面的Layout弄上ViewPager2

<androidx.viewpager2.widget.ViewPager2
   android:id="@+id/viewpager2"
   app:layout_behavior="@string/appbar_scrolling_view_behavior"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
  />

上面把TabLayout写上

<com.google.android.material.tabs.TabLayout
   android:id="@+id/tablayout"
   android:layout_width="match_parent"
   android:layout_height="50dp"
   app:tabGravity="fill"

   android:theme="@style/Theme.Design.Light.NoActionBar"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintTop_toBottomOf="@+id/toolbar" />

之后先弄一个新的Fragment再创建Fragment的适配器

Fragment的适配器

public class viewpager2Adapter extends FragmentStateAdapter {
   private List<Fragment>mFragments;
   public viewpager2Adapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List<Fragment>fragments) {
       super(fragmentManager, lifecycle);
       mFragments = fragments;
       Log.d("TAG","adapter"+"适配器的构造函数");
  }
   @NonNull
   @Override
   public Fragment createFragment(int position) {
       Log.d("TAG","createFragment"+"这是第"+position+"个视图");
       return mFragments.get(position);
  }
   @Override
   public int getItemCount() {
       Log.d("TAG","size"+"返回"+mFragments.size());
       return mFragments.size();
  }
}

之后再MainActivity里面写

private TabLayout mTabLayout;
private ViewPager2 mViewPager2;
private List<Fragment>mFragments = new ArrayList<>();
mViewPager2 = findViewById(R.id.viewpager2);
mTabLayout = findViewById(R.id.tablayout);
        mFragments.add(BlankFragment.newInstance("1","1"));
       mFragments.add(BlankFragment.newInstance("1","1"));
       mFragments.add(BlankFragment.newInstance("1","1"));
       mFragments.add(BlankFragment.newInstance("1","1"));
       mFragments.add(BlankFragment.newInstance("1","1"));
       mFragments.add(BlankFragment.newInstance("1","1"));
       mList1.add("1");
       mList1.add("2");
       mList1.add("3");
       mList1.add("4");
       mList1.add("5");
       mList1.add("6");
viewpager2Adapter adapter = new viewpager2Adapter(getSupportFragmentManager(),getLifecycle(),mFragments);
mViewPager2.setAdapter(adapter);

上面的这一步完成了适配器的搭建与TabLayout的一些东西

TabLayout的如下

new TabLayoutMediator(mTabLayout, mViewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
   @Override
   public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
       tab.setText(mList1.get(position));
  }
}).attach();

完成


2.4NavigationView

NavigationView一般就是用来实现侧滑菜单,为了弄它,我们先弄普通的侧拉菜单

<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/draw"
  xmlns:android="http://schemas.android.com/apk/res/android">
  <LinearLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:orientation ="vertical"
  >
  <androidx.appcompat.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      android:theme="@style/Theme.Design.Light.NoActionBar"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_collapseMode="pin"
      app:popupTheme="@style/Base.ThemeOverlay.AppCompat.Dark" />

      <com.google.android.material.tabs.TabLayout
          android:id="@+id/tablayout"
          android:layout_width="match_parent"
          android:layout_height="50dp"
          app:tabGravity="fill"

          android:theme="@style/Theme.Design.Light.NoActionBar"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toBottomOf="@+id/toolbar" />
      <androidx.viewpager2.widget.ViewPager2
          android:id="@+id/viewpager2"
          app:layout_behavior="@string/appbar_scrolling_view_behavior"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          />
          </LinearLayout>
  <ImageView
    android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_gravity="left"
  />
</androidx.drawerlayout.widget.DrawerLayout>

对了,要用Toolbar的一个前提就是ActionBar必须给它设置为NoActionBar

然后在MainActivity里面先是

setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

第一个是将ToolBar摆到ActionBar位置,添加进去

第二个是设置一个键,默认是这样的<-

之后重写方法

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item){
   switch (item.getItemId()){
       case android.R.id.home:mDrawerLayout.openDrawer(GravityCompat.START);
       break;
  }
   return true;
}

这个方法就是让左滑的时候能打开侧滑菜单


好,现在加上NavigationView

先把ImageView换成NavigationView

<com.google.android.material.navigation.NavigationView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/navigationView"
   app:menu="@menu/menu"
   app:headerLayout="@layout/head"
   android:layout_gravity="left"/>

之后创建menu和headerLayout

<?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/name"
       android:title="名字"/>
   <item
       android:id="@+id/directing"
       android:title="直播"/>
   <item
       android:id="@+id/file"
       android:title="文件"/>
</group>
   <item
       android:title="其他">
   <menu>
       <item
           android:id="@+id/picture"
           android:title="相册" />
       <item
           android:id="@+id/game"
           android:title="游戏"/>
   </menu>
   </item>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:background="@color/black"
   android:layout_height="match_parent">

   <de.hdodenhof.circleimageview.CircleImageView
       android:id="@+id/circleImage"
       android:layout_width="100dp"
       android:layout_height="100dp"
       android:layout_marginStart="30dp"
       android:layout_marginTop="50dp"
       android:src="@mipmap/background"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

   <TextView
       android:layout_width="200dp"
       android:layout_height="200dp"
       android:layout_marginStart="60dp"
       android:layout_marginTop="30dp"
       android:text="傻吊"
       android:textColor="@color/white"
       android:textSize="30dp"
       app:layout_constraintStart_toEndOf="@+id/circleImage"
       app:layout_constraintTop_toTopOf="@+id/circleImage" />
</androidx.constraintlayout.widget.ConstraintLayout>

就ok了

2.5 CoordinatorLayout

2.51CoordinatorLayout实现Toolbar的隐藏效果

这个比较简单,先用CoordinatorLayout包裹整个,

之后用AppBarLayout包裹住Toolbar

<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/draw"
   xmlns:android="http://schemas.android.com/apk/res/android">
   <androidx.coordinatorlayout.widget.CoordinatorLayout
       android:layout_width="match_parent"
       android:fitsSystemWindows="true"
       android:layout_height="match_parent">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/appbarlayout"
       android:theme="@style/Theme.Design.Light.NoActionBar"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent">

   <androidx.appcompat.widget.Toolbar
       android:id="@+id/toolbar"
       android:layout_width="match_parent"
       android:layout_height="?attr/actionBarSize"
       android:theme="@style/Theme.Design.Light.NoActionBar"
       app:layout_scrollFlags="scroll|exitUntilCollapsed"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent"
       app:layout_collapseMode="pin"
       app:popupTheme="@style/Base.ThemeOverlay.AppCompat.Dark" />
       <com.google.android.material.tabs.TabLayout
           android:id="@+id/tablayout"
           android:layout_width="match_parent"
           android:layout_height="50dp"
           app:tabGravity="fill"

           android:theme="@style/Theme.Design.Light.NoActionBar"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toBottomOf="@+id/toolbar" />

   </com.google.android.material.appbar.AppBarLayout>

       <androidx.viewpager2.widget.ViewPager2
           android:id="@+id/viewpager2"
           app:layout_behavior="@string/appbar_scrolling_view_behavior"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
          />

       <com.google.android.material.floatingactionbutton.FloatingActionButton
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginEnd="40dp"
       android:layout_marginBottom="40dp"
       android:id="@+id/floatingbutton"
       android:layout_gravity="right|bottom"
       android:src="@drawable/ic_baseline_add_24"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent" />

   </androidx.coordinatorlayout.widget.CoordinatorLayout>
   <com.google.android.material.navigation.NavigationView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/navigationView"
       app:menu="@menu/menu"
       app:headerLayout="@layout/head"
       android:layout_gravity="left"/>
</androidx.drawerlayout.widget.DrawerLayout>

注意Toolbar里面有句这个:

app:layout_scrollFlags="scroll|exitUntilCollapsed"

滚动标志取值说明
scroll简单朴素的滚动,没什么花样
enterAlways该标志与scroll的区别在于,它会让头部盖住主体,而scroll不会盖住,只要往下拉,TabLayout就会显示出来,不必等着RecyclerView到顶部才可以显示
exitUntilCollapsed设置该标志后,页面上总会看到工具栏
enterAlwaysCollapsed该标志与enterAlways的区别在于,它支持layout_collapseMode设定的折叠效果
snap设置该标志后,每当用户松开手势,系统会自动判断是向上收缩,还是向下展开

2.52CoordinatorLayout结合CollapsingToolbarLayout实现Toolbar的折叠效果

CollapsingToolbarLayout设置layout_scrollFlag属性,可以控制包含在CollapsingToolbarLayout中的控件,比如ImageView,Toolbar在响应layout_behavior事件做出的相应的scrollFlags滑动事件。在布局文件中用CollapsingToolbarLayoutImageView,Toolbar包裹起来作为一个可折叠的Toolbar,再用AppBarLayout将其包裹作为Appbar的整体

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/draw"
   xmlns:android="http://schemas.android.com/apk/res/android">
   <androidx.coordinatorlayout.widget.CoordinatorLayout
       android:layout_width="match_parent"
       android:fitsSystemWindows="true"
       android:layout_height="match_parent">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/appbarlayout"
       android:theme="@style/Theme.Design.Light.NoActionBar"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.CollapsingToolbarLayout
   android:layout_width="match_parent"
   app:layout_scrollFlags="scroll|exitUntilCollapsed"
   android:id="@+id/collapsing"
   app:expandedTitleGravity="left|bottom"
   app:contentScrim="@color/white"
   app:collapsedTitleGravity="left"
   android:layout_height="wrap_content">
   <ImageView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:src="@mipmap/two"/>

   <androidx.appcompat.widget.Toolbar
       android:id="@+id/toolbar"
       android:layout_width="match_parent"
       android:layout_height="?attr/actionBarSize"
       android:theme="@style/Theme.Design.Light.NoActionBar"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent"
       app:layout_collapseMode="pin"
       app:popupTheme="@style/Base.ThemeOverlay.AppCompat.Dark" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
       <com.google.android.material.tabs.TabLayout
           android:id="@+id/tablayout"
           android:layout_width="match_parent"
           android:layout_height="50dp"
           app:tabGravity="fill"

           android:theme="@style/Theme.Design.Light.NoActionBar"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toBottomOf="@+id/toolbar" />

   </com.google.android.material.appbar.AppBarLayout>

       <androidx.viewpager2.widget.ViewPager2
           android:id="@+id/viewpager2"
           app:layout_behavior="@string/appbar_scrolling_view_behavior"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
          />

       <com.google.android.material.floatingactionbutton.FloatingActionButton
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginEnd="40dp"
       android:layout_marginBottom="40dp"
       android:id="@+id/floatingbutton"
       android:layout_gravity="right|bottom"
       android:src="@drawable/ic_baseline_add_24"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent" />

   </androidx.coordinatorlayout.widget.CoordinatorLayout>
   <com.google.android.material.navigation.NavigationView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/navigationView"
       app:menu="@menu/menu"
       app:headerLayout="@layout/head"
       android:layout_gravity="left"/>
</androidx.drawerlayout.widget.DrawerLayout>

注意我在ViewPager2写了句

app:layout_behavior="@string/appbar_scrolling_view_behavior"

这个必须要写


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。