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

时间:2015-03-17 08:06:26

标签: android android-linearlayout android-imageview

我正在尝试以编程方式使用LinearLayout水平填充ImageViews。在水平方向上,一切都运行良好,但它在垂直方向上保留了我不想要的空间。

这是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>

这是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);
    }
}

这就是结果:

result

显然,这些图像是完美的正方形。

我做错了什么?

5 个答案:

答案 0 :(得分:0)

如果将外部 LinearLayout的android:layout_height更改为&#34; wrap_content&#34;是否有效?

答案 1 :(得分:0)

尝试制作LinearLayout.Params宽度&amp;高度为“LayoutParams.WRAP_CONTENT”&amp;也是XML文件中线性布局的高度

答案 2 :(得分:0)

尝试parent.addView(v, params);

答案 3 :(得分:0)

这是解决问题的方法。

(以下代码应添加到parent.addView(v)

之前的for循环中

你需要使用一个Runnable线程来获取Views宽度,它将在运行时设置为高度,否则你将在知道View的宽度之前设置高度,因为布局还没有画了。

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()以强制视图在与UI线程不同的线程上重绘

答案 4 :(得分:0)

感谢@Terence 添加了

v.setAdjustViewBounds = true;