teekib
teekib

Reputation: 2821

EditText: Center hint but have entered text start from top

Hi i have a edit text with the hint, i made the hint as middle using android:gravity:"center". when i start typing from in the edittext the typing is starting from the middle, how to make the typing start from leftcorner while still hint is centered

<EditText
        android:id="@+id/edittext"
        android:layout_width="230dp"
        android:layout_height="110dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/imageView1"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="33dp"
        android:layout_toLeftOf="@+id/relativeLayout1"
        android:background="@drawable/roundcorners"
        android:ems="10"
        android:gravity="center_horizontal"
        android:hint="@string/fbhint"
        android:lines="6"
        android:paddingRight="5dp"
        android:textSize="14sp"      
        android:windowSoftInputMode="stateHidden" />

Upvotes: 14

Views: 20982

Answers (3)

Graeme Campbell
Graeme Campbell

Reputation: 384

I was trying to do the opposite scenario - for the hint to appear at the left, and the typed text to appear in the middle, and I found part of the solution I needed here, but for the sake of anyone else who is trying to do this, I thought I'd post my full solution, adapted to the above scenario :).

So as I was trying to figure this out, I found there were two challenges: 1) For the hint to appear centered, while any text that the user types is left aligned. 2) For the cursor to immediately appear where the user's text would appear, rather than where the hint begins. I also wanted the hint to remain until the user started to type, and to reappear when the user deleted what they had typed.

My solution involved two EditText boxes layered on top of each other, with the upper box containing the hint, and the lower one containing the text. as so:

<!-- This EditText box is where the user writes their text. 
It is aligned left, doesn't have a hint in it, 
and is the desired width of the box 
!-->

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textShortMessage"
        android:fontFamily="sans-serif-medium"
        android:background="@color/white"
        android:layout_marginTop="5dp"
        android:id="@+id/event_heading"
        android:hint=""
        android:layout_below="@id/page_title"
        />

<!-- This second EditText box only contains the hint text. 
It is centered, is only the width of the hint text, 
and for my purposes, the text was italic !-->

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textShortMessage"
        android:fontFamily="sans-serif-medium"
        android:background="@color/white"
        android:layout_marginTop="5dp"
        android:layout_below="@id/page_title"
        android:id="@+id/event_headingHint"
        android:hint="Heading"
        android:gravity="center"
        android:textStyle="italic"
        />

The box containing the hint was second, so that it appeared above the other one. I was using this within a fragment so I then overrode onCreateView in the fragment, pulled out the two EditText boxes, and sent them to a method I wrote for adding the necessary listeners as follows:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.fragment_create_event, container, false);
    EditText heading = (EditText) view.findViewById(R.id.event_heading);
    EditText headingHint = (EditText) view.findViewById(R.id.event_headingHint);
    addFormatTidier(heading, headingHint);
    return view;
}

Otherwise, if trying to do this within an Activity rather than a fragment, you could use the same code inside the onCreate method, just after the setContentView command as so:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    ...
    setContentView(R.layout.activity_add_event);
    EditText heading = (EditText) findViewById(R.id.event_heading);
    EditText headingHint = (EditText) findViewById(R.id.event_headingHint);
    addFormatTidier(heading, headingHint);
    ...
}

Then finally for my 'addFormatTidier' method, I added a listener to each EditText box: First I attached an onFocusChange listener to the 'hint' EditText, to move the focus over to the other EditText if the user clicked on the hint. Then I attached an addTextChangedListener to my other EditText, in order to remove the hint once the user started typing, and to restore it if the user deleted all they had typed, as follows:

private void addFormatTidier(final EditText text, final EditText hint)
{

    // save the hint so I can restore it later
    final CharSequence hintText = hint.getHint();

    // Add a listener to shift focus away from the hint text to the other EditText when the hint is clicked.
    hint.setOnFocusChangeListener(new android.view.View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
            if (hasFocus)
            {
                text.requestFocus();
            }
        }
    });

    // Add a listener to remove the hint text when the user starts typing, and to restore it when the user clears what they have typed.
    text.addTextChangedListener(new TextWatcher()
    {
        public void afterTextChanged(Editable s) {}
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() > 0)
            {
                hint.setHint("");
            }
            else
            {
                hint.setHint(hintText);
            }
        }
    });
}

For the hint to disappear as soon as the user clicks on the field and reappear if they click away without leaving any text inside, the following method could be used instead:

private void addFormatTidier(final EditText text, final EditText hint)
{

    // save the hint so I can restore it later
    final CharSequence hintText = hint.getHint();

    // Add a listener to shift focus away from the hint text to the other EditText when the hint is clicked, and simultaneously clear the hint text.
    hint.setOnFocusChangeListener(new android.view.View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
            if (hasFocus)
            {
                text.requestFocus();
                hint.setHint("");
            }
        }
    });

    // Add a listener to remove the hint text when the main EditText receives focus, and to restore it when the EditText loses focus without any text inside it.
    text.setOnFocusChangeListener(new android.view.View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
            if (hasFocus)
            {
                hint.setHint("");
            }
            else
            {
                if(!(text.getText().length()>0))
                {
                    hint.setHint(hintText);
                }
            }
        }
    });
}

I hope this is useful to anyone else trying to figure out how to solve a similar problem :D. It was userM1433372 in his comment above who set me on the right track for where to start :D.

Upvotes: 1

userM1433372
userM1433372

Reputation: 5497

I don't think this is possible "out-of-the box" but you can do it programmatically:

yourEditText.addTextChangedListener(new TextWatcher() {
     public void afterTextChanged(Editable s) {}
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

     public void onTextChanged(CharSequence s, int start, int before, int count) {
          if (s.length() > 0){
               // position the text type in the left top corner
               yourEditText.setGravity(Gravity.LEFT | Gravity.TOP);  
          }else{
               // no text entered. Center the hint text.
               yourEditText.setGravity(Gravity.CENTER);  
          }
     }
}

Upvotes: 25

user370305
user370305

Reputation: 109237

By default android EditText has center gravity. Just make it android:gravity="top|left"

Also there is no any special attribute for making hint in center and text in top. Both follow the same gravity attribute.

Android hint is a just for something like a label for where user has to start input the characters.

Upvotes: 20

Related Questions