Mario Rossi
Mario Rossi

Reputation: 127

Setting color filter to Vector Drawable

I was tryng to create something really simple. My idea was an HorizontalScrollView with some different coloured cards.

Code:

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


    LinearLayout parent = (LinearLayout) findViewById(R.id.modeList);
    Color[] colorList={Color.BLUE,Color.GREEN,Color.RED,Color.ORANGE,Color.AQUA};
    String[] nameList={"Film","Music","Brand","Animals","People"};


    for(int i=0; i<5; i++) {
        drawCard(parent, nameList[i], colorList[i]);
    }
}

Here is the method i use to display the cards

private void drawCard(LinearLayout parent, String cardTitle, Color color){

    int middleColorID, darkColorID;
    switch(color){
        case RED: {
            middleColorID=R.color.middleRed;
            darkColorID=R.color.darkRed;
            break;
        }
        case BLUE: {
            middleColorID=R.color.middleBlue;
            darkColorID=R.color.darkBlue;
            break;
        }
        case ORANGE: {
            middleColorID=R.color.middleOrange;
            darkColorID=R.color.darkOrange;
            break;
        }
        case PURPLE: {
            middleColorID=R.color.middlePurple;
            darkColorID=R.color.darkPurple;
            break;
        }
        case CYAN: {
            middleColorID=R.color.middleCyan;
            darkColorID=R.color.darkCyan;
            break;
        }
        case AQUA: {
            middleColorID=R.color.middleAqua;
            darkColorID=R.color.darkAqua;
            break;
        }
        case GREEN: {
            middleColorID=R.color.middleGreen;
            darkColorID=R.color.darkGreen;
            break;
        }
        default: {
            middleColorID=R.color.middleGreen;
            darkColorID=R.color.darkGreen;
            break;
        }

    }

    //create the card and assign background
    RelativeLayout child = new RelativeLayout(this);
    child.setBackgroundResource(R.drawable.card);
    child.setElevation(30);

    //set margin and layout parent
    RelativeLayout.LayoutParams parentParams = new RelativeLayout.LayoutParams(400, -1);
    parentParams.setMargins(10,0,10,0);
    parent.addView(child, parentParams);

    //create the wave_outline
    RelativeLayout waveOutline = new RelativeLayout(this);
    Drawable waveDrw = getDrawable(R.drawable.ic_newwave_outline);
    waveDrw.setColorFilter(getResources().getColor(darkColorID), PorterDuff.Mode.SRC_ATOP);
    waveOutline.setBackground(waveDrw);
    RelativeLayout.LayoutParams waveOutlineParams =  new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 120);
    waveOutlineParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    waveOutlineParams.bottomMargin=120;
    child.addView(waveOutline, waveOutlineParams);

    //create the wave
    RelativeLayout wave = new RelativeLayout(this);
    waveDrw = getDrawable(R.drawable.ic_newwave);
    waveDrw.setColorFilter(getResources().getColor(middleColorID), PorterDuff.Mode.SRC_ATOP);
    wave.setBackground(waveDrw);
    RelativeLayout.LayoutParams containerParams =  new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 120);
    containerParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    containerParams.bottomMargin=90;
    child.addView(wave, containerParams);


    //create the bottom filler
    RelativeLayout cardFiller = new RelativeLayout(this);
    waveDrw = getDrawable(R.drawable.card_bottom);
    waveDrw.setColorFilter(getResources().getColor(middleColorID), PorterDuff.Mode.SRC_ATOP);
    cardFiller.setBackground(waveDrw);
    RelativeLayout.LayoutParams cardFillerParams =  new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 90);
    cardFillerParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    child.addView(cardFiller, cardFillerParams);

    //set the name
    TextView child_name= new TextView(this);
    child_name.setText(cardTitle);
    RelativeLayout.LayoutParams child_nameParams =  new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    child_name.setGravity(Gravity.CENTER);
    child_name.setTextSize(30);
    child_name.setTextColor(getResources().getColor(R.color.dirtyWhite));
    child_nameParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    child_nameParams.bottomMargin=30;
    child.addView(child_name, child_nameParams);

}

The strange thing is that when i try to run this code the two wave vector drawable that i use have the same color on all cards (they seems to get the last color passed to the method). If i try to swap the resource, using some other xml shape file instead of the vector, the displayed colour is the right one. This made me thinking that the problem are the two vector but i can't understand what am i missing. They actually successfully set the proper color filter one time, but only the last one. It seem that the old filter is overwritten. Any ideas? Thanks

Here are some screenshots: Screenshot 1 Screenshot 2

Upvotes: 1

Views: 695

Answers (1)

Perraco
Perraco

Reputation: 17360

Drawables pointing to a same resource share their state. This means that for example if you have 2 Views which instantiate drawables using the same resource, then whatever changes you apply to one of the View's drawables will also be seen in the other View.

What you need to do is to call the method drawable.mutate() right after getDrawable. This will ensure that whatever changes are applied to one of the drawable instances are unique to that specific instance, without affecting other drawables in the other views pointing to the same resource.

Upvotes: 2

Related Questions