Android新控件之MotionLayout+CoordinatorLayout+TabLayout+ViewPager 懸浮置頂和頂部滑動動畫<八>

效果.gif

近年來,越來越多的類似博客主頁頁面 頂部背景圖搭配文字出現各種各樣的效果,懸浮置吸頂.小飛機飛行效果,原先 使用CoordinatorLayout 控件監(jiān)聽 移動變化然后再給各個控件設置動畫以及屬性,來完成實現效果

效果

  1. 實現懸浮置吸頂
  2. 頂部滑動小飛機飛行動畫效果

思路

CoordinatorLayout+ViewPager+RecyclerView(ScroolView)實現懸浮置吸頂效果,MotionLayout+MotionScene實現頂部橫向滑動實現頂部小飛機飛行和背景圖滑動效果

實現

1. xml布局 activity_viewpager.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"
    android:orientation="vertical">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!-- 頂部布局  配置layout_scrollFlags="scroll|exitUntilCollapsed 實現吸頂-->
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="200dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <!-- 頂部布局以及頂部背景圖滑動小飛機滑動效果 -->
            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/motion_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layoutDescription="@xml/scene_viewpager_top">

                <ImageView
                    android:id="@+id/background"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scaleType="centerCrop"
                    android:src="@drawable/monterey" />

                <ImageView
                    android:id="@+id/textView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@mipmap/iv_fly" />

            </androidx.constraintlayout.motion.widget.MotionLayout>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
        <!-- tab布局 -->
        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white" />
    </com.google.android.material.appbar.AppBarLayout>

    <!-- 底部頁面布局布局(vp中fragment 必須嵌套滑動布局) -->
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:scrollbars="none"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

實現吸頂效果注意:


1.CollapsingToolbarLayout中配置   app:layout_scrollFlags="scroll|exitUntilCollapsed"

2.ViewPager中配置 app:layout_behavior="@string/appbar_scrolling_view_behavior"

3.ViewPager中的fragment 根布局必須是可滑動的布局RecycerView / ScroolView

1. MotionScene布局 scene_viewpager_top.xml

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">
    <!-- 控制動畫屬性  duration時間  motionInterpolator 動畫插值器  constraintSetStart和constraintSetEnd  開始和技術的的ConstraintSet -->
    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start">
        <!-- 動畫中的關鍵點  25  50  75   注意配置旋轉角度-->
        <!-- percentY關鍵點位置屬性 位置為父布局的相對百分比位置 -->
        <!-- parentRelative 關鍵點類型 此類型是父布局的相對位置-->
        <KeyFrameSet>
            <!--關鍵點1-->
            <KeyPosition
                motion:framePosition="25"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@+id/textView"
                motion:percentY=".6" />

            <KeyAttribute
                android:rotation="-10"
                motion:framePosition="25"
                motion:motionTarget="@+id/textView" />

            <!--關鍵點2-->
            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@+id/textView"
                motion:percentY=".8" />

            <KeyAttribute
                android:rotation="40"
                motion:framePosition="50"
                motion:motionTarget="@+id/textView" />
            <!--關鍵點3-->
            <KeyPosition
                motion:framePosition="75"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@+id/textView"
                motion:percentY=".9" />

            <KeyAttribute
                android:rotation="-10"
                motion:framePosition="75"
                motion:motionTarget="@+id/textView" />
        </KeyFrameSet>
    </Transition>

    <!--    配置開始時控件的位置  控件通過id 屬性關聯布局中的屬性-->
    <ConstraintSet android:id="@+id/start">
        <!--  放大平移效果 scaleX 縮放  translationX 橫向移動-->
        <Constraint
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleX="1.2"
            android:scaleY="1.2"
            android:translationX="-10dp" />
        <Constraint
            android:id="@id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginBottom="20dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent" />

    </ConstraintSet>
    <!--    配置結束時控件的位置  控件通過id 屬性關聯布局中的屬性-->
    <ConstraintSet android:id="@+id/end">

        <Constraint
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleX="1.2"
            android:scaleY="1.2"
            android:translationX="10dp" />

        <Constraint
            android:id="@id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>
