Android初步进阶之Design Support Library库简单使用(二)

上接上一篇文章,继续介绍这个库的使用。

上一篇文章

  1. 使用NavigationView来实现抽屉菜单界面
    上次也说了,我们费劲用Toolbar实现的抽屉式菜单,这不是又有一个封装好的组件吗,都是封装带师。废话不多说,做好就这样:
    在这里插入图片描述
  • 首先,我们在上一篇文章的基础上进行改造,修改主界面的布局文件main_activity.xml。
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:id="@+id/draw_layout"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:id="@+id/layout_out"
        android:orientation="vertical"
        >
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            >
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                />
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tab_layout"
                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/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />
    </LinearLayout>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_header"
        app:menu="@menu/draw_mean"
        />
</androidx.drawerlayout.widget.DrawerLayout>
  • 然后,创建要放入NavigationView的界面,navigation_header.xml。那个image01是我的图片资源。
<?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:layout_height="150dp"
    android:background="?attr/colorPrimaryDark"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    >
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="50dp"
        android:background="@mipmap/image01"
        android:scaleType="centerCrop"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:text="穹我此生-皆无悔恨"
        android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionMode.Title"
        android:textSize="20sp"
        />
</LinearLayout>
  • 修改主活动的代码
import android.app.Activity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout

class MainActivity :AppCompatActivity() {
    var mDrawerLayout:DrawerLayout? = null
    var mViewPager:ViewPager? = null
    var mTabLayout:TabLayout? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        initViewPager()
    }
    fun initViewPager(){
        mTabLayout = findViewById(R.id.tab_layout)
        mViewPager = findViewById(R.id.view_pager)
        val titles = ArrayList<String>()
        val fragments= ArrayList<Fragment>()
        titles.add("精选")
        titles.add("体育")
        titles.add("巴萨")
        titles.add("购物")
        titles.add("明星")
        titles.add("精选")
        titles.add("体育")
        titles.add("巴萨")
        titles.add("购物")
        titles.add("明星")
        //初始化tab与fragment
        titles.forEach { mTabLayout!!.addTab(mTabLayout!!.newTab().setText(it)); fragments.add(ListFragment()) }
        val mFragmentAdapter:FragmentAdapter = FragmentAdapter(this.supportFragmentManager, fragments, titles)
        mViewPager!!.adapter = mFragmentAdapter
        mTabLayout!!.setupWithViewPager(mViewPager)
        mTabLayout!!.setTabsFromPagerAdapter(mFragmentAdapter)
        //在这里设置新的抽屉界面
        val navigationView:NavigationView = findViewById(R.id.navigation_view)
        mDrawerLayout = findViewById(R.id.draw_layout)
        navigationView!!.setNavigationItemSelectedListener {
            it.setChecked(true)
            val title:String = it.title.toString()
            Toast.makeText(applicationContext, title, Toast.LENGTH_SHORT).show()
            mDrawerLayout!!.closeDrawers()
            true
        }
    }
}

这就OK啦。

  1. 使用CoordinatorLayout来实现ToolBar的隐藏和折叠

像大多数的APP,我们在向上滑动的时候,上面的toolbar都会进行折叠,目的是带来更加宽阔的视野。可以方便地采用CoordinatorLayout来实现,这个效果。

  • 首先,修改我们的主页面main_activity.xml。
<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:fitsSystemWindows="true"
    android:id="@+id/coordinator_layout"
    tools:context=".MainActivity"
    >
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            >
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                />
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tab_layout"
                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/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:clickable="true"
            android:onClick="checkin"
            android:src="@drawable/abc_vector_test"
            app:layout_anchor="@id/view_pager"
            app:layout_anchorGravity="bottom|right|end"
            />
            <!--特别注意, layout_anchor的指向,不能指向父布局,否则,会报错-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>

放入了,一个浮动的按钮。

  • 然后,修改一点主活动代码MainActivity.kt。
import android.app.ActionBar
import android.app.Activity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout

class MainActivity :AppCompatActivity() {
    var mViewPager:ViewPager? = null
    var mTabLayout:TabLayout? = null
    var mToolbar:Toolbar? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        initViewPager()
    }
    fun initViewPager(){
    //这里改了一点
        mToolbar = findViewById(R.id.toolbar)
        setSupportActionBar(mToolbar)
        val ab:androidx.appcompat.app.ActionBar = supportActionBar!!
        ab.setDisplayHomeAsUpEnabled(true)
        
        mTabLayout = findViewById(R.id.tab_layout)
        mViewPager = findViewById(R.id.view_pager)
        val titles = ArrayList<String>()
        val fragments= ArrayList<Fragment>()
        titles.add("精选")
        titles.add("体育")
        titles.add("巴萨")
        titles.add("购物")
        titles.add("明星")
        titles.add("精选")
        titles.add("体育")
        titles.add("巴萨")
        titles.add("购物")
        titles.add("明星")
        //初始化tab与fragment
        titles.forEach { mTabLayout!!.addTab(mTabLayout!!.newTab().setText(it)); fragments.add(ListFragment()) }
        val mFragmentAdapter:FragmentAdapter = FragmentAdapter(this.supportFragmentManager, fragments, titles)
        mViewPager!!.adapter = mFragmentAdapter
        mTabLayout!!.setupWithViewPager(mViewPager)
        mTabLayout!!.setTabsFromPagerAdapter(mFragmentAdapter)
    }
    //点击浮动按钮触发
    fun checkin(view:View):Unit{
        Snackbar.make(view, "点击", Snackbar.LENGTH_SHORT)
            .setAction("评论", View.OnClickListener {  })
            .setDuration(BaseTransientBottomBar.LENGTH_SHORT)
            .show()
    }
}

