一、概述
前几天接到一个需求,就是一个LinearLayout从屏幕的中间划出,之前我是一点头绪没有的的,可是后来我想到了属性动画这个好东西,然后我先和大家说一下我的思路:
1、首先我们要实现的就是滑动出来,这个还是比较简单的,我们只需要用一个属性动画向上滑动就可以了。
2、我们要实现LinearLayout从屏幕中间出来,我是这么想的,我们动态去改变viewLinearLayout高度,通过他滑动了多少距离,我们就去设置他的高度为多少,这样就可以实现LinearLayout从中间滑出的效果了,但是这样需要有一个前提条件,那么就是LinearLayout中的view高度是要确定的。下面看一下我们的实现:
二、实现
先看一下布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.andy.dynamicsethigthdemo.MainActivity">
<Button
android:id="@+id/to_top"
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上移"/>
<Button
android:id="@+id/to_bottom"
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上移"/>
<LinearLayout
android:id="@+id/transfer_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:layout_marginTop="100dp">
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="已取消"
android:gravity="center"
android:background="@color/colorPrimary"/>
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="已完成"
android:gravity="center"
android:background="@color/colorAccent"/>
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="已发送"
android:gravity="center"
android:background="#ffff00"/>
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="待出车"
android:gravity="center"
android:background="@color/colorPrimary"/>
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="待确认"
android:gravity="center"
android:background="#ffa500"/>
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="待评价"
android:gravity="center"
android:background="#ffefd5"/>
<TextView
android:layout_width="100dp"
android:layout_height="30dp"
android:text="待支付"
android:gravity="center"
android:background="@color/colorPrimary"/>
</LinearLayout>
</LinearLayout>
这个布局我只想说一点,那么就是每个Textview的高度一定要是一个固定的值,不能是wrap_content,可以自己实践一下不用固定高度的情况。
好了下面说一下我们滑动的实现,其实滑动的实现还是比较简单的用属性动画直接监听一下就可以了,然后别忘了把你设定的值转为px
下面看代码:
final ValueAnimator valueAnimator = ValueAnimator.ofInt(dp2px(this,400.0f), dp2px(this,190.0f));
valueAnimator.setDuration(1000);
valueAnimator.setTarget(transferLayout);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
transferLayout.setTranslationY((int) valueAnimator.getAnimatedValue());
}
});
final ValueAnimator valueAnimator1 = ValueAnimator.ofInt(dp2px(this,190.0f), dp2px(this,400.0f));
valueAnimator1.setDuration(1000);
valueAnimator1.setTarget(transferLayout);
valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
transferLayout.setTranslationY((int) valueAnimator.getAnimatedValue());
}
});
to_bottom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
valueAnimator1.start();
}
});
topButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
valueAnimator.start();
}
});
}
public static int dp2px(Context context, float dipValue) {
if (context != null) {
if ((float) ViewGroup.LayoutParams.MATCH_PARENT == dipValue) {
return ViewGroup.LayoutParams.MATCH_PARENT;
}
if ((float) ViewGroup.LayoutParams.WRAP_CONTENT == dipValue) {
return ViewGroup.LayoutParams.WRAP_CONTENT;
}
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
return (int) dipValue;
}
其实这个地方也是比较简单好了下面我们看一下设置高度的实现,我们假设移动的范围是200到400,反向的就是400到200,那么,LinearLayout的高度不管向上还是向下移动都是400 - valueAnimator.getAnimatedValue()代码我就不写了 就是在addUpdateListener中加上
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp2px(getBaseContext(), 100.0f), dp2px(getBaseContext(), 400.0f) - (int) valueAnimator.getAnimatedValue()); // LinearLayout.LayoutParams params = transferLayout.getLayoutParams(); params.gravity = Gravity.CENTER_HORIZONTAL; // params.setMarginEnd(); transferLayout.setLayoutParams(params);
就可以完成动态设置高度了。
好了看一下整体程序:
package com.example.andy.dynamicsethigthdemo;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
private LinearLayout transferLayout;
private Button topButton,to_bottom;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
transferLayout = (LinearLayout)findViewById(R.id.transfer_layout);
topButton = (Button)findViewById(R.id.to_top);
to_bottom = (Button)findViewById(R.id.to_bottom);
final ValueAnimator valueAnimator = ValueAnimator.ofInt(dp2px(this,400.0f), dp2px(this,190.0f));
valueAnimator.setDuration(1000);
valueAnimator.setTarget(transferLayout);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp2px(getBaseContext(), 100.0f), dp2px(getBaseContext(), 400.0f) - (int) valueAnimator.getAnimatedValue());
// LinearLayout.LayoutParams params = transferLayout.getLayoutParams();
params.gravity = Gravity.CENTER_HORIZONTAL;
// params.setMarginEnd();
transferLayout.setLayoutParams(params);
transferLayout.setTranslationY((int) valueAnimator.getAnimatedValue());
}
});
final ValueAnimator valueAnimator1 = ValueAnimator.ofInt(dp2px(this,190.0f), dp2px(this,400.0f));
valueAnimator1.setDuration(1000);
valueAnimator1.setTarget(transferLayout);
valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp2px(getBaseContext(), 100.0f), dp2px(getBaseContext(), 400.0f) - (int) valueAnimator.getAnimatedValue());
// LinearLayout.LayoutParams params = transferLayout.getLayoutParams();
params.gravity = Gravity.CENTER_HORIZONTAL;
// params.setMarginEnd();
transferLayout.setLayoutParams(params);
transferLayout.setTranslationY((int) valueAnimator.getAnimatedValue());
}
});
to_bottom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
valueAnimator1.start();
}
});
topButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
valueAnimator.start();
}
});
}
public static int dp2px(Context context, float dipValue) {
if (context != null) {
if ((float) ViewGroup.LayoutParams.MATCH_PARENT == dipValue) {
return ViewGroup.LayoutParams.MATCH_PARENT;
}
if ((float) ViewGroup.LayoutParams.WRAP_CONTENT == dipValue) {
return ViewGroup.LayoutParams.WRAP_CONTENT;
}
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
return (int) dipValue;
}
}
总结:好了这就是view在屏幕中间划出的的实现,切记一定要转换px。如果本文有什么错误或者相关地方有什么问题,欢迎指正和提问。