Android 특수효과 물결무늬 의 실현

10345 단어 android물결 무늬
머리말
물결 무늬 의 특수 효 과 는 여러분 이 많 든 적 든 본 적 이 있 을 것 입 니 다.제 인상 에는 대체적으로 다음 과 같은 몇 가지 가 있 습 니 다.
     알 리 페 이"씩씩"식
     유량 구'출 렁'식
     실제 물결 무늬 효과,Bitmap 기반 처리 식
말 이 많 지 않 으 니 먼저 효 과 를 보 자.
충전 식 물결 무늬,간격 이 같다.

비 충전 식 물결 무늬,간격 이 같다.

비 충전 식 물결 무늬,간격 이 끊임없이 커진다.

충전 식 물결 무늬,간격 이 계속 작 아 집 니 다.

기본 적 인 원 리 를 아 셨 을 거 예요.캔버스 로 그 리 는 거 잖 아 요.하지만 쉬 운 그림 은 아니에요.아래 를 보 세 요.
분석 하 다.
이런 유형의 물결 무늬 는 사실은 원 을 그 리 는 것 일 뿐이다.주어진 사각형 에서 하나의 원 은 최소 반지름 에서 최대 반지름 으로 확대 되 고 투명 도 는 1.0 에서 0.0 으로 변 한다.우 리 는 이러한 확산 이 등 속 이 라 고 가정 하면 원 이 생 성(투명 도 는 1.0)에서 사라 짐(투명 도 는 0.0)까지 의 시간 이 정 해진 값 이 라 고 가정 합 니 다.그러면 어느 순간 에 원 의 반지름 과 투명 도 는 확산 시간(현재 시간-생 성 시간)에 의 해 결정 할 수 있 습 니 다.
이루어지다
위의 분석 에 따 르 면 우 리 는 다음 과 같은Circle류 를 써 서 원 을 표시 한다.

private class Circle {
 private long mCreateTime;

 public Circle() {
 this.mCreateTime = System.currentTimeMillis();
 }

 public int getAlpha() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return (int) ((1.0f - percent) * 255);
 }

 public float getCurrentRadius() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return mInitialRadius + percent * (mMaxRadius - mInitialRadius);
 }
}
자 연 스 럽 게WaveView에 현재 표시 되 고 있 는 원 을 저장 하 는 List 가 있어 야 합 니 다.

private List<Circle> mCircleList = new ArrayList<Circle>();
확산 을 시작 하 는 방법start을 정의 합 니 다.

public void start() {
 if (!mIsRunning) {
 mIsRunning = true;
 mCreateCircle.run();
 }
}

private Runnable mCreateCircle = new Runnable() {
 @Override
 public void run() {
 if (mIsRunning) {
 newCircle();
 postDelayed(mCreateCircle, mSpeed); //   mSpeed       
 }
 }
};

private void newCircle() {
 long currentTime = System.currentTimeMillis();
 if (currentTime - mLastCreateTime < mSpeed) {
 return;
 }
 Circle circle = new Circle();
 mCircleList.add(circle);
 invalidate();
 mLastCreateTime = currentTime;
}
start방법 은 간단하게 원 을 만 들 고mCircleList에 추 가 했 을 뿐 순환 으로 원 을 만 드 는Runnable을 열 었 다.그 다음 에 화면 새로 고침 을 알 렸 다.우 리 는 다시onDraw방법 을 보 자.

protected void onDraw(Canvas canvas) {
 Iterator<Circle> iterator = mCircleList.iterator();
 while (iterator.hasNext()) {
 Circle circle = iterator.next();
 if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
 mPaint.setAlpha(circle.getAlpha());
 canvas.drawCircle(getWidth() / 2, getHeight() / 2, circle.getCurrentRadius(), mPaint);
 } else {
 iterator.remove();
 }
 }
 if (mCircleList.size() > 0) {
 postInvalidateDelayed(10);
 }
}
onDraw방법 은 각각Circle을 옮 겨 다 니 며Circle의 확산 시간 이 설 정 된 확산 시간 을 초과 하 는 지,그렇지 않 으 면 제거 하고,그렇지 않 으 면 현재 의 투명도 와 반경 을 계산 하여 그립 니 다.우 리 는 연속 적 인 파문 확산 효 과 를 얻 기 위해 시간 지연 리 셋 을 추가 했다.
지금 프로그램 을 실행 하면 그림 2 의 효 과 를 볼 수 있 을 것 입 니 다.그런데 좀 어색 합 니 다.상식 적 으로 물결 의 간격 이 점점 커지 고 있 습 니 다.어떻게 해 야 합 니까?
기교.
물결 무늬 의 반지름 이 고 르 지 않 게 커지 려 면 우 리 는Circle방법 을 수정 할 수 밖 에 없다.우 리 는 이 방법 을 다시 한 번 보 았 다.

public float getCurrentRadius() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return mInitialRadius + percent * (mMaxRadius - mInitialRadius);
}
Circle.getCurrentRadius()percent현재 확산 시간 과 총 확산 시간의 한 백분율 로 현재 확산 시간 이 총 확산 시간 을 초과 할 때Circle제거 되 는 것 을 고려 하여Circle의 실제 구간 은[0,1]이 고[0,1]을 보면 여러분 이 생각 하 는 것 이 무엇 인지 모 르 겠 습 니 다.제 가 먼저 생각 하 는 것 은 바로 차동 장치percent입 니 다.우 리 는 차 치 기 를 정의 함으로써 반경 변화 에 대한 제 어 를 실현 할 수 있다.
코드 수정:

