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 를 사용 하 는 것 이 너무 제한 되 고 가끔 은 생각 을 바 꾸 면 기묘 한 효 과 를 얻 을 수 있 을 지도 모른다.안 드 로 이 드 에서 물결 무늬 효 과 를 구현 하 는 모든 콘 텐 츠 입 니 다.안 드 로 이 드 개발 에 도움 이 되 셨 으 면 합 니 다.
。
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.