android平滑动画效果--搜索框
效果一
1、首先需要创建两个activity;
2、在第一个activity中如下
/** * 过度动画 * @param activity * @param sharedElement 执行动画的view */ fun start(activity: Activity, sharedElement: View?) { val intent = Intent(activity, WorkManagementQuerySearchActivity::class.java) val mOptionsCompat = //判断执行动画的view是否为null,如果为null执行自定义动画 if (sharedElement != null) { ActivityOptionsCompat.makeSceneTransitionAnimation( activity, sharedElement, ImageViewerActivity.SHARED_ELEMENT ) } else { ActivityOptionsCompat.makeCustomAnimation( activity, R.anim.iv_anim_in, R.anim.iv_anim_out ) } var bundle: Bundle? = null if (mOptionsCompat != null) { bundle = mOptionsCompat.toBundle() } activity.startActivity(intent, bundle) }
3、在第二个activity
//workQuerySearchEt 需要过度的view ViewCompat.setTransitionName(workQuerySearchEt, ImageViewerActivity.SHARED_ELEMENT)
效果二
1、自定义滑动组件
class AnimationNestedScrollView : NestedScrollView { private var listener: OnAnimationScrollChangeListener? = null constructor(context: Context) : super(context) {} constructor(context: Context, @Nullable attrs: AttributeSet?) : super(context, attrs) {} constructor( context: Context, @Nullable attrs: AttributeSet?, defStyleAttr: Int ) : super(context, attrs, defStyleAttr) { } fun setOnAnimationScrollListener(listener: OnAnimationScrollChangeListener?) { this.listener = listener } interface OnAnimationScrollChangeListener { fun onScrollChanged(dy: Float) } override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) { super.onScrollChanged(l, t, oldl, oldt) if (listener != null) { listener!!.onScrollChanged(scrollY * 0.65f) //x0.65 使位移效果更加平滑 解决手指按住停留时抖动问题 } } }
2、布局文件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context=".SearchAnimActivity"> <RelativeLayout android:id="@+id/search_rl_top" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#3F51B5"> <RelativeLayout android:id="@+id/search_layout" android:layout_width="match_parent" android:layout_height="44dp"> <ImageView android:id="@+id/search_iv_back" android:layout_width="10dp" android:layout_height="20dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:src="@drawable/ic_back" /> <TextView android:id="@+id/search_tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_center android:layout_marginTop="11.5dp" android:gravity="center" android:text="这是标题" android:textColor="#fff" android:textSize="17dp" android:textStyle="bold" /> </RelativeLayout> <LinearLayout android:id="@+id/search_ll_search" android:layout_width="match_parent" android:layout_height="35dp" android:layout_alignParentLeft="true" android:layout_marginLeft="15dp" android:layout_marginTop="49dp" android:layout_marginRight="15dp" android:layout_marginBottom="10dp" android:background="@drawable/activity_search_tv_shape" android:gravity="center_vertical" android:orientation="horizontal" android:visibility="visible"> <ImageView android:layout_width="16dp" android:layout_height="16dp" android:layout_marginLeft="10dp" android:src="@drawable/seace" /> <TextView android:id="@+id/search_tv_search" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="5dp" android:layout_marginRight="10dp" android:layout_weight="1" android:cursorVisible="false" android:gravity="center_vertical|center_horizontal" android:hint="这是搜索框" android:textSize="15dp" /> <ImageView android:layout_width="16dp" android:layout_height="16dp" android:layout_marginRight="10dp" android:src="@drawable/seace" /> </LinearLayout> </RelativeLayout> <com.github.aachartmodel.aainfographics.demo.AnimationNestedScrollView android:id="@+id/search_sv_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/search_rl_top"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="900dp" /> </LinearLayout> </com.github.aachartmodel.aainfographics.demo.AnimationNestedScrollView> </RelativeLayout>
3、代码
private fun initView() { val sv_view = findViewById<AnimationNestedScrollView>(R.id.search_sv_view) val ll_search = findViewById<LinearLayout>(R.id.search_ll_search) val tv_title = findViewById<TextView>(R.id.search_tv_title) val searchLayoutParams = ll_search.getLayoutParams() as MarginLayoutParams val titleLayoutParams = tv_title.getLayoutParams() as MarginLayoutParams val LL_SEARCH_MIN_TOP_MARGIN = dp2px(this, 4.5f);//布局关闭时顶部距离 val LL_SEARCH_MAX_TOP_MARGIN = dp2px(this, 49f);//布局默认展开时顶部距离 val LL_SEARCH_MAX_WIDTH = getScreenWidth(this) - dp2px(this, 30f);//布局默认展开时的宽度 // val LL_SEARCH_MIN_WIDTH = getScreenWidth(this) - dp2px(this, 82f);//布局关闭时的宽度 安 居客的效果的代码 val LL_SEARCH_MIN_WIDTH = getScreenWidth(this) - dp2px(this, 122f);//布局关闭时的宽度 京东效果 val TV_TITLE_MAX_TOP_MARGIN = dp2px(this, 11.5f); sv_view.setOnAnimationScrollListener(object : OnAnimationScrollChangeListener { override fun onScrollChanged(dy: Float) { var searchLayoutNewTopMargin: Float = LL_SEARCH_MAX_TOP_MARGIN - dy // var searchLayoutNewWidth: Float = // LL_SEARCH_MAX_WIDTH - dy * 0.5f //此处 * 1.3f 可以设置搜索框宽度缩放的速率 安 居客的效果的代码 var searchLayoutNewWidth = LL_SEARCH_MAX_WIDTH - dy * 3.0f //此处 * 1.3f 可以设置搜索框宽度缩放的速率 京东效果 val titleNewTopMargin = (TV_TITLE_MAX_TOP_MARGIN - dy * 0.5).toFloat() //处理布局的边界问题 searchLayoutNewWidth = if (searchLayoutNewWidth < LL_SEARCH_MIN_WIDTH) LL_SEARCH_MIN_WIDTH.toFloat() else searchLayoutNewWidth if (searchLayoutNewTopMargin < LL_SEARCH_MIN_TOP_MARGIN) { searchLayoutNewTopMargin = LL_SEARCH_MIN_TOP_MARGIN.toFloat() } if (searchLayoutNewWidth < LL_SEARCH_MIN_WIDTH) { searchLayoutNewWidth = LL_SEARCH_MIN_WIDTH.toFloat() } var titleAlpha: Float = 255 * titleNewTopMargin / TV_TITLE_MAX_TOP_MARGIN if (titleAlpha < 0) { titleAlpha = 0f } //设置相关控件的LayoutParams 此处使用的是MarginLayoutParams,便于设置params的topMargin属性 tv_title.setTextColor(tv_title.getTextColors().withAlpha(titleAlpha.toInt())) titleLayoutParams.topMargin = titleNewTopMargin.toInt() tv_title.setLayoutParams(titleLayoutParams) searchLayoutParams.topMargin = searchLayoutNewTopMargin.toInt() searchLayoutParams.width = searchLayoutNewWidth.toInt() ll_search.setLayoutParams(searchLayoutParams) } }) } fun dp2px(context: Context?, dpValue: Float): Int { if (null == context) { return 0 } val scale: Float = context.getResources().getDisplayMetrics().density return (dpValue * scale + 0.5f).toInt() } fun getScreenWidth(context: Context?): Int { return if (null == context) { 0 } else context.getResources().getDisplayMetrics().widthPixels }
4、效果切换
实现京东的效果,布局文件只需要设置search_ll_search的属性即可:
a、xml
android:layout_centerHorizontal="true"
替换成
android:layout_alignParentLeft="true"
b、
1.修改搜索栏的最小宽度:
val LL_SEARCH_MIN_WIDTH = getScreenWidth(this) - dp2px(this, 82f);//布局关闭时的宽度 安 居客的效果的代码
val LL_SEARCH_MIN_WIDTH = getScreenWidth(this) - dp2px(this, 122f);//布局关闭时的宽度 京东效果
2.设置搜索框宽度缩放的速率
// var searchLayoutNewWidth: Float =
// LL_SEARCH_MAX_WIDTH - dy * 0.5f //此处 * 1.3f 可以设置搜索框宽度缩放的速率 安 居客的效果的代码
var searchLayoutNewWidth =
LL_SEARCH_MAX_WIDTH - dy * 3.0f //此处 * 1.3f 可以设置搜索框宽度缩放的速率 京东效果
最总效果