开发者

Android - Set drawable's gradient dynamically

I have a drawable from an XML resource, and I want to use that drawable but set the gradient color dynamically. So far I have something like this:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
        android:radius="3dip">
    </corners>
    <gradient
        android:angle="90"
        android:type="linear"
        android:startColor="#FFFFFFFF"
        android:centerColor="#FFFF0000"
        android:endColor="#FFFF0000">
    </gradient>
</shape>

Now I figured that I would be able to make the colors dynamically by getting the drawable at runtime, cast开发者_开发技巧ing it as a GradientDrawable, and using a method to set the colors. The GradientDrawable however does not have such a method, and one can only set the colors in the constructor. I find it very strange that this is the case because all the other aspects of the gradient are settable. Is there an easier way than overriding onDraw() and doing the gradient myself? Some of the classes I'm trying to use are very poorly documented..


Resources are primarily static, and typically do not allow modification. Some resource types allow you to "clone" a mutable copy. GradientDrawable only allows you to set the colors in the contstuctor (as you discovered), so you need to create those internally if you want to control the colors dynamically at runtime, or better yet, select one of a fixed number of backgrounds from resource instead. As mentioned previously, use setBackgroundDrawable() to install your background at runtime. No need to pass judgment, just Get-R-Done!


Make a GradientDrawable Class like this:

public class RoundedDrawable extends GradientDrawable {

        public RoundedDrawable(int shape, int solidColor, int strokeWidth,
     int strokeColor, float[] fourRadii) {

            this.mutate();
            this.setShape(shape);
            this.setColor(solidColor);
            this.setStroke(strokeWidth, strokeColor);
            this.setCornerRadii(fourRadii);
        }
    }

Now use this in your Activity like this:

public class AAActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_transaction_layout);

    RoundedDrawable customBg;

    RelativeLayout relList = (RelativeLayout) findViewById(R.id.relList);
    float radii[]={5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f};
    customBg = new RoundedDrawable(GradientDrawable.RECTANGLE,Color.parseColor("#FFFFFF"),
            2, Color.parseColor("#8C8C8C"),radii);
    relList.setBackgroundDrawable(customBg);

    LinearLayout linearItemsRow = (LinearLayout) findViewById(R.id.linearItemsRow);
    float[] rowRadii={5.0f, 5.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f};
    customBg = new RoundedDrawable(GradientDrawable.RECTANGLE,Color.parseColor("#CBCBCB"),
            0, 0, rowRadii);
    linearItemsRow.setBackgroundDrawable(customBg);


}

}

Hope this will help.


you can set as background drawable for a view dynamically.

view.setBackgroundDrawable(R.drawable.your_drawable_id);


Class

final class MyGradientDrawable extends GradientDrawable {
        MyGradientDrawable(int fromColor, int toColor) {
            super(Orientation.BOTTOM_TOP, new int[]{fromColor, toColor});

            setCornerRadius(0);
            setGradientType(LINEAR_GRADIENT);
            setGradientRadius(90);
        }
    }

Usage

  final int firstColor = ContextCompat.getColor(requireContext(), R.color.my_first_color);
  final int secondColor = ContextCompat.getColor(requireContext(), R.color.my_second_color);
  final MyGradientDrawable myGradBg = new MyGradientDrawable(firstColor, secondColor);

  myView.setBackground(myGradBg)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