Small EditText have a setError with a lot of lines

2020-03-09 07:40发布

I have a small EditText and I want to display errors (using editText.setError()) in it. In Android API 10 the message is displayed in a lot of lines and it's unreadable. In Android 15 works relatively fine. I attach screenshots to illustrate the problem at the end of the question.

How I can display the error messages in a appropriate mode?

I wrote a little example to reproduce the problem:

The Activity:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ((EditText) findViewById(R.id.b)).setError("A error description and bla bla bla bla bla.");
}

The layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <EditText
        android:id="@+id/a"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />


    <EditText
        android:id="@+id/b"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/c"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/d"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/e"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/f"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

Device with Android API 10:

Device with Android API 10

Tablet with Android API 15:

Tablet with Android API 15

Related question. But the answer doesn't work for me.


UPDATE

I executed the same code on two equals simulators except the API level. The results can be seen on the screens. The API 15 still does not fix the error completely. The text is legible but the popup is not in the correct position.

API 10 API 15

5条回答
小情绪 Triste *
2楼-- · 2020-03-09 07:49

I think you should set the width of the edit text as fill parents so that it will take the proper place, otherwise give the width like 200 or 250 dp so that in that particular width your error message will be shown to you.

查看更多
何必那么认真
3楼-- · 2020-03-09 07:49

does those two emulator have the same screen sizes?.. if so, i think it would be appropriate to set the layout_widths and the heights to wrap content for the popup and if the error still persist then define specifically the width and height of the popup

查看更多
对你真心纯属浪费
4楼-- · 2020-03-09 07:54

So looking at the source for 2.3.3 the width of the error text is set to slightly less than the width of the TextView it is related to.

They've jimmied around with that for 4.0.3 so that, in your example, the width of the pop-up is correct - but the nature of your layout is such that the pointer is in the wrong place.

I think you've a reasonable example for a bug report against 4.0.3 as I don't think you've got that unusual a use-case.

In order to sort this out though I'd recommend using a TextView that you hide and reveal as necessary. You can set an error image on the edit text as below.

Drawable errorImage = getContext().getResources().getDrawable( R.drawable.your_error_image);
theEditTextInQuestion.setCompoundDrawableWithIntrinsicBounds(errorImage, null, null, null);”
查看更多
我命由我不由天
5楼-- · 2020-03-09 07:57

I think a problem might be that the LinearLayout in your XML has no weightSum attribute. I do not know if you can use layout_weight in child views if LinearLayout does not have a weightSum declared. Also, try changing your layout_widths to "wrap_content" and get rid of the layout_weights if that doesnt work.

查看更多
走好不送
6楼-- · 2020-03-09 08:10

on api 14, TextView use this class;

private static class ErrorPopup extends PopupWindow {
    private boolean mAbove = false;
    private final TextView mView;
    private int mPopupInlineErrorBackgroundId = 0;
    private int mPopupInlineErrorAboveBackgroundId = 0;

    ErrorPopup(TextView v, int width, int height) {
        super(v, width, height);
        mView = v;
        // Make sure the TextView has a background set as it will be used the first time it is
        // shown and positionned. Initialized with below background, which should have
        // dimensions identical to the above version for this to work (and is more likely).
        mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
                com.android.internal.R.styleable.Theme_errorMessageBackground);
        mView.setBackgroundResource(mPopupInlineErrorBackgroundId);
    }

    void fixDirection(boolean above) {
        mAbove = above;

        if (above) {
            mPopupInlineErrorAboveBackgroundId =
                getResourceId(mPopupInlineErrorAboveBackgroundId,
                        com.android.internal.R.styleable.Theme_errorMessageAboveBackground);
        } else {
            mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
                    com.android.internal.R.styleable.Theme_errorMessageBackground);
        }

        mView.setBackgroundResource(above ? mPopupInlineErrorAboveBackgroundId :
            mPopupInlineErrorBackgroundId);
    }

    private int getResourceId(int currentId, int index) {
        if (currentId == 0) {
            TypedArray styledAttributes = mView.getContext().obtainStyledAttributes(
                    R.styleable.Theme);
            currentId = styledAttributes.getResourceId(index, 0);
            styledAttributes.recycle();
        }
        return currentId;
    }

    @Override
    public void update(int x, int y, int w, int h, boolean force) {
        super.update(x, y, w, h, force);

        boolean above = isAboveAnchor();
        if (above != mAbove) {
            fixDirection(above);
        }
    }
}

And call like this;

final float scale = getResources().getDisplayMetrics().density;
            mPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f), (int) (50 * scale + 0.5f));
            mPopup.setFocusable(false);

So Android TextView use your phone density. I tried for change density but i couldn't work because it need root. If you can this, maybe its work. But i guess it is not possible.

查看更多
登录 后发表回答