12

I am facing a problem with the position of the error indicator of my EditText when calling editText.setError("...").

As you can see in the screenshot I am using a BottomSheetDialog with an EditText inside of it. When I display the error indicator, the text is completely out of place. It seems as if the dialog "thinks" that it is full-screen, while it is actually not.

enter image description here

This is my dialog layout file (phone_dialog.xml):

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                             xmlns:app="http://schemas.android.com/apk/res-auto"
                                             android:layout_width="match_parent"
                                             android:layout_height="wrap_content"
                                             android:layout_weight="0"
                                             android:orientation="vertical">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:padding="@dimen/padding_layout_normal"
        android:text="@string/dialog_title_edit_phone"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <EditText
        android:id="@+id/etPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:inputType="phone"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvTitle"/>


    <Button
        android:id="@+id/btnSavePhone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/etPhone"/>

</android.support.constraint.ConstraintLayout>

My Activity layout file (activity_contacts.xml):

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvContacts"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

This is how I show the dialog from my Activity:

PhoneBottomDialog dialog = new PhoneBottomDialog(Context);
dialog.show();

This is my PhoneBottomDialog class:

public class PhoneBottomDialog extends BottomSheetDialog {

    public PhoneBottomDialog(Context context) {
        super(context);

        View view = getLayoutInflater().inflate(R.layout.phone_dialog, null);
        setContentView(view);

        // additional setup below this...
    }

    // ...
}

I am not performing any other layouting inside my custom PhoneButtomDialog. Changing the root layout of my dialog to RelativeLayout or LinearLayout as well as adding a ScrollView did not change anything. It's also not a device or specific Android version related issue as the problem occurs on all of my testing devices ranging from Android 5.0 to 7.1, it also occurs on the emulator.

Does anyone have an idea why this is happening?

Philipp Jahoda
  • 50,880
  • 24
  • 180
  • 187

3 Answers3

7

You can use TextInputLayout and inside that you can define Edit Text.

I have done some modification inside your phone_dialog.xml.

phone_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:layout_gravity="bottom"
    android:background="@android:color/holo_blue_light"
    android:padding="10dp"
    app:behavior_hideable="true"
    app:behavior_peekHeight="60dp"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:padding="10dp"
            android:text="dialog_title_edit_phone" />

        <android.support.design.widget.TextInputLayout
            android:id="@+id/inputPhone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/TextInputLayoutLabel">

            <EditText
                android:id="@+id/etPhone"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Enter phone"
                android:imeOptions="actionDone"
                android:inputType="phone"
                android:maxLines="1"
                android:textSize="20sp" />

        </android.support.design.widget.TextInputLayout>


        <Button
            android:id="@+id/btnSavePhone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/etPhone"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="8dp"
            android:text="Save" />

    </LinearLayout>

</FrameLayout>

Inside style.xml add this.

<style name="TextInputLayoutLabel" parent="Widget.Design.TextInputLayout">
        <!-- Hint color and label color in FALSE state -->
        <item name="android:textColorHint">@android:color/black</item>
        <item name="android:textSize">15sp</item>
        <!-- Label color in TRUE state and bar color FALSE and TRUE State -->
        <item name="colorAccent">@color/colorPrimary</item>
        <item name="colorControlNormal">@color/colorAccent</item>
        <item name="colorControlActivated">@color/colorAccent</item>
    </style>

PhoneBottomDialog.java

public class PhoneBottomDialog extends BottomSheetDialog {

    TextInputLayout inputPhone;
    EditText edtPhone;
    Button btnSave;

    public PhoneBottomDialog(Context context) {
        super(context);

        View view = getLayoutInflater().inflate(R.layout.phone_dialog, null);
        setContentView(view);

        // additional setup below this...

        inputPhone = (TextInputLayout) view.findViewById(R.id.inputPhone);

        edtPhone = (EditText) view.findViewById(R.id.etPhone);
        btnSave = (Button) view.findViewById(R.id.btnSavePhone);

        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!validatePhone())
                    return;
            }
        });

    }

    private boolean validatePhone() {
        if (edtPhone.getText().toString().isEmpty()) {
            inputPhone.setError("Please enter valid phone number with country code.");
            requestFocus(edtPhone);
            return false;
        } else {
            inputPhone.setErrorEnabled(false);
        }
        return true;
    }

    private void requestFocus(View view) {
        if (view.requestFocus()) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }

    // ...
}

And inside Activity.

@SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test24);
        mContext = this;

        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

        PhoneBottomDialog dialog = new PhoneBottomDialog(mContext);
        dialog.show();
}

Below you can see the output for this.

enter image description here

Jay Rathod
  • 11,131
  • 6
  • 34
  • 58
  • 1
    I went with the TIL and got it to work. Still wondering why EditText.setError(...) has such problems with BottomSheetDialog. – Philipp Jahoda May 22 '17 at 12:36
1

From Lollipop(5.0) version android provide TextInputLayout to do this. Use below xml and java code to show same type view.

abc.xml:

<android.support.design.widget.TextInputLayout
                android:id="@+id/text_input_layout_user"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                app:theme="@style/AppTheme">

                <android.support.v7.widget.AppCompatEditText
                    android:id="@+id/et_username"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Username"
                    android:imeOptions="actionNext"
                    android:inputType="text"
                    android:singleLine="true"
                    android:textColor="@color/icons"
                    android:textSize="16sp" />
            </android.support.design.widget.TextInputLayout>

Abc.java:

private TextInputLayout
textInputLayout_User = (TextInputLayout) findViewById(R.id.text_input_layout_user);
textInputLayout_User.setError(getString(R.string.valid_username));
林果皞
  • 7,539
  • 3
  • 55
  • 70
Aniruddh Parihar
  • 3,072
  • 3
  • 21
  • 39
1

add compile 'com.android.support:design:24.2.0' in gradle dependencies

use TextInputLayout in xml.

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputServer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:layout_marginBottom="36dp"
    app:errorTextAppearance="@style/TextErrorAppearance">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ........./>
</android.support.design.widget.TextInputLayout>
Jay Rathod
  • 11,131
  • 6
  • 34
  • 58
Akshay Kumar S
  • 333
  • 3
  • 12