Android:以编程方式填充线性布局,得到额外的 space
Android: populating Linear Layout programmatically, It gets extra space
我正在尝试以编程方式用一些 ImageViews
水平填充 LinearLayout
。在水平方向上,一切都很好,但它在垂直方向上保留了额外的 space 我不想要的东西。
这里是 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);
}
}
这就是结果:
显然,图像是完美的正方形。
我做错了什么?
如果将 outer LinearLayout 的 android:layout_height 更改为 "wrap_content" 是否有效?
尝试将 LinearLayout.Params 宽度和高度设为 "LayoutParams.WRAP_CONTENT" 以及 XML 文件中线性布局的高度
尝试parent.addView(v, params);
这就是解决您问题的方法。
(以下代码应在 parent.addView(v)
之前添加到您的 for 循环中
您需要使用 Runnable 线程才能获得将在运行时设置为高度的视图宽度,否则您将在知道视图宽度之前尝试设置高度,因为布局还没有还没抽到。
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 线程
不同的线程上重绘
感谢@Terence 解决了
已添加
v.setAdjustViewBounds = true;
我正在尝试以编程方式用一些 ImageViews
水平填充 LinearLayout
。在水平方向上,一切都很好,但它在垂直方向上保留了额外的 space 我不想要的东西。
这里是 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);
}
}
这就是结果:
显然,图像是完美的正方形。
我做错了什么?
如果将 outer LinearLayout 的 android:layout_height 更改为 "wrap_content" 是否有效?
尝试将 LinearLayout.Params 宽度和高度设为 "LayoutParams.WRAP_CONTENT" 以及 XML 文件中线性布局的高度
尝试parent.addView(v, params);
这就是解决您问题的方法。
(以下代码应在 parent.addView(v)
之前添加到您的 for 循环中您需要使用 Runnable 线程才能获得将在运行时设置为高度的视图宽度,否则您将在知道视图宽度之前尝试设置高度,因为布局还没有还没抽到。
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 线程
不同的线程上重绘感谢@Terence 解决了 已添加
v.setAdjustViewBounds = true;