안드로이드의 가장 실용적인 TextView 텍스트 하나하나 효과

4658 단어
문자가 하나하나 효과를 내는 데 있어서, 우리가 단번에 생각한 방법은 모두 for 순환을 해서 텍스트 내용을 계속 바꾸는 것일 수도 있다.
이 방법은 겉으로는 괜찮아 보이지만 실제적으로 실용적으로 보면 문제가 많다. 예를 들어 여러 줄이 중간에 있는 텍스트에 대해 효과를 내는 것은 점진적인 것이 아니다. 왜냐하면 정렬과 줄 바꿈의 영향을 받아 문자가 많아지면서 텍스트의 구조가 끊임없이 변화하기 때문이다.
다음은 가장 실용적이고 안정적인 텍스트를 하나하나 보여 줍니다. 사용자 정의 구성 요소인 FadeInTextView입니다.
1. FadeInTextView는 TextView의 모든 특성을 완전히 계승하고 어떠한 부정적인 영향도 없다. FadeInTextView를 사용하는 것은 TextView를 사용하는 것과 같다.
2. 효과를 간단하게 설정한다.
(1) setFadeInDuration: 총 출력 효과 시간을 설정합니다.
(2) setMoveUnitLength: 점진적인 보폭을 몇 문자로 설정하고 기본값은 1이다.
(3) setFadeInMaskColor: 마스크 색상을 설정합니다. 즉, 문자 영역의 색상이 표시되지 않습니다.
전체 소스는 다음과 같습니다.
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.text.Layout;
import android.util.AttributeSet;
import android.widget.TextView;

public class FadeInTextView extends TextView {
	private static final int DEFAULT_UNIT_LENGTH = 2;
	private static final int DEFAULT_DURATION = 3820;
	private List lineRects = new ArrayList();
	private int duration = DEFAULT_DURATION;
	private int moveUnitLength;
	private int fromLine = 0;
	private int moveCount;
	private int fromStart;
	private int maskColor;
	private Paint paint;
	private FadeInListener fadeInListener;

	private volatile boolean fadeInFinished = false;

	private boolean hasCallListener = false;

	public FadeInTextView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public FadeInTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public FadeInTextView(Context context) {
		super(context);
	}

	public boolean isFadeInFinished() {
		return fadeInFinished;
	}

	public void setFadeInDuration(int duration) {
		this.duration = duration;
	}

	public int getFadeInDuration() {
		return duration;
	}

	public void setMoveUnitLength(int moveUnitLength) {
		this.moveUnitLength = moveUnitLength;
	}

	public void setFadeInMaskColor(int maskColor) {
		this.maskColor = maskColor;
	}

	public void setFadeInListener(FadeInListener fadeInListener) {
		this.fadeInListener = fadeInListener;
	}

	public void activateFadeInListener() {
		this.hasCallListener = false;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if (lineRects.isEmpty()) {
			getLineRects();
			if (fadeInListener != null && !hasCallListener) {
				fadeInListener.onFadeInStart(this);
			}
		}
		if (paint == null) {
			paint = new Paint();
			paint.setColor(maskColor);
			paint.setAntiAlias(true);
			paint.setStyle(Style.FILL);
		}
		for (int i = fromLine; i < lineRects.size(); i++) {
			Rect rect = new Rect(lineRects.get(i));
			if (i == fromLine) {
				rect.left = fromStart;
			}
			canvas.drawRect(rect, paint);
		}

		if (!computeNextFrame()) {
			fadeInFinished = true;
			if (fadeInListener != null && !hasCallListener) {
				fadeInListener.onFadeInEnd(this);
				hasCallListener = true;
			}
			return;
		}
		postDelayed(new Runnable() {
			@Override
			public void run() {
				invalidate();
			}
		}, duration / moveCount);
	}

	private boolean computeNextFrame() {
		if (lineRects.size() <= fromLine) {
			return false;
		}
		Rect currentLineRect = lineRects.get(fromLine);
		if (fromStart >= currentLineRect.right) {
			return false;
		}
		fromStart = fromStart + moveUnitLength;
		if (fromStart >= currentLineRect.right) {
			fromLine++;
			if (lineRects.size() > fromLine) {
				fromStart = lineRects.get(fromLine).left;
			} else {
				fromStart = 0;
			}
		}
		return true;

	}

	private void getLineRects() {
		Layout layout = getLayout();
		if (layout == null) {
			return;
		}
		int lineCount = layout.getLineCount();
		int totalLength = 0;
		for (int i = 0; i < lineCount; i++) {
			Rect rect = new Rect();
			rect.left = (int) layout.getLineLeft(i);
			rect.right = (int) layout.getLineRight(i);
			rect.top = layout.getLineTop(i);
			rect.bottom = layout.getLineBottom(i);
			if (i == 0) {
				fromStart = rect.left;
			}
			lineRects.add(rect);
			totalLength = totalLength + rect.width();
		}
		if (moveUnitLength <= 0) {
			moveUnitLength = DEFAULT_UNIT_LENGTH;
		}
		moveCount = totalLength / moveUnitLength;
		if (moveCount <= 0) {
			moveCount = 1;
		}
	}

	public static interface FadeInListener {
		public void onFadeInStart(TextView tv);

		public void onFadeInEnd(TextView tv);
	}
}

국제 관례
————————————————————————————————————————————————————————
저자: 박하 기장(전재 원작자 명기)
깔끔하고 안정적이고 우아한 무한 가능!

좋은 웹페이지 즐겨찾기