androidseekbarlayerdrawable

Why dynamically created SeekBar is not with my color?


I have to create SeekBar with primary and secondary progress at runtime. Looking at tileify function for how should I treat LayerDrawable, and progress_horizontal_holo_dark.xml for proper IDs, i came up with following:

    // parent view
    LinearLayout parent = (LinearLayout) findViewById(R.id.parent);

    // create widget
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

    SeekBar seekBar = new SeekBar(this);
    seekBar.setLayoutParams(params);

    // set bg resources
    Drawable background = getResources().getDrawable(R.drawable.scrubber_track_holo_light);
    ScaleDrawable primary = new ScaleDrawable(getResources().getDrawable(R.drawable.scrubber_primary_holo), 0x10|0x03, 100.0f, 100);

    ScaleDrawable secondary = new ScaleDrawable(getResources().getDrawable(R.drawable.scrubber_secondary_holo), 0x100x03, 100.0f, 85);

    LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { background, secondary, primary});
    layerDrawable.setId(0, android.R.id.background);
    layerDrawable.setId(1, android.R.id.secondaryProgress);
    layerDrawable.setId(2, android.R.id.progress);

    seekBar.setBackgroundDrawable(layerDrawable);
    seekBar.setThumb(getResources().getDrawable(R.drawable.seekbar_btn));

    // set values
    seekBar.setMax(50);
    seekBar.setSecondaryProgress(25);
    seekBar.setProgress(15);
    parent.addView(seekBar);  

This is how SeekBar should look like:

ideal

And this are mine resource files:

primary- scrubber_primary_holo.9.png
secondary- scrubber_secondary_holo.9.png

Problem:

enter image description here

Any ideas?


Solution

  • In case someone else has the same problem, I found the solution. There were two issues. First one is that ScaleBitmap although used in XML doesn't work from code. I had to use ClipDrawable. The second issue was with showing primary and secondary progress - they were shown after the first progress change. This is solved by adding seekBar to parent view first and then setting primary and secondary progress. You can see the source code below. Cheers!

        // CREATE WIDGET
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    
        SeekBar seekBar = new SeekBar(this, null, android.R.attr.seekBarStyle);
        seekBar.setLayoutParams(params);
        parent.addView(seekBar);
    
        seekBar.setMax(50);
        seekBar.setProgress(15);
        seekBar.setSecondaryProgress(25);
    
    
        // CREATE PROGRESS BAR
        LayerDrawable layerDrawable = (LayerDrawable) seekBar.getProgressDrawable();
        seekBar.setThumb(getResources().getDrawable(R.drawable.seekbar_btn));
    
        Drawable progress = (Drawable) layerDrawable.findDrawableByLayerId(android.R.id.progress);
        Bitmap progressBmp = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_secondary_holo);
        progress = new ClipDrawable(new BitmapDrawable(getResources(), progressBmp), Gravity.AXIS_PULL_BEFORE, ClipDrawable.HORIZONTAL);
        layerDrawable.setDrawableByLayerId(android.R.id.progress, progress);
    
        Drawable secondary = (Drawable) layerDrawable.findDrawableByLayerId(android.R.id.secondaryProgress);
        Bitmap secondaryBmp = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_primary_holo);
        secondary = new ClipDrawable(new BitmapDrawable(getResources(), secondaryBmp), Gravity.AXIS_PULL_BEFORE, ClipDrawable.HORIZONTAL);
        layerDrawable.setDrawableByLayerId(android.R.id.secondaryProgress, secondary);
    
        Drawable background = (Drawable) layerDrawable.findDrawableByLayerId(android.R.id.background);
        Bitmap backgroundBmp = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_track_holo_light);
        background = new BitmapDrawable(getResources(), backgroundBmp);
        layerDrawable.setDrawableByLayerId(android.R.id.background, background);