You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中EditText自动调整文本大小失效及自定义行间距问题求助

Hey there! Let's break down solutions for both of your desired effects, since you've already tried common approaches and hit specific roadblocks:

1. Auto-adjust text size to fit EditText width per added element

The native autoSizeTextType you tried works to fit the entire text content within the EditText's height, not to shrink text so each manually added line (your "element") fits the width without wrapping. To fix this, we'll create a custom AutoFitEditText that adjusts the font size based on the longest line in your text.

Step-by-Step Implementation

a. Create the custom EditText class

public class AutoFitEditText extends AppCompatEditText {
    private float minTextSize;
    private float maxTextSize;
    private float stepGranularity;
    private final Paint textPaint = new Paint();

    public AutoFitEditText(Context context) {
        super(context);
        initDefaults();
    }

    public AutoFitEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        // Load custom attributes from XML
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.AutoFitEditText);
        minTextSize = ta.getDimension(R.styleable.AutoFitEditText_minTextSize, spToPx(8));
        maxTextSize = ta.getDimension(R.styleable.AutoFitEditText_maxTextSize, spToPx(28));
        stepGranularity = ta.getDimension(R.styleable.AutoFitEditText_stepGranularity, spToPx(1));
        ta.recycle();
        initDefaults();
    }

    private void initDefaults() {
        textPaint.set(getPaint());
        setTextSize(TypedValue.COMPLEX_UNIT_PX, maxTextSize);
        // Listen for text changes to adjust size
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                adjustTextSize();
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });
    }

    private void adjustTextSize() {
        if (getText().length() == 0 || getWidth() == 0) return;

        int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        float currentSize = maxTextSize;
        String[] lines = getText().toString().split("\n");
        float maxLineWidth = 0;

        // Calculate width of longest line at current size
        textPaint.setTextSize(currentSize);
        for (String line : lines) {
            float lineWidth = textPaint.measureText(line);
            if (lineWidth > maxLineWidth) maxLineWidth = lineWidth;
        }

        // Shrink size until longest line fits or we hit min size
        while (maxLineWidth > availableWidth && currentSize > minTextSize) {
            currentSize -= stepGranularity;
            textPaint.setTextSize(currentSize);
            maxLineWidth = 0;
            for (String line : lines) {
                float lineWidth = textPaint.measureText(line);
                if (lineWidth > maxLineWidth) maxLineWidth = lineWidth;
            }
        }

        setTextSize(TypedValue.COMPLEX_UNIT_PX, currentSize);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // Re-adjust if width changes (e.g., screen rotation)
        if (w != oldw) adjustTextSize();
    }

    private float spToPx(float sp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }
}

b. Add custom attributes to res/values/attrs.xml

<declare-styleable name="AutoFitEditText">
    <attr name="minTextSize" format="dimension" />
    <attr name="maxTextSize" format="dimension" />
    <attr name="stepGranularity" format="dimension" />
</declare-styleable>

c. Use the custom EditText in your layout

<com.yourpackage.AutoFitEditText
    android:id="@+id/exercise"
    android:layout_width="300dp" <!-- Your fixed width -->
    android:layout_height="wrap_content"
    android:inputType="textMultiLine|textCapSentences"
    app:minTextSize="8sp"
    app:maxTextSize="28sp"
    app:stepGranularity="1sp" />

Now, every time you add an element to the EditText, the font size will automatically shrink to fit the longest line within the EditText's width.


2. Add spacing between manually added elements (not auto-wrapped lines)

The lineSpacingExtra attribute applies to all lines, including auto-wrapped ones. Instead, we'll use Spannable Strings to add spacing only between your manually added elements (each separated by \n).

Implementation

When adding a new element to the EditText, wrap it in a Spannable to add a top margin to the new element (skip this for the first element):

EditText exercise = findViewById(R.id.exercise);
String newElement = "Your long text that may wrap automatically";
SpannableStringBuilder ssb = new SpannableStringBuilder(exercise.getText());

// Add spacing if this isn't the first element
if (exercise.getText().length() > 0) {
    ssb.append("\n");
    // Convert desired dp spacing to pixels
    int paragraphSpacing = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        16, // Adjust this value for your desired spacing
        getResources().getDisplayMetrics()
    );
    // Add a margin to the start of the new element
    ssb.setSpan(
        new LeadingMarginSpan.Standard(0, paragraphSpacing),
        ssb.length(),
        ssb.length() + newElement.length(),
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    );
}

// Append the new element
ssb.append(newElement);
exercise.setText(ssb);

How it works:

  • LeadingMarginSpan.Standard(0, paragraphSpacing) adds extra space above the new element's first line.
  • Auto-wrapped lines within the same element will only use the EditText's default line spacing (set with android:lineSpacingExtra if needed).
  • You can adjust the 16 value to control how much spacing appears between your elements.

内容的提问来源于stack exchange,提问作者Malte Ge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:22:42