滑动效果:
在这里插入图片描述

  1. 那么,我想不仅仅折叠Toolbar,我还想,把其它组件连同它一起折叠了呢?这个时候,就需要用到CollapsingToolbarLayout布局了。
    这个组件,会将自己包裹的组件(包括Toolbar)一起进行滑动时的折叠.
  • 首先,修改主布局文件main_activity.xml文件。
<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:fitsSystemWindows="true"
    android:id="@+id/coordinator_layout"
    tools:context=".MainActivity"
    >
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            >
            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/collapsing_toolbar"
                android:fitsSystemWindows="true"
                app:contentScrim="?attr/colorPrimary"
                app:expandedTitleMarginEnd="64dp"
                app:expandedTitleMarginStart="48dp"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                >
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fitsSystemWindows="true"
                    android:scaleType="centerCrop"
                    android:src="@mipmap/image01"
                    />
                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin"
                    app:layout_scrollFlags="scroll|enterAlways"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    />
            </com.google.android.material.appbar.CollapsingToolbarLayout>
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tab_layout"
                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/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:clickable="true"
            android:onClick="checkin"
            android:src="@drawable/abc_vector_test"
            app:layout_anchor="@id/view_pager"
            app:layout_anchorGravity="bottom|right|end"
            />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

加入ScollapsingToolbarLayout布局。

  • 然后,修改主活动,设定一下标题
val collapsingToolbar:CollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar)
collapsingToolbar.title = "春日野穹"
  • 最后,修改一下RecyclerView的布局。就是ListFragment.kt
val mRecyclerView = contentView.findViewById<RecyclerView>(R.id.list)
mRecyclerView.layoutManager = StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL)
mRecyclerView.itemAnimator = DefaultItemAnimator()

效果如下:
在这里插入图片描述滑上去后:
在这里插入图片描述

  1. 其实上面那个效果,也是封装出来的,毕竟封装带师。下面,就说一说行为的定义吧。自定义Behavior也有用到,也就是上面的@string/appbar_scolling_view_behavior。下面实现一个向下滑动底部导航消失,向上滑动出现的行为。
    一般来说有两种方式,分别是:
  • 定义的View监听CoordinatorLayout里的滑动状态
  • 定义的View监听另一个View的状态变化。

第一种

  • 创建的行为
package com.example.compant

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewPropertyAnimator
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import java.util.jar.Attributes

class FooterBehavior(val context: Context, val attrs:AttributeSet) : CoordinatorLayout.Behavior<View>(context, attrs){
    private var directionChange:Int = 0
    /**
     *
     */
    override fun onStartNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: View,
        directTargetChild: View,
        target: View,
        axes: Int,
        type: Int
    ): Boolean {
        return axes and ViewCompat.SCROLL_AXIS_VERTICAL !== 0
    }
    /**
     *
     */
    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: View,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        println(1234)
        if(dy > 0 && directionChange < 0 || dy < 0 && directionChange > 0){
            child.animate().cancel()
            directionChange = 0
        }
        directionChange += dy
        if(directionChange > child.height && child.visibility == View.VISIBLE){
            hide(child)
        }else if(directionChange < 0 && child.visibility == View.GONE){
            show(child)
        }else{

        }

    }
    /**
     * 隐藏函数
     */
    private fun hide(view:View){
        val animator:ViewPropertyAnimator = view.animate().translationY(view.height.toFloat())
            .setInterpolator(object :FastOutSlowInInterpolator(){})
            .setDuration(200)
        animator.setListener(object :AnimatorListenerAdapter(){
            override fun onAnimationEnd(animation: Animator?) {
                view.visibility = View.GONE
            }
        })
        animator.start()
    }
    /**
     * 显示函数
     */
    private fun show(view:View):Unit{
        val animator:ViewPropertyAnimator = view.animate().translationY(0F)
            .setInterpolator(object :FastOutSlowInInterpolator(){})
            .setDuration(200)
        animator.setListener(object :AnimatorListenerAdapter(){
            override fun onAnimationEnd(animation: Animator?) {
                view.visibility = View.VISIBLE
            }
        })
        animator.start()
    }
}

第二种方式

  • 创建行为
package com.example.compant

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.appbar.AppBarLayout

class FooterMyBehavior(val context: Context, val attrs: AttributeSet) : CoordinatorLayout.Behavior<View>(context, attrs){
    override fun layoutDependsOn(
        parent: CoordinatorLayout,
        child: View,
        dependency: View
    ): Boolean {
        return dependency::class == AppBarLayout::class
    }

    override fun onDependentViewChanged(
        parent: CoordinatorLayout,
        child: View,
        dependency: View
    ): Boolean {
        var translatetionY:Float = Math.abs(dependency.y)
        child.translationY = translatetionY
        return true
    }
}
  • 把行为设置为app:layout_behavior就可以了。
app:layout_behavior="com.example.compant.FooterMyBehavior"

特别说明,第一种存在问题,应该是Android的库版本问题,这个在低版本里面可以完美实现的行为,而在较高的版本中,会出现只会检测到第一次滑动的Bug。这个是这个版本中RecyclerView和这个组件有冲突导致的结果。

好了,我了解的组件介绍完了!$_¥

上一篇文章

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值