RelativeLayout 中有 TextView (標題) 和 ImageView (刪除線),希望 ImageView 寬度**精確匹配** TextView 文字實際寬度,而非佔滿父容器。
android:layout_height="match_parent"
android:src="@drawable/strike_line" />
結果:title_container 寬度被 ImageView 撐滿,TextView 文字被截斷或置中不正確。
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignLeft="@id/title"
android:layout_alignRight="@id/title"
android:src="@drawable/strike_line"
android:scaleType="fitXY" />
| 屬性 | 作用 |
|---|---|
android:layout_alignLeft="@id/title" | ImageView 左邊緣對齊 TextView 左邊緣 |
android:layout_alignRight="@id/title" | ImageView 右邊緣對齊 TextView 右邊緣 |
android:layout_alignStart/@id/title | API 17+ RTL 支援,建議同時加上 |
android:layout_alignEnd/@id/title | 同上 |
android:scaleType=\"fitXY\" | 圖片非等比例拉伸填滿 ImageView 範圍 (刪除線需求) |
RelativeLayout container = findViewById(R.id.title_container);
TextView title = findViewById(R.id.title);
ImageView strike = findViewById(R.id.title_strike_through);
// 確保參數為 RelativeLayout.LayoutParams
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) strike.getLayoutParams();
if (params == null) {
params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
params.addRule(RelativeLayout.ALIGN_LEFT, title.getId());
params.addRule(RelativeLayout.ALIGN_RIGHT, title.getId());
params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
strike.setLayoutParams(params);
strike.setScaleType(ImageView.ScaleType.FIT_XY);
title.addTextChangedListener(new TextWatcher() {
@Override public void afterTextChanged(Editable s) {
// 強制重新測量佈局,ImageView 會自動跟隨 TextView 新寬度
title.requestLayout();
strike.requestLayout();
}
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
public class StrikeThroughTextView extends TextView {
private Paint strikePaint;
public StrikeThroughTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
strikePaint = new Paint();
strikePaint.setColor(Color.RED);
strikePaint.setStrokeWidth(3f);
strikePaint.setAntiAlias(true);
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 計算文字基線位置
float y = getBaseline() - getTextSize() / 3; // 刪除線大概位置
canvas.drawLine(0, y, getMeasuredWidth(), y, strikePaint);
}
}
優勢:無額外 View、自動匹配文字寬度、效能更好、支援動畫。