</MotionScene>

MotionScene 注意事項

1.KeyFrameSet 中KeyPosition關鍵點的配置以及關鍵屬性的對應位置
2.背景圖需要先縮放變大才能執(zhí)行移動位置

3.頁面代碼

package com.wu.material.activity

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import com.wu.material.R
import com.wu.material.adapter.ViewPagerAdapter
import com.wu.material.fragment.DemoFragment


/**
 * @author wkq
 *
 * @date 2022年01月30日 13:54
 *
 *@des
 *
 */

class ViewPagerActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_viewpager)
        initVp()
    }

    private fun initVp() {

        var vp = ViewPagerAdapter(supportFragmentManager)
        vp.addPageFragment(DemoFragment(), "List")
        vp.addPageFragment(DemoFragment(), "Type2")
        vp.addPageFragment(DemoFragment(), "Type3")
        vp.addPageFragment(DemoFragment(), "Type4")
        var pager = findViewById<ViewPager>(R.id.pager)
        var tabs = findViewById<TabLayout>(R.id.tabs)
        var motion_layout = findViewById<MotionLayout>(R.id.motion_layout)
        pager.adapter = vp
        tabs.setupWithViewPager(pager)

        pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
                val progress = (position + positionOffset) / (vp.count - 1)
                motion_layout.progress = progress
            }

            override fun onPageSelected(position: Int) {
            }

            override fun onPageScrollStateChanged(state: Int) {
            }
        })
    }

}

總結

實現縱向(上下)滑動吸頂效果,橫向(左右)滑動頂部布局小飛機飛行以及背景圖平移效果.CoordinatorLayout+CollapsingToolbarLayout+ViewPager+ScrollView實現吸頂效果,MotionLayout實現小飛機以及背景平移效果,簡單的配置實現了上述各種效果簡單方便,大家可以參考以下非常方便

參考文獻

1.Google的MotionLayout介紹說明

2.MotionLayout的文檔簡介

3.MotionLayout 源碼地址

4. 源碼地址

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阀湿,隨后出現的幾起案子瘟滨,更是在濱河造成了極大的恐慌硫麻,老刑警劉巖钞艇,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谷扣,死亡現場離奇詭異撇眯,居然都是意外死亡屠尊,警方通過查閱死者的電腦和手機县遣,發(fā)現死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門糜颠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萧求,你說我怎么就攤上這事其兴。” “怎么了夸政?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵元旬,是天一觀的道長。 經常有香客問我守问,道長匀归,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任耗帕,我火速辦了婚禮穆端,結果婚禮上,老公的妹妹穿的比我還像新娘仿便。我一直安慰自己体啰,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布嗽仪。 她就那樣靜靜地躺著荒勇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钦幔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天常柄,我揣著相機與錄音鲤氢,去河邊找鬼。 笑死西潘,一個胖子當著我的面吹牛卷玉,可吹牛的內容都是我干的。 我是一名探鬼主播喷市,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼相种,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了品姓?” 一聲冷哼從身側響起寝并,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤箫措,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后衬潦,有當地人在樹林里發(fā)現了一具尸體斤蔓,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年镀岛,在試婚紗的時候發(fā)現自己被綠了弦牡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡漂羊,死狀恐怖驾锰,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情走越,我是刑警寧澤椭豫,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站买喧,受9級特大地震影響捻悯,放射性物質發(fā)生泄漏。R本人自食惡果不足惜淤毛,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一今缚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧低淡,春花似錦姓言、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至猪杭,卻和暖如春餐塘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背皂吮。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工戒傻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜂筹。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓需纳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親艺挪。 傳聞我的和親對象是個殘疾皇子不翩,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容