Here is a good way to do this:
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); } 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); }
Also, if you want to use a gradient bitmap instead of a real one, use:
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); }
EDIT: Alternative to runJustBeforeBeingDrawn: https://stackoverflow.com/questions/35172/ ...
android developer Jul 09 '15 at 8:03 2015-07-09 08:03
source share