简体   繁体   English

Android:以编程方式填充线性布局,它会获得额外的空间

[英]Android: populating Linear Layout programmatically, It gets extra space

I'm trying to populate a LinearLayout horizontally with some ImageViews programmatically. 我正在尝试以编程方式水平填充一些ImageViewsLinearLayout In horizontal directon, everything works very well, but it reserves extra space vertically what I don't want. 在水平方向上,一切工作都很好,但它在垂直方向保留了我不需要的额外空间。

Here is the xml: 这是xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="es.uam.dadm.jacopo_grassi_connecta4.Settings" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/your_color" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/your_color_container" >

</LinearLayout>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/adv_color" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/adv_color_container" >

</LinearLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/sounds" />

    <Switch
        android:id="@+id/sounds_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true" />
</RelativeLayout>

and here's the java code: 这是java代码:

private PlayerDataSource playersdb;
private Player player;

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

    Bundle extras = getIntent().getExtras();
    playersdb = new PlayerDataSource(this);
    player = playersdb.getPlayer(extras.getString(Utils.PARAM_PLAYER_ID));

    buildColors();

    Switch sounds = (Switch)findViewById(R.id.sounds_switch);
    sounds.setOnCheckedChangeListener(this);
    sounds.setChecked(player.getSounds() == 0 ? false : true);
}

@Override
public void onClick(View v) {
    Integer tag = (Integer) v.getTag(R.id.TAG_ADV);
    if(tag == null){        //your color
        tag = (Integer) v.getTag(R.id.TAG_YOU);
        player.setColor(tag);
    }else{                  //adv color
        player.setColorAdv(tag);
    }
    playersdb.updatePlayer(player);
    buildColors();
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if(isChecked){
        player.setSounds(1);
    }else{
        player.setSounds(0);
    }
    playersdb.updatePlayer(player);
}

private void buildColors(){
    LinearLayout parent = (LinearLayout)findViewById(R.id.your_color_container);
    parent.removeAllViewsInLayout();

    for (int i = 0; i < 5; ++i) {
        LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.weight = 0.2f;
        ImageView v = new ImageView(this);
        Integer drawable = null;
        switch (i){
        case 0:
            drawable = R.drawable.red_piece;
            break;
        case 1:
            drawable = R.drawable.yellow_piece;
            break;
        case 2:
            drawable = R.drawable.green_piece;
            break;
        case 3:
            drawable = R.drawable.purple_piece;
            break;
        case 4:
            drawable = R.drawable.azure_piece;
            break;
        }
        v.setLayoutParams(params);
        v.setImageResource(drawable);
        v.setTag(R.id.TAG_YOU, drawable);
        v.setOnClickListener(this);

        if (drawable.equals(player.getColor())) {
            v.setBackgroundColor(getResources().getColor(R.color.azul));
        }

        parent.addView(v);
    }

    parent = (LinearLayout)findViewById(R.id.adv_color_container);
    parent.removeAllViewsInLayout();

    for (int i = 0; i < 5; ++i) {
        LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.weight = 0.2f;
        ImageView v = new ImageView(this);
        Integer drawable = null;
        switch (i){
        case 0:
            drawable = R.drawable.red_piece;
            break;
        case 1:
            drawable = R.drawable.yellow_piece;
            break;
        case 2:
            drawable = R.drawable.green_piece;
            break;
        case 3:
            drawable = R.drawable.purple_piece;
            break;
        case 4:
            drawable = R.drawable.azure_piece;
            break;
        }
        v.setLayoutParams(params);
        v.setImageResource(drawable);
        v.setTag(R.id.TAG_ADV, drawable);
        v.setOnClickListener(this);

        if (drawable.equals(player.getColorAdv())) {
            v.setBackgroundColor(getResources().getColor(R.color.azul));
        }

        parent.addView(v);
    }
}

and that's the result: 结果是:

结果

Obviously, the images are perfect squares. 显然,图像是完美的正方形。

What am I doing wrong? 我究竟做错了什么?

如果将外部 LinearLayout的android:layout_height更改为“ wrap_content”,是否可以正常工作?

尝试将LinearLayout.Params的宽度和高度设置为“ LayoutParams.WRAP_CONTENT”,并将XML文件中的线性布局的高度设置为

尝试parent.addView(v, params);

This is how to solve your problem. 这是解决问题的方法。

(the below code should be added into your for loop before parent.addView(v) (以下代码应在parent.addView(v)之前添加到for循环中

You need to use a Runnable thread in order to get the Views width which will be set as the height at runtime or else you'll be trying to set the Height before you know the View's width because the layout hasn't been drawn yet. 您需要使用Runnable线程来获取Views宽度,该宽度将在运行时设置为高度,否则您将在知道View宽度之前尝试设置Height,因为尚未绘制布局。

v.post(new Runnable() {
    @Override
    public void run() {
        LinearLayout.LayoutParams mParams;
        mParams = (LinearLayout.LayoutParams) v.getLayoutParams();
        mParams.height = v.getWidth();
        v.setLayoutParams(mParams);
        v.postInvalidate();
    }
});

v.postInvalidate() is called to force the view to redraw while on a separate thread than the UI thread 调用v.postInvalidate()强制视图在与UI线程不同的线程上重绘

通过添加@Terence解决了

v.setAdjustViewBounds = true;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM