0

我能够以编程方式构建数十个视图的 LinearLayout 并将其显示为 Activity 的内容视图。我能够遍历 LinearLayout 树并更改视图的背景颜色。

我可以在树上行走并调整视图的相对权重,并在 onCreate() 末尾附近调用 setContentView() 来显示树。

我有一个 seekBar 以交互方式调整颜色,这很有效。同样,我有一个 seekBar 以交互方式调整权重。我知道权重正在正确更改。

但是不知何故,在交互式更改权重后视图不会重新显示,而在交互式更改颜色后会重新显示。

为了在更改权重后重新显示内容视图,我必须做什么?

4

2 回答 2

1

requestLayout()为我工作

<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) {

            }
        });
    }
}
于 2015-06-09T23:25:45.323 回答
0

我找到了一个答案,为什么即使调用 requestLayout() 权重也不会改变。我制作了一个类似于 karokyo 的程序,但我的不使用 XML 布局文件。就像上面的 karakyo 一样,它使用 seekBar 交互地改变权重。但它以编程方式创建所有视图。我发现在将视图添加到 ViewGroup(例如,LinearLayout)时,提供给 addView() 的 LayoutParams 不会复制到视图中,而是作为对象添加。因此,如果在多个 addView() 调用中提供了一个 LayoutParams,那么添加的视图将共享相同的 LayoutParams。然后,如果一个 View 的权重发生变化(通过分配给 getLayoutParams()).weight),其他 View 的权重也会发生变化,因为它们共享相同的 LayoutParams 对象。显然,当从 XML 布局膨胀视图时,

package course.example.interactiveweightexperiment;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.SeekBar;


public class WeightSeekBar extends Activity {
    private final String TAG = "WeightSeekBar-TAG";
    private LinearLayout mainLayout;
    private LinearLayout linearColors;
    private View redView;
    private View blueView;
    SeekBar weightSeekBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        redView = new View(this);
        redView.setBackgroundColor(0xff770000);

        blueView = new View(this);
        blueView.setBackgroundColor(0xff000077);

        weightSeekBar = new SeekBar(this);
        weightSeekBar.setMax(100);
        weightSeekBar.setProgress(50);

        weightSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                ((LinearLayout.LayoutParams) redView.getLayoutParams()).weight = 100 - progress;
                ((LinearLayout.LayoutParams) blueView.getLayoutParams()).weight = progress;

                linearColors.requestLayout();
                // linearColors.invalidate();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        linearColors = new LinearLayout(this);
        linearColors.setOrientation(LinearLayout.VERTICAL);

        linearColors.addView(redView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 50));
        linearColors.addView(blueView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 50));

        /* the following does not allow the child Views to be assigned different weights.
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 50);
        linearColors.addView(redView, params);
        linearColors.addView(blueView, params);
        */

        mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);
        mainLayout.addView(linearColors, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 19));
        mainLayout.addView(weightSeekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1));

        setContentView(mainLayout);
    }
}
于 2015-06-10T21:10:11.513 回答