Change the width of a ProgressBar added at runtime

25,853

R.layout.activity includes this:

<ProgressBar
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:visibility="visible"
        style="@android:style/Widget.ProgressBar.Large.Inverse"
/>

And then the code:

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    ProgressBar bar = (ProgressBar)findViewById(R.id.progress);
    bar.getLayoutParams().height = 500;
    bar.invalidate();
}

The call to the invalidate() method is important as that is when the view is redrawn to take the changes into account. Although unintuitive, it does allow for better performance by batching changes.

Share:
25,853
Snowwire
Author by

Snowwire

Updated on March 29, 2020

Comments

  • Snowwire
    Snowwire about 4 years

    I am building up a UI from code and can successfully add ProgressBar widgets, however I cannot alter the dimensions of the widget to values I need, it always stays at the default size (around 50dp). I've tried the following code;

        ProgressBar progressBar = new ProgressBar(activity, null, android.R.attr.progressBarStyleHorizontal);
        progressBar.setMinimumHeight(20);
        progressBar.setMinimumWidth(100);
    

    I've also tried setting the progressBar LayoutParams but again nothing and I've tried wrapping the widget in another layout, but still not luck.

    Can anyone help, as I can't see how to do it? If there is a solution using XML it could work, but I have to set the dimension and location at runtime.


    For Progress XML I used the following.

    <ProgressBar
          xmlns:android="http://schemas.android.com/apk/res/android" 
          android:layout_width="fill_parent"
          android:layout_height="10dp"
          android:indeterminateOnly="false"
          android:progressDrawable="@android:drawable/progress_horizontal"
          android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
          android:maxWidth="1000dp"
       />
    

    Then the code to inflate it is as follows. This is a mix of what we have been discussing.

        LayoutInflater layoutInflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ProgressBar progressBar = (ProgressBar)layoutInflater.inflate(R.layout.progress_bar, null);
        progressBar.setMinimumHeight(10);
        progressBar.setMinimumWidth(200);
        progressBar.setLayoutParams(new RelativeLayout.LayoutParams(200, 10);
    
        progressBar.setMax(100);
        progressBar.setProgress(getScrollBarValue());
        progressBar.setIndeterminate(isIndeterminate());
        progressBar.getLayoutParams().width = 200;
        progressBar.invalidate();
    
  • Snowwire
    Snowwire over 13 years
    I tried what you suggested, and I could get the height of the widget to change, but not the width. From what I could tell the max and min width properties have to be the same for the size to take effect. The max size property cannot be changed at runtime, it is not exposed.
  • Snowwire
    Snowwire over 13 years
    I tried the method you suggested, but it didn't have any effect on the size.
  • sstn
    sstn over 13 years
    Which direction is your ProgressBar? The size in the direction of the progress bar should be determined by the layout, usually.
  • Ollie C
    Ollie C over 13 years
    This is not true, you can set the parameters in code, using LayoutParams
  • sstn
    sstn over 13 years
    @Ollie I meant the size will be derived/determined by the layout. Using XML or LayoutParams in the code will be the same, basically. Or did I misunderstood you?
  • Ollie C
    Ollie C over 13 years
    I detailed two methods you need to use, calling one on its own won't work. I've just built a test activity using this code with a ProgressBar and it works fine. So I'd suggest you make sure that a) the code you've written is being executed, and b) that the code is making the size adjustment to the right progress bar. I've updated my answer to include the code.
  • Snowwire
    Snowwire over 13 years
    I haven't had a chance to try your code yet, but the layouts I'm defining completely in code. So I create a RelativeLayout, then add a child view that is a ProgressBar. setContentView is then used to add the RelativeLayout. There is no layout.xml
  • Ollie C
    Ollie C over 13 years
    That shouldn't make any difference, the XML is held in memory in exactly the same object, type, and structure, as if you create it in code. It's possible you are setting (or not setting) properties that are conflicting with the code that changes the size - try setting your properties exactly as in my example.
  • Ollie C
    Ollie C over 13 years
    I see you added your code. Mine works and yours isn't yet, so I think you need to look at every difference between the two pieces of code and narrow down what exactly is conflicting. I notice you've set the layout_width to fill_parent - that certainly conflicts with you setting the width, as one will take precedence over the other.
  • Snowwire
    Snowwire over 13 years
    I'm at work again now, so will have to try it tonight. Will let you know.
  • sstn
    sstn about 13 years
    I can confirm that this does NOT work - at least not with the bar styles on 2.1 - the spinner styles are sizeable, though. Besides that, the call to invalidate() is not required - which view do you want to invalidate in onCreate()?
  • Ollie C
    Ollie C about 13 years
    @sstn The code above works for me in v2.2 using ProgressBar. The code is in onCreate() as an example only. For me the call to invalidate() is absolutely required, without it, no redraw occurs, and resizing does not happen.
  • Snowwire
    Snowwire about 13 years
    Finally got it working. I did it with a combination of a layout XML holding a LinearLayout with a ProgressBar child element. I then inflated this at runtime and used progressBar.getLayoutParams().width=200 to get the width. The invalidate call wasn't needed. This was on a Nexus One running 2.2. I've still to test it on other platforms. Thanks for all your help guys, it was your posts that got me there.