如何擴展TextView
以允許繪製具有漸變效果的文本?帶有漸變的Android文本
回答
似乎無法擴展TextView以使用漸變繪製文本。但是,可以通過創建畫布並在其上繪製來實現此效果。首先我們需要declare our custom UI element。在開始時,我們需要創建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
方法。如果這是d一個,那麼不幸的是,繪製文本的錨將始終在底部,因此我們必須將-textPaint.getFontMetricsInt().ascent()
添加到我們的y座標中。
一個簡單但比較有限的解決辦法是使用這些屬性:
android:fadingEdge="horizontal"
android:scrollHorizontally="true"
我已經用它在哪裏,我希望他們淡出如果他們太久文本框。
這是一個很好的黑客攻擊。我不認爲你可以垂直工作?沒有任何android:scrollVertically屬性,據我所見 – Casebash 2010-04-21 23:49:04
對不起,我不知道該怎麼做:( – pgsandstrom 2010-04-22 06:46:27
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);
+1中,使它更簡單,更高效 – 2011-07-08 10:12:16
感謝您提供了一個非常簡單的解決方案:) – 2011-08-12 07:44:54
在我的ICS設備上,這似乎不起作用 - - 它是完全透明的。其他人看到同樣的事情?該視圖不是硬件加速的。 – 2012-03-01 01:14:59
我已經卷起了一個包含這兩種方法的庫。您可以使用XML創建GradientTextView,或者使用GradientTextView.setGradient(TextView textView ...)在常規TextView對象上執行該操作。
下面是一個例子LinearLayout中,你可以用這個例子的TextView過了,在源代碼中有不會是梯度編碼,你得到的源代碼,並添加從該網站本身的代碼 - http://android-codes-examples.blogspot.com/2011/07/design-linearlayout-or-textview-and-any.html
這裏是一個很好的方式做到這一點:
/**
* 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);
}
這裏是多行支持作爲一個班輪。這也適用於按鈕。
textView.getPaint().setShader(new LinearGradient(0,0,0,textView.getLineHeight(), startColor, endColor, Shader.TileMode.REPEAT));
簡單和卓越的作品! – 2016-03-25 05:31:55
工程,但對於高度,你可能要考慮低於實際線的字母(如y,g,j等),並將lineheight乘以1.10f, 'textView.getLineHeight()* 1.10f'。 – 2018-01-26 11:06:47
- 1. 帶漸變神器的Android漸變
- 2. 帶漸變和邊框的文本
- 3. 帶有漸變的iOS UIProgressView
- 4. Android上的OpenGL漸變色帶
- 5. 帶有漸變邊框的javascript
- 6. 帶漸變的多段線
- 7. 帶顏色漸變的UIBeziepath
- 8. 帶方向的QML漸變
- 9. 帶漸變渲染的PNG
- 10. 帶漸變和自定義字體的文本
- 11. Android中的漸變
- 12. Android漸變背景漸變爲透明
- 13. 繪製帶有漸變的文字填充可可
- 14. 漸變背景上的文字漸變
- 15. 使用CSS3在文本上創建雙色漸變漸變
- 16. android圖像漸變
- 17. 帶有漸變,漸變背景和居中文字的CSS樣式的導航按鈕
- 18. Android - 帶有圖標和文本的Gridview
- 19. Android上的CSS漸變
- 20. Android的平方漸變?
- 21. Android中的漸變選項?
- 22. Android中的橢圓漸變
- 23. 橢圓漸變的Android
- 24. Android css3漸變文字問題
- 25. 帶圖像的徑向漸變IOS
- 26. 帶漸變圖像疊加的標題
- 27. 帶漸變的圓形箭頭
- 28. 帶IPP功能的線性漸變
- 29. ggplot2帶顏色漸變的圓環圖
- 30. 在編輯文本邊框中添加漸變android
嗨,請問您能否在此答案中增加一些代碼?具體來說,BoringLayout的其餘部分擴展布局 謝謝! – ekatz 2011-05-10 18:39:13
我鏈接到BoringLayout,它應該包含在SDK – Casebash 2011-05-10 21:25:29