您的位置:首页 > 移动开发 > Android开发

水波效果

2016-01-10 17:57 411 查看


一、水波外扩

资料来源:http://blog.csdn.net/shineflowers/article/details/47280545



布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/wave1"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="@drawable/wateout_wave"
/>
<ImageView
android:id="@+id/wave2"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="@drawable/wateout_wave"/>
<ImageView
android:id="@+id/wave3"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="@drawable/wateout_wave" />
<ImageView
android:id="@+id/btnVoice"
android:layout_width="166dp"
android:layout_height="166dp"
android:layout_centerInParent="true"
android:background="@drawable/wateout_voice" />
</RelativeLayout>

源码:
package com.example.administrator.wavetest;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
public class WaveOutActivity extends AppCompatActivity {
private ImageView mNormal;
private ImageView mWave1;
private ImageView mWave2;
private ImageView mWave3;
private AnimationSet mAnimationSet1;
private AnimationSet mAnimationSet2;
private AnimationSet mAnimationSet3;
private static final int OFFSET = 600;  //每个动画的播放时间间隔
private static final int MSG_WAVE2_ANIMATION = 2;
private static final int MSG_WAVE3_ANIMATION = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wave_out);
mNormal = (ImageView) findViewById(R.id.btnVoice);
mWave1 = (ImageView) findViewById(R.id.wave1);
mWave2 = (ImageView) findViewById(R.id.wave2);
mWave3 = (ImageView) findViewById(R.id.wave3);
mAnimationSet1 = initAnimationSet();
mAnimationSet2 = initAnimationSet();
mAnimationSet3 = initAnimationSet();
mNormal.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
showWaveAnimation();
break;
case MotionEvent.ACTION_UP:
clearWaveAnimation();
break;
case MotionEvent.ACTION_CANCEL:
clearWaveAnimation();
}
return true;
}
});
}
private AnimationSet initAnimationSet() {
//AnimationSet提供了一个把多个动画组合成一个组合的机制
//并可设置组中动画的时序关系,如同时播放,顺序播放等
AnimationSet as = new AnimationSet(true);
//缩放动画效果
ScaleAnimation sa = new ScaleAnimation(
1f    //动画起始时 X坐标上的伸缩尺寸
, 2.3f  //动画结束时 X坐标上的伸缩尺寸
, 1f    //动画起始时Y坐标上的伸缩尺寸
, 2.3f  //动画结束时Y坐标上的伸缩尺寸
, ScaleAnimation.RELATIVE_TO_SELF //动画在X轴相对于物件位置类型:相对于自身
, 0.5f                            //动画相对于物件的X坐标的开始位置
, ScaleAnimation.RELATIVE_TO_SELF //动画在Y轴相对于物件位置类型:相对于自身
, 0.5f                            //动画相对于物件的Y坐标的开始位置
);
sa.setDuration(OFFSET * 3);//设置动画持续时间
sa.setRepeatCount(Animation.INFINITE);// 设置循环
//透明度动画效果
AlphaAnimation aa = new AlphaAnimation(
1           //动画起始时 透明度
, 0.1f      //动画结束时 透明度
);
aa.setDuration(OFFSET * 3);//设置动画持续时间
aa.setRepeatCount(Animation.INFINITE);//设置循环
as.addAnimation(sa);
as.addAnimation(aa);
return as;
}
private void showWaveAnimation() {
//启动动画
mWave1.startAnimation(mAnimationSet1);
//一定延时后启动动画2、3
mHandler.sendEmptyMessageDelayed(MSG_WAVE2_ANIMATION, OFFSET);
mHandler.sendEmptyMessageDelayed(MSG_WAVE3_ANIMATION, OFFSET * 2);
}
private void clearWaveAnimation() {
//结束动画
mWave1.clearAnimation();
mWave2.clearAnimation();
mWave3.clearAnimation();
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_WAVE2_ANIMATION:
mWave2.startAnimation(mAnimationSet2);
break;
case MSG_WAVE3_ANIMATION:
mWave3.startAnimation(mAnimationSet3);
break;
}
}
};
}


二、正弦水波

资料来源:http://blog.csdn.net/tianjian4592/article/details/44222565



