Android에서 그라디언트가있는 텍스트
TextView
그라디언트 효과가있는 텍스트 그리기를 허용하려면 어떻게 확장 합니까?
TextView secondTextView = new TextView(this);
Shader textShader=new LinearGradient(0, 0, 0, 20,
new int[]{Color.GREEN,Color.BLUE},
new float[]{0, 1}, TileMode.CLAMP);
secondTextView.getPaint().setShader(textShader);
5 가지 색상의 그라디언트로 top answer (@Taras)를 사용했지만 문제가 있습니다. textView가 흰색 덮개를 씌운 것처럼 보입니다. 다음은 내 코드와 스크린 샷입니다.
textView = (TextView) findViewById(R.id.main_tv);
textView.setText("Tianjin, China".toUpperCase());
TextPaint paint = textView.getPaint();
float width = paint.measureText("Tianjin, China");
Shader textShader = new LinearGradient(0, 0, width, textView.getTextSize(),
new int[]{
Color.parseColor("#F97C3C"),
Color.parseColor("#FDB54E"),
Color.parseColor("#64B678"),
Color.parseColor("#478AEA"),
Color.parseColor("#8446CC"),
}, null, Shader.TileMode.CLAMP);
textView.getPaint().setShader(textShader);
몇 시간 후에 textView.setTextColor()
그라디언트의 첫 번째 색상으로 호출해야한다는 것을 알았습니다 . 그런 다음 스크린 샷 :
누군가를 돕기를 바랍니다!
그라디언트로 텍스트를 그리기 위해 TextView를 확장 할 수 없습니다. 그러나 캔버스를 만들고 그 위에 그림을 그리면이 효과를 얻을 수 있습니다. 먼저 사용자 정의 UI 요소 를 선언 해야합니다 . 초기에는 Layout 의 하위 클래스를 만들어야합니다 . 이 경우 한 줄의 텍스트 만 지원 하는 BoringLayout 을 사용 합니다.
Shader textShader=new LinearGradient(0, 0, 0, 20,
new int[]{bottom,top},
new float[]{0, 1}, TileMode.CLAMP);//Assumes bottom and top are colors defined above
textPaint.setTextSize(textSize);
textPaint.setShader(textShader);
BoringLayout.Metrics boringMetrics=BoringLayout.isBoring(text, textPaint);
boringLayout=new BoringLayout(text, textPaint, 0, Layout.Alignment.ALIGN_CENTER,
0.0f, 0.0f, boringMetrics, false);
그런 다음 onMeasure
및 다음을 재정의합니다 onDraw
.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension((int) textPaint.measureText(text), (int) textPaint.getFontSpacing());
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
boringLayout.draw(canvas);
}
우리의 구현은 onDraw
이 시점에서 상당히 게으르다 (측정 사양을 완전히 무시합니다!하지만 뷰에 충분한 공간이 제공된다는 것을 보장하는 한 정상적으로 작동합니다.
또는에서 상속 Canvas
하고 onPaint
메서드를 재정의 할 수 있습니다 . 이렇게하면 안타깝게도 그려지는 텍스트의 앵커가 항상 맨 아래에 있으므로 -textPaint.getFontMetricsInt().ascent()
y 좌표 에 추가 해야합니다.
이 두 가지 방법을 모두 포함하는 라이브러리를 롤업했습니다. XML로 GradientTextView를 만들거나 GradientTextView.setGradient (TextView textView ...)를 사용하여 일반 TextView 객체에서 수행 할 수 있습니다.
https://github.com/koush/Widgets
여기에는 하나의 라이너로 여러 줄 지원이 있습니다. 이것은 버튼에서도 작동합니다.
Shader shader = new LinearGradient(0,0,0,textView.getLineHeight(),
startColor, endColor, Shader.TileMode.REPEAT);
textView.getPaint().setShader(shader);
간단하지만 다소 제한적인 해결책은 다음 속성을 사용하는 것입니다.
android:fadingEdge="horizontal"
android:scrollHorizontally="true"
너무 길어지면 페이드 아웃되기를 원하는 텍스트 필드에 사용했습니다.
여기에 좋은 방법이 있습니다.
/**
* sets a vertical gradient on the textView's paint, so that on its onDraw method, it will use it.
*
* @param viewAlreadyHasSize
* set to true only if the textView already has a size
*/
public static void setVerticalGradientOnTextView(final TextView tv, final int positionsAndColorsResId,
final boolean viewAlreadyHasSize) {
final String[] positionsAndColors = tv.getContext().getResources().getStringArray(positionsAndColorsResId);
final int[] colors = new int[positionsAndColors.length];
float[] positions = new float[positionsAndColors.length];
for (int i = 0; i < positionsAndColors.length; ++i) {
final String positionAndColors = positionsAndColors[i];
final int delimeterPos = positionAndColors.lastIndexOf(':');
if (delimeterPos == -1 || positions == null) {
positions = null;
colors[i] = Color.parseColor(positionAndColors);
} else {
positions[i] = Float.parseFloat(positionAndColors.substring(0, delimeterPos));
String colorStr = positionAndColors.substring(delimeterPos + 1);
if (colorStr.startsWith("0x"))
colorStr = '#' + colorStr.substring(2);
else if (!colorStr.startsWith("#"))
colorStr = '#' + colorStr;
colors[i] = Color.parseColor(colorStr);
}
}
setVerticalGradientOnTextView(tv, colors, positions, viewAlreadyHasSize);
}
/**
* sets a vertical gradient on the textView's paint, so that on its onDraw method, it will use it. <br/>
*
* @param colors
* the colors to use. at least one should exist.
* @param tv
* the textView to set the gradient on it
* @param positions
* where to put each color (fraction, max is 1). if null, colors are spread evenly .
* @param viewAlreadyHasSize
* set to true only if the textView already has a size
*/
public static void setVerticalGradientOnTextView(final TextView tv, final int[] colors, final float[] positions,
final boolean viewAlreadyHasSize) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
final TileMode tile_mode = TileMode.CLAMP;
final int height = tv.getHeight();
final LinearGradient lin_grad = new LinearGradient(0, 0, 0, height, colors, positions, tile_mode);
final Shader shader_gradient = lin_grad;
tv.getPaint().setShader(shader_gradient);
}
};
if (viewAlreadyHasSize)
runnable.run();
else
runJustBeforeBeingDrawn(tv, runnable);
}
public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) {
final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
runnable.run();
return true;
}
};
view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
또한 그라디언트의 비트 맵을 대신 사용하거나 실제 비트 맵을 사용하려면 다음을 사용하십시오.
/**
* sets an image for the textView <br/>
* NOTE: this function must be called after you have the view have its height figured out <br/>
*/
public static void setBitmapOnTextView(final TextView tv, final Bitmap bitmap) {
final TileMode tile_mode = TileMode.CLAMP;
final int height = tv.getHeight();
final int width = tv.getWidth();
final Bitmap temp = Bitmap.createScaledBitmap(bitmap, width, height, true);
final BitmapShader bitmapShader = new BitmapShader(temp, tile_mode, tile_mode);
tv.getPaint().setShader(bitmapShader);
}
편집 : runJustBeforeBeingDrawn의 대안 : https://stackoverflow.com/a/28136027/878126
다음은 linearlayout의 예입니다.이 예를 textview에도 사용할 수 있으며 소스 코드에는 그래디언트 코딩이 없을 것입니다. 소스 코드를 가져 와서 해당 사이트 자체에서 코드를 추가합니다 -http : // android-codes-examples .blogspot.com / 2011 / 07 / design-linearlayout-or-textview-and-any.html
참조 URL : https://stackoverflow.com/questions/2680607/text-with-gradient-in-android
'Programing' 카테고리의 다른 글
Mongodb : 127.0.0.1:27017에 연결하지 못했습니다. 이유 : errno : 10061 (0) | 2020.12.28 |
---|---|
자바 수학에서 조합 'N choose R'? (0) | 2020.12.28 |
iOS 앱의 첫 실행 감지 (0) | 2020.12.28 |
WPF WebBrowser 컨트롤-스크립트 오류를 억제하는 방법? (0) | 2020.12.28 |
Matplotlib-일련의 선 플롯에 컬러 바 추가 (0) | 2020.12.27 |