实现的的效果
描述:一开始是完全显示的,然后高度慢慢减少,图片自上而下消失。还有就是左右慢慢展开
分析:这个效果看似很简单,但是实际上根据常规的android机制,是很难以实现的。
解决方案
想了很久,突然联想到MeasureSpec的三种情况(自适应,合父布局一样和绝对大小)。感觉图像设置为绝对大小并且靠底部对齐。然后自上而下减少外布局高度,应该可以实现效果。
一、慢慢折叠与向下展开动画
1.自定义绝对大小的Imageview
package com.ruidde.csndresourcedemo.img;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import androidx.annotation.Nullable;
@SuppressLint("AppCompatCustomView")
public class AnimImageView extends ImageView {
private static final int IMAGE_HEIGHT = 500;
public AnimImageView(Context context) {
super(context);
}
public AnimImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs, 0);
}
public AnimImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr, 0);
}
/**
* 设置的高度最好是bitmap的高度,这样不好压缩变形。这里写死了
* @param widthMeasureSpec 宽度
* @param heightMeasureSpec 高度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, IMAGE_HEIGHT);
// setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
实现效果的关键不过就是一行代码:
setMeasuredDimension(widthMeasureSpec, CommonUtil.dip2px(IMAGE_HEIGHT));
2.XML文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@color/white"
tools:context=".MainActivity">
<Button
android:id="@+id/bt_scale_big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="向上展开" />
<Button
android:id="@+id/bt_scale_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/bt_scale_big"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="慢慢折叠" />
<RelativeLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_below="@+id/bt_scale_small">
<com.ruidde.csndresourcedemo.img.AnimImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:src="@mipmap/two" />
</RelativeLayout>
</RelativeLayout>
3.Activity中代码
package com.ruidde.csndresourcedemo;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
public class AnimImageActivity extends Activity implements View.OnClickListener {
private RelativeLayout mContentLayout;
private RelativeLayout.LayoutParams mLayoutParams;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anim);
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
}
findIds();
}
private void findIds() {
mContentLayout = findViewById(R.id.ll_content);
findViewById(R.id.bt_scale_big).setOnClickListener(this);
findViewById(R.id.bt_scale_small).setOnClickListener(this);
mLayoutParams = (RelativeLayout.LayoutParams) mContentLayout.getLayoutParams();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_scale_big:
animScaleBig();
break;
case R.id.bt_scale_small:
animScaleSmall();
break;
default:
break;
}
}
private void animScaleBig() {
ValueAnimator scaleBig = ValueAnimator.ofFloat(100, 500);
scaleBig.setInterpolator(new LinearInterpolator());
scaleBig.setDuration(1000);
scaleBig.addUpdateListener(mListener);
scaleBig.start();
}
private ValueAnimator.AnimatorUpdateListener mListener = new ValueAnimator
.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mLayoutParams.height = (int) (float) animation.getAnimatedValue();
mContentLayout.setLayoutParams(mLayoutParams);
}
};
private void animScaleSmall() {
ValueAnimator scaleBig = ValueAnimator.ofFloat(500, 100);
scaleBig.setInterpolator(new LinearInterpolator());
scaleBig.setDuration(1000);
scaleBig.addUpdateListener(mListener);
scaleBig.start();
}
}
二、左右慢慢展开
1.XML文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 这里imageView的src定义为clipdrawable资源 -->
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/drawable_clip" />
</LinearLayout>
2.Activity代码
package com.ruidde.csndresourcedemo;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.drawable.ClipDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import java.util.Timer;
import java.util.TimerTask;
/**
* 图片的慢慢展开动画
*/
public class ClipDrawableActivity extends Activity {
private ImageView imageView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clip_drawable);
imageView = (ImageView) findViewById(R.id.image);
//获取图片所显示的ClipDrawble对象
ClipDrawable clipdrawable = (ClipDrawable) imageView.getDrawable();
initDate(clipdrawable);
}
public void initDate(final ClipDrawable clipdrawable) {
/**
* Handler
* */
@SuppressLint("HandlerLeak") final Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x1233) {
//修改ClipDrawable的level值
clipdrawable.setLevel(clipdrawable.getLevel() + 500);
}
}
};
/**
* 计时器
* */
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
Message msg = new Message();
msg.what = 0x1233;
//发送消息,通知应用修改ClipDrawable对象的level值
handler.sendMessage(msg);
//取消定时器
if (clipdrawable.getLevel() >= 10000) {
timer.cancel();
}
}
}, 0, 300);
}
}