源码:
package com.example.administrator.wavetest.View;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.AttributeSet;
import android.view.View;
import com.example.administrator.wavetest.utils.UiUtils;
/**
* Created by Administrator on 2016/1/8.
*/
public class DynamicWave extends View {
// 波纹颜色
private static final int WAVE_PAINT_COLOR = 0x880000aa;
// 第一条水波移动速度
private int TRANSLATE_X_SPEED_ONE = 7;
// 第二条水波移动速度
private int TRANSLATE_X_SPEED_TWO = 5;
// y = Asin(wx + b) + h
private float STRETCH_FACTOR_A = 20;
private int OFFSET_Y = 0;
//周期
private float mCycleFactorW;
private int mTotalWidth;
private int mTotalHeight;
//水波高度
private int mWaveHeight = 400;
//重绘间隔时间
private int ViewTimer = 100;
private float[] mYPositions;
private float[] mResetOneYPositions;
private float[] mResetTwoYPositions;
private int mXOffsetSpeedOne;
private int mXOffsetSpeedTwo;
private int mXOneOffset;
private int mXTwoOffset;
private Paint mWavePaint;
private DrawFilter mDrawFilter;
private Context mContext;
public DynamicWave(Context context, AttributeSet attrs){
super(context, attrs);
mContext = context;
// 将dp转化为px,用于控制不同分辨率上移动速度基本一致
mXOffsetSpeedOne = UiUtils.dipToPx(context, TRANSLATE_X_SPEED_ONE);
mXOffsetSpeedTwo = UiUtils.dipToPx(context, TRANSLATE_X_SPEED_TWO);
// 初始绘制波纹的画笔
mWavePaint = new Paint();
// 去除画笔锯齿
mWavePaint.setAntiAlias(true);
// 设置风格为实线
mWavePaint.setStyle(Paint.Style.FILL);
// 设置画笔颜色
mWavePaint.setColor(WAVE_PAINT_COLOR);
//图片线条抗锯齿
mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 从canvas层面去除绘制时锯齿
canvas.setDrawFilter(mDrawFilter);
//移动数据
resetPositonY();
for (int i = 0; i < mTotalWidth; i++) {
// 减400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果
// 绘制第一条水波纹
canvas.drawLine(i, mTotalHeight - mResetOneYPositions[i] - mWaveHeight, i,
mTotalHeight,
mWavePaint);
// 绘制第二条水波纹
canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i] - mWaveHeight, i,
mTotalHeight,
mWavePaint);
}
// 改变两条波纹的移动点
mXOneOffset += mXOffsetSpeedOne;
mXTwoOffset += mXOffsetSpeedTwo;
// 如果已经移动到结尾处,则重头记录
if (mXOneOffset >= mTotalWidth) {
mXOneOffset = 0;
}
if (mXTwoOffset > mTotalWidth) {
mXTwoOffset = 0;
}
// 引发view重绘,一般可以考虑延迟20-30ms重绘,空出时间片
postInvalidateDelayed(ViewTimer);
//postInvalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 记录下view的宽高
mTotalWidth = w;
mTotalHeight = h;
// 用于保存原始波纹的y值
mYPositions = new float[mTotalWidth];
// 用于保存波纹一的y值
mResetOneYPositions = new float[mTotalWidth];
// 用于保存波纹二的y值
mResetTwoYPositions = new float[mTotalWidth];
// 将周期定为view总宽度
mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);
initData();
}
private void initData(){
// 根据view总宽度得出所有对应的y值   y = Asin(wx+b)+h
for (int i = 0; i < mTotalWidth; i++) {
mYPositions[i] = (float) (STRETCH_FACTOR_A * Math.sin(mCycleFactorW * i) + OFFSET_Y);
}
}
private void resetPositonY() {
// mXOneOffset代表当前第一条水波纹要移动的距离
int yOneInterval = mYPositions.length - mXOneOffset;
// 使用System.arraycopy方式重新填充第一条波纹的数据
System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0, yOneInterval);
System.arraycopy(mYPositions, 0, mResetOneYPositions, yOneInterval, mXOneOffset);
int yTwoInterval = mYPositions.length - mXTwoOffset;
System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0,
yTwoInterval);
System.arraycopy(mYPositions, 0, mResetTwoYPositions, yTwoInterval, mXTwoOffset);
}
public void setTRANSLATE_X_SPEED_ONE(int speed){
TRANSLATE_X_SPEED_ONE = speed;
mXOffsetSpeedOne = UiUtils.dipToPx(mContext, TRANSLATE_X_SPEED_ONE);
}
public void setTRANSLATE_X_SPEED_TWO(int speed){
TRANSLATE_X_SPEED_TWO = speed;
mXOffsetSpeedTwo = UiUtils.dipToPx(mContext, TRANSLATE_X_SPEED_TWO);
}
public void setWaveheight(int height){
mWaveHeight = height;
}
public void setViewTimer(int time){
ViewTimer = time;
}
public void setSTRETCH_FACTOR_A(int a){
STRETCH_FACTOR_A = a;
initData();
}
public void setOFFSET_Y(int y){
OFFSET_Y = y;
initData();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息