<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ConstraintLayout2.0一篇寫不完之極坐標布局與動畫

          共 12729字,需瀏覽 26分鐘

           ·

          2021-08-16 04:00


          點擊上方藍字關(guān)注我,知識會給你力量

          相對于一般布局方式的笛卡爾坐標系,MotionLayout還拓展了ConstraintLayout中的相對中心布局方式,我們暫且稱之為「極坐標布局」方式。

          極坐標布局方式在某些場景下,比笛卡爾坐標系的建立更加方便,特別是涉及到一些圓周運動和相對中心點運動的場景。

          Rotational OnSwipe

          在OnSwipe的基礎(chǔ)上,極坐標方式拓展了運動的方向,給dragDirection增加了dragClockwise和dragAnticlockwise參數(shù),用于設(shè)置OnSwipe的順時針滑動和逆時針滑動,這兩個屬性,在設(shè)置rotationCenterId后才會生效。那么借助這個,就可以很方便的實現(xiàn)一些圓形路徑的滑動效果和動畫。

          通過下面這個例子,我們來看下Rotational OnSwipe的使用方法。

          首先,極坐標的布局還是借助ConstraintLayout,代碼如下所示。

          <?xml version="1.0" encoding="utf-8"?>
          <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:id="@+id/motionLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#cfc"
              app:layoutDescription="@xml/motion_01_dial_scene"
              app:motionDebug="SHOW_ALL">

              <TextView
                  android:id="@+id/number1"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="1"
                  android:textSize="24sp"
                  app:layout_constraintCircle="@id/dial"
                  app:layout_constraintCircleAngle="73"
                  app:layout_constraintCircleRadius="112dp"
                  app:layout_constraintTag="hop" />

             ......

              <TextView
                  android:id="@+id/number0"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="0"
                  android:textSize="24sp"
                  app:layout_constraintCircle="@id/dial"
                  app:layout_constraintCircleAngle="172"
                  app:layout_constraintCircleRadius="112dp"
                  app:layout_constraintTag="hop" />

              <ImageView
                  android:id="@+id/dial"
                  android:layout_width="300dp"
                  android:layout_height="300dp"
                  android:src="@drawable/dial"
                  app:layout_constraintBottom_toBottomOf="parent"
                  app:layout_constraintEnd_toEndOf="parent"
                  app:layout_constraintHorizontal_bias="0.6"
                  app:layout_constraintStart_toStartOf="parent"
                  app:layout_constraintTag="center"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintVertical_bias="0.8" />

              <ImageView
                  android:id="@+id/dialhook"
                  android:layout_width="70dp"
                  android:layout_height="70dp"
                  android:src="@drawable/dial_hook"
                  app:layout_constraintCircle="@id/dial"
                  app:layout_constraintCircleAngle="122"
                  app:layout_constraintCircleRadius="112dp"
                  app:layout_constraintTag="hop" />

          </androidx.constraintlayout.motion.widget.MotionLayout>

          極坐標布局就是借助layout_constraintCircle、layout_constraintCircleAngle、layout_constraintCircleRadius來確定圓心、角度和半徑,從而實現(xiàn)極坐標的布局,接下來,再通過OnSwipe來實現(xiàn)圓形滑動效果。

          <?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"
              motion:defaultDuration="2000">

              <ConstraintSet android:id="@+id/start">
                  <Constraint android:id="@+id/dial">
                      <Transform android:rotation="0" />
                  </Constraint>
              </ConstraintSet>

              <ConstraintSet android:id="@+id/end">
                  <Constraint android:id="@+id/dial">
                      <Transform android:rotation="300" />
                  </Constraint>
              </ConstraintSet>

              <Transition
                  motion:autoTransition="animateToStart"
                  motion:constraintSetEnd="@+id/end"
                  motion:constraintSetStart="@+id/start"
                  motion:duration="1000"
                  motion:motionInterpolator="easeIn">

                  <OnSwipe
                      motion:dragDirection="dragClockwise"
                      motion:dragScale=".9"
                      motion:maxAcceleration="10"
                      motion:maxVelocity="50"
                      motion:onTouchUp="autoCompleteToStart"
                      motion:rotationCenterId="@id/dial" />
                  <KeyFrameSet>

                  </KeyFrameSet>
              </Transition>
          </MotionScene>

          核心就在OnSwipe中,設(shè)置rotationCenterId后,再設(shè)置滑動的方向為順時針即可,展示如下所示。

          image-20302

          Relative Animation

          在MotionLayout中,它進一步加強了在動畫中對極坐標運動的支持,特別是一些極坐標的相對運動動畫,可以通過MotionLayout,以非常簡單的方式表現(xiàn)出來。我們舉個簡單的例子,一個行星環(huán)繞的動畫,如下所示。

          image-208867

          我們可以發(fā)現(xiàn),這個動畫的軌跡是非常復(fù)雜的,太陽以自己為中心自傳,地球繞著太陽旋轉(zhuǎn)的同時還在自傳,月球繞著地球旋轉(zhuǎn),衛(wèi)星繞著地球旋轉(zhuǎn)的同時,逐漸遠離地球,靠近月球。

          這樣一個復(fù)雜的極坐標動畫效果,雖然借助ConstraintLayout可以很方便的實現(xiàn)定位布局,但是運動時,卻無法繼續(xù)保持極坐標的依賴關(guān)系,所以,這里需要使用MotionLayout來維持運動時的極坐標約束關(guān)系。

          首先,使用ConstraintLayout來完成起始布局的建立,代碼如下所示。

          <?xml version="1.0" encoding="utf-8"?>
          <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:id="@+id/motionLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#FF003b60"
              app:layoutDescription="@xml/motion_01_motion_scene"
              app:motionDebug="SHOW_ALL">

              <ImageView
                  android:id="@+id/sun"
                  android:layout_width="180dp"
                  android:layout_height="180dp"
                  android:src="@drawable/sun"
                  app:layout_constraintBottom_toBottomOf="parent"
                  app:layout_constraintEnd_toEndOf="parent"
                  app:layout_constraintStart_toStartOf="parent"
                  app:layout_constraintTop_toBottomOf="parent" />

              <TextView
                  android:id="@+id/rocket"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="??"
                  android:textSize="28sp"
                  app:layout_constraintCircle="@id/earth"
                  app:layout_constraintCircleAngle="0"
                  app:layout_constraintCircleRadius="60dp" />

              <androidx.constraintlayout.utils.widget.ImageFilterView
                  android:id="@+id/moon"
                  android:layout_width="16dp"
                  android:layout_height="16dp"
                  android:rotation="-240"
                  android:src="@drawable/moon"
                  app:layout_constraintCircle="@id/earth"
                  app:layout_constraintCircleAngle="0"
                  app:layout_constraintCircleRadius="180dp" />

              <androidx.constraintlayout.utils.widget.ImageFilterView
                  android:id="@+id/earth"
                  android:layout_width="160dp"
                  android:layout_height="160dp"
                  android:src="@drawable/earth"
                  app:layout_constraintCircle="@id/sun"
                  app:layout_constraintCircleAngle="315"
                  app:layout_constraintCircleRadius="200dp" />

          </androidx.constraintlayout.motion.widget.MotionLayout>

          接下來,在Scene文件中,設(shè)置相對運動關(guān)系,代碼如下所示。

          <ConstraintSet android:id="@+id/start">

              <Constraint android:id="@id/earth">
                  <Motion motion:animateRelativeTo="@+id/sun" />
              </Constraint>

              <Constraint android:id="@id/moon">
                  <Motion motion:animateRelativeTo="@+id/earth" />
              </Constraint>

              <Constraint android:id="@+id/rocket">
                  <Motion
                      motion:animateRelativeTo="@+id/earth"
                      motion:motionPathRotate="45" />
              </Constraint>
          </ConstraintSet>

          借助animateRelativeTo來實現(xiàn)Motion中的相對中心點,使用motionPathRotate來設(shè)置旋轉(zhuǎn)的角度。

          ?

          Motion標簽中的motionPathRotate和Constraint標簽中的transitionPathRotate的作用,都是讓其相對于Path旋轉(zhuǎn)一定角度。

          ?

          MotionLayout中新增的屬性非常多,大家可以參考我的這些文章,從各個方面,逐個擊破MotionLayout的各個難點。

          向大家推薦下我的網(wǎng)站 https://xuyisheng.top/  點擊原文一鍵直達

          專注 Android-Kotlin-Flutter 歡迎大家訪問



          往期推薦


          本文原創(chuàng)公眾號:群英傳,授權(quán)轉(zhuǎn)載請聯(lián)系微信(Tomcat_xu),授權(quán)后,請在原創(chuàng)發(fā)表24小時后轉(zhuǎn)載。
          < END >
          作者:徐宜生

          更文不易,點個“三連”支持一下??

          瀏覽 59
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  波多野吉衣一二三区乱码 | 操逼视频免费无码 | 欧美后门菊门交3p视频在线观看 | 国内自拍第一区二区三区 | 欧美日韩在线免费 |