Android开发:如何动态修改TextCell视图尺寸(不改动XML)
问题
我有一个默认宽度100sp、高度35sp的自定义TextCell视图,还有一个宽度50sp的垂直LinearLayout。点击按钮时会往这个LinearLayout里添加多个TextCell,要求不修改text_cell.xml文件(该视图在其他场景要保留原有尺寸),但添加到这个LinearLayout的TextCell宽度要设为50sp。我试过用LayoutParams设置尺寸,但视图还是保持100sp宽度,求解决办法。
相关代码
text_cell.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:foregroundGravity="center" tools:ignore="MissingConstraints"> <View android:id="@+id/black_frame" android:layout_width="100sp" android:layout_height="35sp" android:background="@color/black" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/color_box" app:layout_constraintBottom_toBottomOf="@+id/black_frame" app:layout_constraintEnd_toEndOf="@+id/black_frame" app:layout_constraintStart_toStartOf="@+id/black_frame" app:layout_constraintTop_toTopOf="@+id/black_frame" android:layout_width="98sp" android:layout_height="33sp" android:background="#ffffff" android:gravity="center" android:textColor="@color/black" android:text="" android:autoSizeTextType="uniform" android:lines="1" android:padding="5sp" android:textStyle="bold" android:textAlignment="center"/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
TextCell.java
package com.example.teacherplanner; import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.view.LayoutInflater; import android.widget.RelativeLayout; import android.widget.TextView; public class TextCell extends RelativeLayout { public TextCell(Context context,String text,String color) { super(context); init(context,text,color); } public TextCell(Context context,String text,String color, AttributeSet attrs) { super(context, attrs); init(context,text,color); } private void init(Context context, String text, String color) { LayoutInflater inflater = LayoutInflater.from(context); inflater.inflate(R.layout.text_cell,this,true); TextView TextInside = findViewById(R.id.color_box); TextInside.setText(text); TextInside.setBackgroundColor(Color.parseColor(color)); } }
尝试的LayoutParams代码
第一种尝试:
TextCell timestamp = new TextCell(WeekEditing.this,"test","#FFD54F"); timestamp.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT )); TimeStamps.addView(timestamp);
第二种尝试:
TextCell timestamp = new TextCell(WeekEditing.this,"test","#FFD54F"); int widthInPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 50, getResources().getDisplayMetrics()); int heightInPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 35, getResources().getDisplayMetrics()); ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(widthInPixels, heightInPixels); timestamp.setLayoutParams(layoutParams); TimeStamps.addView(timestamp);
解决方法
问题核心是TextCell的根布局为wrap_content,内部black_frame固定100sp宽度直接撑开了外层布局,导致你设置的LayoutParams无法约束内部视图尺寸。以下两种方案均可解决:
方案一:视图缩放(快速实现)
通过缩放整个TextCell来适配目标宽度,无需修改类结构:
TextCell timestamp = new TextCell(WeekEditing.this,"test","#FFD54F"); // 计算缩放比例:目标宽度50sp / 原宽度100sp float scale = 0.5f; timestamp.setScaleX(scale); // 高度保持原尺寸,无需缩放Y轴 ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT ); timestamp.setLayoutParams(params); TimeStamps.addView(timestamp);
这种方式简单直接,不会影响其他场景的TextCell使用,适合快速实现需求。
方案二:动态修改内部视图尺寸(精准控制,推荐)
在TextCell类中添加公开方法,动态修改内部black_frame和color_box的尺寸,避免缩放带来的文本模糊问题:
- 修改TextCell.java,添加尺寸控制方法:
public class TextCell extends RelativeLayout { private View blackFrame; private TextView colorBox; // 原构造方法保持不变 private void init(Context context, String text, String color) { LayoutInflater inflater = LayoutInflater.from(context); inflater.inflate(R.layout.text_cell,this,true); blackFrame = findViewById(R.id.black_frame); colorBox = findViewById(R.id.color_box); colorBox.setText(text); colorBox.setBackgroundColor(Color.parseColor(color)); } // 新增:设置自定义尺寸的方法 public void setCustomSize(int widthSp, int heightSp) { Context context = getContext(); // 将sp转换为像素 int widthPx = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, widthSp, context.getResources().getDisplayMetrics() ); int heightPx = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, heightSp, context.getResources().getDisplayMetrics() ); // 修改黑色边框尺寸 ViewGroup.LayoutParams frameParams = blackFrame.getLayoutParams(); frameParams.width = widthPx; frameParams.height = heightPx; blackFrame.setLayoutParams(frameParams); // 修改内部文本框尺寸(保持比边框小2sp,和原布局一致) int boxOffsetPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,2,context.getResources().getDisplayMetrics()); ViewGroup.LayoutParams boxParams = colorBox.getLayoutParams(); boxParams.width = widthPx - boxOffsetPx; boxParams.height = heightPx - boxOffsetPx; colorBox.setLayoutParams(boxParams); } }
- 添加TextCell时调用该方法:
TextCell timestamp = new TextCell(WeekEditing.this,"test","#FFD54F"); // 设置宽度50sp,高度保持原35sp timestamp.setCustomSize(50,35); // 让TextCell占满LinearLayout宽度 timestamp.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT )); TimeStamps.addView(timestamp);
这种方式可以精准控制布局细节,没有缩放副作用,同时保留原xml布局的兼容性。
内容的提问来源于stack exchange,提问作者NikoBitan
相关产品推荐
相关产品推荐

