Search code examples
androidandroid-linearlayoutandroid-layout-weightsetcontentview

Android LinearLayout is not redisplayed after changing weights programmatically


I am able to construct a LinearLayout of dozens of Views programmatically and to display it as the content view of an Activity. I am able to walk the LinearLayout tree and change the backgroundcolors of the Views.

And I am able to walk the tree and adjust the relative weights of the Views and display the tree using a call to setContentView() near the end of onCreate().

I have a seekBar to adjust the colors interactively, and that works. Similarly I have a seekBar to adjust the weights interactively. I know the weights are being changed correctly.

But somehow the view is not redisplayed after changing the weights interactively, whereas it is redisplayed after changing the colors interactively.

What do I have to do in order to redisplay the content view after changing the weights?


Solution

  • requestLayout() works for me

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:orientation="vertical">
        <SeekBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/seek"
            android:progress="50"
            android:max="100"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/linear">
            <View
                android:layout_width="0dp"
                android:layout_height="20dp"
                android:layout_weight="1"
                android:id="@+id/blue"
                android:background="#00f"/>
            <View
                android:layout_width="0dp"
                android:layout_height="20dp"
                android:layout_weight="1"
                android:id="@+id/red"
                android:background="#f00"/>
        </LinearLayout>
    </LinearLayout>
    

    public class MainActivity extends AppCompatActivity {
        private LinearLayout linear;
        private View red;
        private View blue;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            SeekBar seek = (SeekBar) findViewById(R.id.seek);
            linear = (LinearLayout) findViewById(R.id.linear);
            red = findViewById(R.id.red);
            blue = findViewById(R.id.blue);
            seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    ((LinearLayout.LayoutParams) red.getLayoutParams()).weight = 100 - progress;
                    ((LinearLayout.LayoutParams) blue.getLayoutParams()).weight = progress;
    
                    linear.requestLayout();
                }
    
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
    
                }
    
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
    
                }
            });
        }
    }