概述
| 平台
RK3288 + Android 8.1 + compileSdkVersion 26.
| 问题
使用了TableLayout布局电话的拨号按键界面, 效果如下图 (正常):
在后续开发过程的某次修改后, 出现效果图(不正常):
合并两张效果图可看得更明显(红线参考位置):
在布局中 TextView
的 android:gravity=center
已经设置, 从图中可以看出在垂直方向的居中失效了
排查
themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="dw" type="dimen">60dp</item>
<item name="dh" type="dimen">42dp</item>
<style name="TV">
<item name="android:textColor">#FF000000</item>
<item name="android:gravity">center</item>
<item name="android:textSize">22sp</item>
<item name="android:layout_width">@dimen/dw</item>
<item name="android:layout_height">@dimen/dh</item>
<item name="android:layout_marginLeft">6dp</item>
<item name="android:layout_marginTop">6dp</item>
<item name="android:background">@drawable/selector_tv_bg</item>
</style>
</resources>
table_layout_test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff7f7f9">
<ListView android:id="@+id/lv"
android:layout_width="400dp"
android:layout_height="400dp"
/>
<RelativeLayout android:id="@+id/rlPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/lv"
android:background="#220000FF">
<TableLayout android:id="@+id/tl"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TableRow>
<TextView style="@style/TV"
android:text="7"/>
<TextView style="@style/TV"
android:text="8"/>
<TextView style="@style/TV"
android:text="9"/>
</TableRow>
<TableRow>
<TextView style="@style/TV"
android:text="4"/>
<TextView style="@style/TV"
android:text="5"/>
<TextView style="@style/TV"
android:text="6"/>
</TableRow>
<TableRow>
<TextView style="@style/TV"
android:text="1"/>
<TextView style="@style/TV"
android:text="2"/>
<TextView style="@style/TV"
android:text="3"/>
</TableRow>
<TableRow>
<TextView style="@style/TV"
android:text="*"/>
<TextView style="@style/TV"
android:text="0"/>
<TextView style="@style/TV"
android:text="#"/>
</TableRow>
</TableLayout>
</RelativeLayout>
</RelativeLayout>
TableLayoutTest.java
public class TableLayoutTest extends Activity implements View.OnClickListener {
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.table_layout_test);
ViewGroup tl = (ViewGroup) findViewById(R.id.tl);
for(int i = 0; i < tl.getChildCount(); i ++){
ViewGroup row = (ViewGroup) tl.getChildAt(i);
for(int j = 0; j < row.getChildCount(); j ++){
row.getChildAt(j).setOnClickListener(this);
}
}
lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new ArrayAdapter<String>(TableLayoutTest.this,
R.layout.lv_item,
new String[]{"001", "002", "003", "004", "004"}));
}
@Override
public void onClick(View view) {
Log.d("TableLayoutTest", "onClick " + ((TextView)view).getText().toString());
}
}
布局并不复杂, 一个ListView
加上一个 RelativeLayout
, 于是, 把ListView
先去带掉, 果然好了, 这问题就很谜了.
这不合理, 于是, 布局不变, 去掉 lv.setAdapter
, 结果也是好的…
判断会不会是时序的原因, 于是延迟 3秒 setAdapter
:
lv.postDelayed(new Runnable() {
@Override
public void run() {
lv.setAdapter(new ArrayAdapter<String>(TableLayoutTest.this,
R.layout.lv_item,
new String[]{"001", "002", "003", "004", "004"}));
}
}, 3000);
好吧, 刚开始是好的, ListView有内容了后, 出现:
原因参考自ChatGpt
可能原因
TableLayout
的宽度: 由于你使用的是wrap_content
,TableLayout
和TableRow
的宽度可能根据子元素的内容大小进行调整。如果TableLayout
或TableRow
的宽度与TextView
的内容宽度相近,gravity="center"
可能无法正常生效。
TableRow
默认行为:TableRow
中的子元素默认是按内容宽度排列的,而不是平分整个行的宽度。这可能导致TextView
的内容没有在整个单元格内居中。解决方法
为了确保
TableLayout
中的TextView
内容能够正确居中,可以考虑以下方法:
- 为
TextView
设置layout_width="0dp"
并加上layout_weight="1"
: 这将使每个TextView
在同一行内平分可用空间,从而使文本居中。<TableRow> <TextView style="@style/TV" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="7"/> <TextView style="@style/TV" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="8"/> <TextView style="@style/TV" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="9"/> </TableRow>
TableLayout
的stretchColumns
属性: 你可以使用TableLayout
的stretchColumns
属性,使特定列自动拉伸以填充空间,从而在特定情况下实现内容居中。<TableLayout android:id="@+id/tl" android:layout_width="wrap_content" android:layout_height="wrap_content" android:stretchColumns="*">
这里的
android:stretchColumns="*"
表示所有列都可以被拉伸以适应屏幕宽度。总结
通过设置
layout_width="0dp"
并配合layout_weight="1"
,可以确保TextView
在其单元格中居中显示。stretchColumns
属性也可以> 用来调整列的宽度,确保内容的对齐方式更加合理。试试看是否能解决你的问题!
ChatGPT提供的几种方案并没有解决问题, 方案中提及的原因有待验证.
| 解决方案
- 根布局改为FrameLayout
- 修改TableLayout的layout_width属性配置, 指定
android:layout_width="match_parent"
或android:layout_width="300dp"
都可以 - TableLayout 用 LinearLayout或其他布局替换
-
指定父容器布局宽度, 并设置 TableRow的宽度
RelativeLayout android:id=“@+id/rlPhone”
TableLayout android:id=“@+id/tl”
TableRow android:layout_width=“200dp”>