1 Star 0 Fork 0

lany168/TransitionLayout

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0
<h1 align="center">TransitionLayout</h1></br> <p align="center"> 🌠 Transform into a different view or activity using morphing animations. <br>Using<a href="https://material.io/design/motion/the-motion-system.html" target="_blank"> Transition motions </a> of new material version. </p> </br> <p align="center"> <a href="https://devlibrary.withgoogle.com/products/android/repos/skydoves-TransitionLayout"><img alt="Google" src="https://skydoves.github.io/badges/google-devlib.svg"/></a><br> <a href="https://opensource.org/licenses/Apache-2.0"><img alt="License" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"/></a> <a href="https://android-arsenal.com/api?level=21"><img alt="API" src="https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat"/></a> <a href="https://github.com/skydoves/TransitionLayout/actions"><img alt="Build Status" src="https://github.com/skydoves/TransitionLayout/workflows/Android%20CI/badge.svg"/></a> <a href="https://github.com/skydoves"><img alt="Profile" src="https://skydoves.github.io/badges/skydoves.svg"/></a> </p> ## Download Go to the [Releases](https://github.com/skydoves/TransitionLayout/releases) to download the demo APK. ## Screenshots <p align="center"> <img src="/preview/preview0.gif" width="32%"/> <img src="/preview/preview1.gif" width="32%"/> <img src="/preview/preview2.gif" width="32%"/> </p> ## Including in your project [![Maven Central](https://img.shields.io/maven-central/v/com.github.skydoves/transformationlayout.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.github.skydoves%22%20AND%20a:%22transformationlayout%22) [![JitPack](https://jitpack.io/v/skydoves/TransitionLayout.svg)](https://jitpack.io/#skydoves/TransitionLayout) ### Gradle Add below codes to your **root** `build.gradle` file (not your module build.gradle file). ```gradle allprojects { repositories { mavenCentral() } } ``` And add a dependency code to your **module**'s `build.gradle` file. ```gradle dependencies { implementation "com.github.skydoves:transformationlayout:1.1.1" } ``` ## Usage Add following XML namespace inside your XML layout file. ```gradle xmlns:app="http://schemas.android.com/apk/res-auto" ``` ### TransitionLayout Here is a basic example of implementing `TransitionLayout`. <br> We must wrap one or more views that we want to transform. ```gradle <com.github.lany192.layout.TransitionLayout android:layout_width="wrap_content" android:layout_height="wrap_content" app:transformation_targetView="@+id/my_cardView" // sets a target view. app:transformation_duration="450" // sets a duration of the transformation. app:transformation_direction="auto" // auto, entering, returning app:transformation_fadeMode="in" // in, out, cross, through app:transformation_fitMode="auto" // auto, height, width app:transformation_pathMode="arc" // arc, linear > <!-- other views --> </com.github.lany192.layout.TransitionLayout> ``` ### Transform into a view Here is a simple example of transform fab into a view. <img src="https://user-images.githubusercontent.com/24237865/75549488-25321700-5a73-11ea-8908-609592907e84.gif" align="right" width="32%"/> ```gradle <com.github.lany192.layout.TransitionLayout android:id="@+id/transformationLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" app:transformation_duration="550" app:transformation_targetView="@+id/myCardView"> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:backgroundTint="@color/colorPrimary" android:src="@drawable/ic_write"/> </com.github.lany192.layout.TransitionLayout> <com.google.android.material.card.MaterialCardView android:id="@+id/myCardView" android:layout_width="240dp" android:layout_height="312dp" android:layout_marginLeft="30dp" android:layout_marginTop="30dp" app:cardBackgroundColor="@color/colorPrimary" /> ``` #### Bind a TargetView We can bind a targetView that will be transformed from the `TransitionLayout` using the below attribute in XML.<br> If you bind a targetView to the `TransitionLayout`, the targetView's visibility will be `GONE`. ```gradle app:transformation_targetView="@+id/myCardView" ``` Or we can bind a targetView using method. ```kotlin transformationLayout.bindTargetView(myCardView) ``` #### Starting and finishing the transformation After binding a targetView, we can start or finish transformation using the below methods.<br> ```kotlin // start transformation when touching the fab. fab.setOnClickListener { transformationLayout.startTransform() } // finish transformation when touching the myCardView. myCardView.setOnClickListener { transformationLayout.finishTransform() } ``` Here are other functionalities to starting and finishing transformation. ```kotlin // starts and finishes transformation 1000 milliseconds later. // If we use this method on onCreate() method, it will starts transformation automatically 200ms later. transformationLayout.startTransformWithDelay(200) transformationLayout.finishTransformWithDelay(200) // starts and finishes transformation with stopping a parent layout. transformationLayout.startTransform(parent) transformationLayout.finishTransform(parent) ``` ### OnTransformFinishListener We can listen a `TransitionLayout` is transformed or not using `OnTransformFinishListener`. <br> ```kotlin transformationLayout.setOnTransformFinishListener { Toast.makeText(context, "is transformed: $it", Toast.LENGTH_SHORT).show() } ``` Here is the __Java__ way. ```java transformationLayout.onTransformFinishListener=new OnTransformFinishListener(){ @Override public void onFinish(boolean isTransformed){ Toast.makeText(context,"is transformed:"+isTransformed,Toast.LENGTH_SHORT).show(); } }; ``` ### Transform into an Activity We can implement transformation between activities easily using `TransitionActivity` and `TransitionCompat`. <img src="/preview/preview2.gif" align="right" width="32%"/> Here is an example of transforming a floating action button to Activity. <br> We don't need to bind a targetView. ```gradle <com.github.lany192.layout.TransitionLayout android:id="@+id/transformationLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" app:transformation_duration="550"> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:backgroundTint="@color/colorPrimary" android:src="@drawable/ic_write"/> </com.github.lany192.layout.TransitionLayout> ``` #### onTransitionStartContainer We should add `onTransitionStartContainer()` to the Activity that has the floating action button. If your view is in the fragment, the code should be added to the fragment's Activity. It must be called before `super.onCreate`. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { onTransitionStartContainer() // should be called before super.onCreate(). super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } ``` Here is the Java way. ```java TransitionCompat.onTransitionStartContainer(this); ``` #### TransitionAppCompatActivity Extends `TransitionAppCompatActivity` or `TransitionActivity` to your activity that will be transformed. ```kotlin class DetailActivity : TransitionAppCompatActivity() ``` Here is the Java way. ```java public class DetailActivity extends TransitionAppCompatActivity ``` #### TransitionCompat And start the `DetailActivity` using the `TransitionCompat.startActivity` method. ```kotlin val intent = Intent(context, DetailActivity::class.java) TransitionCompat.startActivity(transformationLayout, intent) ``` Here is the Java way. ```java Intent intent=new Intent(context,DetailActivity.class); TransitionCompat.startActivity(transformationLayout,intent); ``` ### Manually Transform into an Activity <img src="/preview/preview2.gif" align="right" width="32%"/> Here is an example of transforming a floating action button to Activity. <br> We don't need to bind a targetView. ```gradle <com.github.lany192.layout.TransitionLayout android:id="@+id/transformationLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" app:transformation_duration="550"> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:backgroundTint="@color/colorPrimary" android:src="@drawable/ic_write"/> </com.github.lany192.layout.TransitionLayout> ``` #### onTransitionStartContainer We should add `onTransitionStartContainer()` to the Activity that has the floating action button. If your view is in the fragment, the code should be added to the fragment's Activity. It must be called before `super.onCreate`. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { onTransitionStartContainer() // should be called before super.onCreate(). super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } ``` Here is the Java way. ```java TransitionCompat.onTransitionStartContainer(this); ``` #### startActivity And we should call `startActivity` with bundle and intent data.<br> We should get a `bundle` using `withActivity` method. It needs a context and any name of transition. <br> The `bundle` must be used as `startActivity`'s parameter.<br> We should put parcelable data to the intent using `getParcelableParams()` method.<br> The extra name of the parcelable data can be anything, and it will be reused later. ```kotlin fab.setOnClickListener { val bundle = transformationLayout.withActivity(this, "myTransitionName") val intent = Intent(this, DetailActivity::class.java) intent.putExtra("TransitionParams", transformationLayout.getParcelableParams()) startActivity(intent, bundle) } ``` If we want to get bundle data in RecyclerView or other classes, <br> we can use `withView` and `withContext` instead of `withActivty`. ```kotlin // usage in the RecyclerView.Adapter override fun onBindViewHolder(holder: PosterViewHolder, position: Int) { val bundle = transformationLayout.withView(holder.itemView, "myTransitionName") } ``` Here is the __Java__ way. ```java Bundle bundle=transformationLayout.withActivity(this,"myTransitionName"); Intent intent=new Intent(this,DetailActivity.class); intent.putExtra("TransitionParams",transformationLayout.getParcelableParams()); startActivity(intent,bundle); ``` #### onTransitionEndContainer And finally, we should add `onTransitionEndContainer()` to the Activity that will be started. <br> It must be added before `super.onCreate`. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { onTransitionEndContainer(intent.getParcelableExtra("TransitionParams")) super.onCreate(savedInstanceState) setContentView(R.layout.activity_detail) } ``` Here is the __Java__ way. ```java TransitionLayout.Params params=getIntent().getParcelableExtra("TransitionParams"); TransitionCompat.onTransitionEndContainer(this,params); ``` ### Transform into a Fragment We can implement transformation between fragments for a single Activity application.<br> Here is an example of transforming a floating action button in Fragment A to Fragment B. <img src="https://user-images.githubusercontent.com/24237865/80108763-a1e6fa80-85b7-11ea-9350-f9d8ebc46310.gif" align="right" width="32%"/> ```gradle <com.github.lany192.layout.TransitionLayout android:id="@+id/transformationLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" app:transformation_duration="550"> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:backgroundTint="@color/colorPrimary" android:src="@drawable/ic_write"/> </com.github.lany192.layout.TransitionLayout> ``` #### onTransitionStartContainer We should call `onTransitionStartContainer()` in the Fragment A that has the floating action button. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) onTransitionStartContainer() } ``` Here is the Java way. ```java TransitionCompat.onTransitionStartContainer(this); ``` #### getBundle and addTransition We should get a bundle from the `TransitionLayout` and put it into the argument.<br> And in the fragment manager's transaction, we should add the `TransitionLayout` using `addTransition` method. ```kotlin val fragment = MainSingleDetailFragment() val bundle = transformationLayout.getBundle("TransitionParams") bundle.putParcelable(MainSingleDetailFragment.posterKey, poster) fragment.arguments = bundle requireFragmentManager() .beginTransaction() .addTransition(transformationLayout) .replace(R.id.main_container, fragment, MainSingleDetailFragment.TAG) .addToBackStack(MainSingleDetailFragment.TAG) .commit() } ``` Here is the Java way ```java MainSingleDetailFragment fragment=new MainSingleDetailFragment(); Bundle bundle=transformationLayout.getBundle("TransitionParams","transitionName"); fragment.setArguments(bundle); FragmentTransaction fragmentTransaction=requireFragmentManager().beginTransaction(); TransitionCompat.addTransition( fragmentTransaction,transformationLayout,"transitionName"); fragmentTransaction.replace(R.id.main_container,fragment,MainSingleDetailFragment.TAG) .addToBackStack(MainSingleDetailFragment.TAG) .commit(); ``` #### Transition name in Fragment A We must set a specific transition name to the `TransitionLayout`.<br> If you want to transform a recyclerView's item, set transiton name in `onBindViewHolder`. ```kotlin transformationLayout.transitionName = "myTransitionName" ``` Here is the Java way. ```java transformationLayout.setTransitionName("myTransitionName"); ``` #### onTransitionEndContainer in Fragment B We should get a `TransitionLayout.Params` from the arguments, and call `onTransitionEndContainer` method.<br> It must be called in `onCreate` method. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val params = arguments?.getParcelable<TransitionLayout.Params>("TransitionParams") onTransitionEndContainer(params) } ``` Here is the Java way. ```java TransitionLayout.Params params=getArguments().getParcelable("TransitionParams"); TransitionCompat.onTransitionEndContainer(this,params); ``` #### Transition name in Fragment B And finally set the specific transition name (same as the transformationLayot in Fragment A) <br> to the target view in Fragment B in `onViewCreated`. ```kotlin override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) detail_container.transitionName = "myTransitionName" } ``` ## TransitionLayout Attributes Attributes | Type | Default | Description --- | --- | --- | --- targetView | resource id | none | Bind a targetView that will be transformed. duration | Long | 350L | Duration of the transformation. pathMotion | Motion.ARC, Motion.LINEAR | default layout | Indicates that this transition should be drawn as the which path. containerColor | Color | Color.TRANSPARENT | Set the container color to be used as the background of the morphing container. allContainerColor | Color | Color.TRANSPARENT | The all container colors (start and end) to be used as the background of the morphing container. scrimColor | Color | Color.TRANSPARENT | Set the color to be drawn under the morphing container. direction | Direction.AUTO, Direction.ENTER, Direction.RETURN | Direction.AUTO | Set the direction to be used by this transform. fadeMode | FadeMode.IN, FadeMode.OUT, FadeMode.CROSS, FadeMode.THROUGH | FadeMode.IN | Set the FadeMode to be used to swap the content of the start View with that of the end View. fitMode | FitMode.AUTO, FitMode.WIDTH, FitMode.HEIGHT | FitMode.AUTO | Set the fitMode to be used when scaling the incoming content of the end View. startElevation | Float | ELEVATION_NOT_SET | The elevation that will be used to render a shadow around the container at the start of the transition. endElevation | Float | ELEVATION_NOT_SET | The elevation that will be used to render a shadow around the container at the end of the transition. elevationShadowEnabled | Boolean | true if (version > Pie) | Whether shadows should be drawn around the container to approximate native elevation shadows on the start and end views. holdAtEndEnabled | Boolean | false | Whether to hold the last frame at the end of the animation. ## Additional 🎈 You can reference the usage of the TransitionLayout in another repository [MarvelHeroes](https://github.com/skydoves/MarvelHeroes). <br> A demo application based on modern Android application tech-stacks and MVVM architecture. ![screenshot](https://user-images.githubusercontent.com/24237865/80602029-9426ee80-8a69-11ea-866d-4e31b6526ab2.png) ## Find this library useful? :heart: Support it by joining __[stargazers](https://github.com/skydoves/transformationlayout/stargazers)__ for this repository. :star: <br> And __[follow](https://github.com/skydoves)__ me for my next creations! 🤩 # License ```xml Copyright 2020 skydoves (Jaewoong Eum) Licensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License. ```

简介

暂无描述 展开 收起
Kotlin
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/lany168/TransitionLayout.git
git@gitee.com:lany168/TransitionLayout.git
lany168
TransitionLayout
TransitionLayout
main

搜索帮助