private Interpolator mInterpolator = new LinearInterpolator();

public void setInterpolator(Interpolator interpolator) {
 mInterpolator = interpolator;
 if (mInterpolator == null) {
 mInterpolator = new LinearInterpolator();
 }
}

private class Circle {
 private long mCreateTime;

 public Circle() {
 this.mCreateTime = System.currentTimeMillis();
 }

 public int getAlpha() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return (int) ((1.0f - mInterpolator.getInterpolation(percent)) * 255);
 }

 public float getCurrentRadius() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);
 }
}
이렇게 하면 외부 에서Interpolator를 사용 할 때Circle를 호출 하여 서로 다른 플러그 인 을 정의 하면 서로 다른 효 과 를 실현 할 수 있다.
그림 3 효과 코드:

mWaveView = (WaveView) findViewById(R.id.wave_view);
mWaveView.setDuration(5000);
mWaveView.setStyle(Paint.Style.STROKE);
mWaveView.setSpeed(400);
mWaveView.setColor(Color.parseColor("#ff0000"));
mWaveView.setInterpolator(new AccelerateInterpolator(1.2f));
mWaveView.start();
그림 4 효과 의 코드:

mWaveView = (WaveView) findViewById(R.id.wave_view);
mWaveView.setDuration(5000);
mWaveView.setStyle(Paint.Style.FILL);
mWaveView.setColor(Color.parseColor("#ff0000"));
mWaveView.setInterpolator(new LinearOutSlowInInterpolator());
mWaveView.start();
WaveView 의 모든 코드 를 첨부 합 니 다:

/**
 *      
 * Created by hackware on 2016/6/17.
 */
public class WaveView extends View {
 private float mInitialRadius; //       
 private float mMaxRadiusRate = 0.85f; //       mMaxRadius, mMaxRadius =      * mMaxRadiusRate;
 private float mMaxRadius; //       
 private long mDuration = 2000; //                
 private int mSpeed = 500; //        , 500ms    
 private Interpolator mInterpolator = new LinearInterpolator();

 private List<Circle> mCircleList = new ArrayList<Circle>();
 private boolean mIsRunning;

 private boolean mMaxRadiusSet;

 private Paint mPaint;
 private long mLastCreateTime;

 private Runnable mCreateCircle = new Runnable() {
 @Override
 public void run() {
 if (mIsRunning) {
 newCircle();
 postDelayed(mCreateCircle, mSpeed);
 }
 }
 };

 public WaveView(Context context) {
 this(context, null);
 }

 public WaveView(Context context, AttributeSet attrs) {
 super(context, attrs);
 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 setStyle(Paint.Style.FILL);
 }

 public void setStyle(Paint.Style style) {
 mPaint.setStyle(style);
 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 if (!mMaxRadiusSet) {
 mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;
 }
 }

 public void setMaxRadiusRate(float maxRadiusRate) {
 this.mMaxRadiusRate = maxRadiusRate;
 }

 public void setColor(int color) {
 mPaint.setColor(color);
 }

 /**
 *   
 */
 public void start() {
 if (!mIsRunning) {
 mIsRunning = true;
 mCreateCircle.run();
 }
 }

 /**
 *   
 */
 public void stop() {
 mIsRunning = false;
 }

 protected void onDraw(Canvas canvas) {
 Iterator<Circle> iterator = mCircleList.iterator();
 while (iterator.hasNext()) {
 Circle circle = iterator.next();
 if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
 mPaint.setAlpha(circle.getAlpha());
 canvas.drawCircle(getWidth() / 2, getHeight() / 2, circle.getCurrentRadius(), mPaint);
 } else {
 iterator.remove();
 }
 }
 if (mCircleList.size() > 0) {
 postInvalidateDelayed(10);
 }
 }

 public void setInitialRadius(float radius) {
 mInitialRadius = radius;
 }

 public void setDuration(long duration) {
 this.mDuration = duration;
 }

 public void setMaxRadius(float maxRadius) {
 this.mMaxRadius = maxRadius;
 mMaxRadiusSet = true;
 }

 public void setSpeed(int speed) {
 mSpeed = speed;
 }

 private void newCircle() {
 long currentTime = System.currentTimeMillis();
 if (currentTime - mLastCreateTime < mSpeed) {
 return;
 }
 Circle circle = new Circle();
 mCircleList.add(circle);
 invalidate();
 mLastCreateTime = currentTime;
 }

 private class Circle {
 private long mCreateTime;

 public Circle() {
 this.mCreateTime = System.currentTimeMillis();
 }

 public int getAlpha() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return (int) ((1.0f - mInterpolator.getInterpolation(percent)) * 255);
 }

 public float getCurrentRadius() {
 float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
 return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);
 }
 }

 public void setInterpolator(Interpolator interpolator) {
 mInterpolator = interpolator;
 if (mInterpolator == null) {
 mInterpolator = new LinearInterpolator();
 }
 }
}
총결산
이 글 을 보시 면 플러그 인 을 이렇게 쓸 수 있 을 것 같 습 니 다.사실은 어떤 때 는 우리 가 시스템 이 제공 하 는 API 를 사용 하 는 것 이 너무 제한 되 고 가끔 은 생각 을 바 꾸 면 기묘 한 효 과 를 얻 을 수 있 을 지도 모른다.안 드 로 이 드 에서 물결 무늬 효 과 를 구현 하 는 모든 콘 텐 츠 입 니 다.안 드 로 이 드 개발 에 도움 이 되 셨 으 면 합 니 다.

좋은 웹페이지 즐겨찾기