Android应用中三列TableLayout无法正常居中问题求助
Hey there, I see you've spent 6 hours troubleshooting this centering glitch—let's get this sorted out. The problem here is that when you add rows dynamically, you're not setting consistent layout parameters for your TextViews and TableRow, which breaks the centering that worked initially with your header row.
Why It's Happening
Your header row uses fixed-width TextViews (90dp) and the TableLayout has android:stretchColumns="*" to distribute space evenly. But when you add dynamic rows:
- You're not setting proper layout parameters for the TextViews, so they size themselves based on content instead of matching the header columns.
- The TableRow is using
WRAP_CONTENTfor width, so it doesn't fill the full width of the TableLayout, throwing off the centering.
Step-by-Step Fix
Let's adjust your populate method to match the header's structure and maintain consistent sizing:
Add Layout Parameters to TextViews
Give each dynamic TextView the same width as your header (90dp) or use weighted sizing to leveragestretchColumns="*". Here's both options:Option 1: Fixed width (matches header exactly)
// Create TableRow.LayoutParams with fixed width matching header TableRow.LayoutParams tvParams = new TableRow.LayoutParams(90, TableRow.LayoutParams.WRAP_CONTENT); // Apply to each TextView t1.setLayoutParams(tvParams); t2.setLayoutParams(tvParams); t3.setLayoutParams(tvParams);Option 2: Weighted sizing (uses stretchColumns to distribute space evenly)
// Use 0dp width and weight 1 to let stretchColumns handle sizing TableRow.LayoutParams tvParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 1f); t1.setLayoutParams(tvParams); t2.setLayoutParams(tvParams); t3.setLayoutParams(tvParams);Update TableRow Layout Parameters
Change the TableRow's width toMATCH_PARENTso it fills the entire TableLayout width, which keeps the centering intact:table.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));Optional: Set Gravity for Text Alignment
Uncomment your gravity lines if you want text centered inside each cell (matches the header'scenter_horizontal):t1.setGravity(Gravity.CENTER_HORIZONTAL); t2.setGravity(Gravity.CENTER_HORIZONTAL); t3.setGravity(Gravity.CENTER_HORIZONTAL);Note: Use
Gravity.CENTER_HORIZONTALinstead of the magic number 1 for readability.
Full Modified populate Method
Here's how your updated method will look with fixed-width TextViews:
public void populate(String name, String description, String grade){ row = new TableRow(this); t1 = new TextView(this); t1.setTextColor(getResources().getColor(R.color.colorPrimary)); t2 = new TextView(this); t2.setTextColor(getResources().getColor(R.color.colorPrimary)); t3 = new TextView(this); t3.setTextColor(getResources().getColor(R.color.colorPrimary)); t1.setText(name); t2.setText(description); t3.setText(grade); t1.setTypeface(null, Typeface.BOLD); // Use Typeface.BOLD instead of magic number 1 t2.setTypeface(null, Typeface.BOLD); t3.setTypeface(null, Typeface.BOLD); t1.setBackground(getResources().getDrawable(R.drawable.cell_shape)); t2.setBackground(getResources().getDrawable(R.drawable.cell_shape)); t3.setBackground(getResources().getDrawable(R.drawable.cell_shape)); t1.setTextSize(15); t2.setTextSize(15); t3.setTextSize(15); t1.setPadding(20, 0, 0, 0); t2.setPadding(20, 0, 0, 0); t3.setPadding(20, 0, 0, 0); // Add layout parameters to match header width TableRow.LayoutParams tvParams = new TableRow.LayoutParams(90, TableRow.LayoutParams.WRAP_CONTENT); t1.setLayoutParams(tvParams); t2.setLayoutParams(tvParams); t3.setLayoutParams(tvParams); // Set text gravity to match header t1.setGravity(Gravity.CENTER_HORIZONTAL); t2.setGravity(Gravity.CENTER_HORIZONTAL); t3.setGravity(Gravity.CENTER_HORIZONTAL); row.addView(t1); row.addView(t2); row.addView(t3); // Make TableRow fill TableLayout width table.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)); }
Quick Notes
- Avoid using magic numbers (like
1for bold or gravity) — use the constant values fromTypefaceandGravityclasses for better readability and maintainability. - Your header uses
android:widthwhich is deprecated; consider switching toandroid:layout_width="90dp"for modern compatibility.
This should make your dynamic rows match the header's structure, keeping the entire TableLayout centered as expected.
内容的提问来源于stack exchange,提问作者Macoryx

