How to create EditText with cross(x) button at end of it? - android

Is there any widget like EditText which contains a cross button, or is there any property for EditText by which it is created automatically? I want the cross button to delete whatever text written in EditText.

Use the following layout:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:padding="5dp">
<EditText
android:id="#+id/calc_txt_Prise"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:layout_marginTop="20dp"
android:textSize="25dp"
android:textColor="#color/gray"
android:textStyle="bold"
android:hint="#string/calc_txt_Prise"
android:singleLine="true" />
<Button
android:id="#+id/calc_clear_txt_Prise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_gravity="right|center_vertical"
android:background="#drawable/delete" />
</FrameLayout>
You can also use the button's id and perform whatever action you want on its onClickListener method.

2020 solution via Material Design Components for Android:
Add Material Components to your gradle setup:
Look for latest version from here: https://maven.google.com/
implementation 'com.google.android.material:material:1.3.0'
or if you havent updated to using AndroidX libs, you can add it this way:
implementation 'com.android.support:design:28.0.0'
Then
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_text"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
Pay attention to: app:endIconMode="clear_text"
As discussed here Material design docs

If you happen to use DroidParts, I've just added ClearableEditText.
Here's what it looks like with a custom background & clear icon set to abs__ic_clear_holo_light from ActionBarSherlock:

This is a kotlin solution. Put this helper method in some kotlin file-
fun EditText.setupClearButtonWithAction() {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
val clearIcon = if (editable?.isNotEmpty() == true) R.drawable.ic_clear else 0
setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
})
setOnTouchListener(View.OnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_UP) {
if (event.rawX >= (this.right - this.compoundPaddingRight)) {
this.setText("")
return#OnTouchListener true
}
}
return#OnTouchListener false
})
}
And then use it as following in the onCreate method and you should be good to go-
yourEditText.setupClearButtonWithAction()
BTW, you have to add R.drawable.ic_clear or the clear icon at first. This one is from google- https://fonts.google.com/icons?selected=Material%20Icons%20Outlined%3Aclear%3A

Android's support libarary has a SearchView class that does exactly this. (Not derrived from EditText though, so have to use a SearchView.OnQueryTextListener instead of a TextWatcher)
Use in XML like so:
<android.support.v7.widget.SearchView
android:id="#+id/searchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryHint="#string/SearchHint"
app:iconifiedByDefault="false"
app:queryHint="#string/SearchHint" />

Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);
where, x is:

For drawable resource you can use standard android images :
web archive for http://androiddrawables.com/Menu.html
For example :
android:background="#android:drawable/ic_menu_close_clear_cancel"

If you don't want to use custom views or special layouts, you can use 9-patch to make the (X) button .
Example: http://postimg.org/image/tssjmt97p/ (I don't have enough points to post images on StackOverflow)
The intersection of the right and bottom black pixels represent the content area. Anything outside of that area is padding. So to detect that the user clicked on the x you can set a OnTouchListener like so:
editText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP){
if (motionEvent.getX()>(view.getWidth()-view.getPaddingRight())){
((EditText)view).setText("");
}
}
return false;
}
});
According to your needs this solution can work better in some cases. I prefer to keep my xml less complicated. This also helps if you want to have an icon on the left, as you can simply include it in the 9 patch.

Just put close cross like drawableEnd in your EditText:
<EditText
...
android:drawableEnd="#drawable/ic_close"
android:drawablePadding="8dp"
... />
and use extension to handle click (or use OnTouchListener directly on your EditText):
fun EditText.onDrawableEndClick(action: () -> Unit) {
setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_UP) {
v as EditText
val end = if (v.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL)
v.left else v.right
if (event.rawX >= (end - v.compoundPaddingEnd)) {
action.invoke()
return#setOnTouchListener true
}
}
return#setOnTouchListener false
}
}
extension usage:
editText.onDrawableEndClick {
// TODO clear action
etSearch.setText("")
}

Clear text:
"Text field with a clear text trailing icon."
If set, an icon is displayed when text is present and pressing it clears the input text.
...
app:endIconMode="clear_text">
​
...
​
</com.google.android.material.textfield.TextInputLayout>
I leave it here:
material.io
Example

I did the UI part like below:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_marginTop="9dp"
android:padding="5dp">
<EditText
android:id="#+id/etSearchToolbar"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:textSize="13dp"
android:padding="10dp"
android:textColor="#android:color/darker_gray"
android:textStyle="normal"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:background="#drawable/edittext_bg"
android:maxLines="1" />
<ImageView
android:id="#+id/ivClearSearchText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="6dp"
android:src="#drawable/balloon_overlay_close"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
edittext_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/rounded_edittext_focused.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle" >
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#C9C9CE" />
<corners
android:bottomLeftRadius="15dp"
android:bottomRightRadius="15dp"
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
</shape>
balloon_overlay_close.png
Cross/Clear button hide/show:
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(charSequence.length() > 0){
clearSearch.setVisibility(View.VISIBLE);
}else{
clearSearch.setVisibility(View.GONE);
}
}
#Override
public void afterTextChanged(Editable editable) {}
});
Handle search stuffs (i.e when user clicks search from soft key board)
searchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
String contents = searchBox.getText().toString().trim();
if(contents.length() > 0){
//do search
}else{
//if something to do for empty edittext
}
return true;
}
return false;
}
});
Clear/Cross button
clearSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchBox.setText("");
}
});

Here is complete library with the widget:
https://github.com/opprime/EditTextField
To use it you should add the dependency:
compile 'com.optimus:editTextField:0.2.0'
In the layout.xml file you can play with the widget settings:
xmlns:app="http://schemas.android.com/apk/res-auto"
app:clearButtonMode,can has such values:
never
always
whileEditing
unlessEditing
app:clearButtonDrawable
Sample in action:

Use
android:drawableRight="#android:drawable/ic_input_delete"

You can use this snippet with Jaydip answer for more than one button. just call it after getting a reference to the ET and Button Elements. I used vecotr button so you have to change the Button element to ImageButton:
private void setRemovableET(final EditText et, final ImageButton resetIB) {
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus && et.getText().toString().length() > 0)
resetIB.setVisibility(View.VISIBLE);
else
resetIB.setVisibility(View.INVISIBLE);
}
});
resetIB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
et.setText("");
resetIB.setVisibility(View.INVISIBLE);
}
});
et.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0){
resetIB.setVisibility(View.VISIBLE);
}else{
resetIB.setVisibility(View.INVISIBLE);
}
}
});
}

If you are in frame layout or you can create a frame layout I tried another approach....
<TextView
android:id="#+id/inputSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="#drawable/ic_actionbar"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/back_button"/>
<Button
android:id="#+id/clear_text_invisible_button"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right|center_vertical"
android:background="#color/transparent"
android:layout_alignBaseline="#+id/inputSearch"
android:layout_alignBottom="#+id/inputSearch"
android:layout_alignRight="#+id/inputSearch"
android:layout_alignEnd="#+id/inputSearch"
android:layout_marginRight="13dp"
/>
This is an edit text where I put a cross icon as a right drawable and than UPON it I put a transparent button which clears text.

<EditText
android:id="#+id/idSearchEditText"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_40dp"
android:drawableStart="#android:drawable/ic_menu_search"
android:drawablePadding="8dp"
android:ellipsize="start"
android:gravity="center_vertical"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:paddingStart="16dp"
android:paddingEnd="8dp"
/>
EditText mSearchEditText = findViewById(R.id.idSearchEditText);
mSearchEditText.addTextChangedListener(this);
mSearchEditText.setOnTouchListener(this);
#Override
public void afterTextChanged(Editable aEditable) {
int clearIcon = android.R.drawable.ic_notification_clear_all;
int searchIcon = android.R.drawable.ic_menu_search;
if (aEditable == null || TextUtils.isEmpty(aEditable.toString())) {
clearIcon = 0;
searchIcon = android.R.drawable.ic_menu_search;
} else {
clearIcon = android.R.drawable.ic_notification_clear_all;
searchIcon = 0;
}
Drawable leftDrawable = null;
if (searchIcon != 0) {
leftDrawable = getResources().getDrawable(searchIcon);
}
Drawable rightDrawable = null;
if (clearIcon != 0) {
rightDrawable = getResources().getDrawable(clearIcon);
}
mSearchEditText.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, rightDrawable, null);
}
#Override
public boolean onTouch(View aView, MotionEvent aEvent) {
if (aEvent.getAction() == MotionEvent.ACTION_UP){
if (aEvent.getX() > ( mSearchEditText.getWidth() -
mSearchEditText.getCompoundPaddingEnd())){
mSearchEditText.setText("");
}
}
return false;
}

Here is the simple complete solution in kotlin.
This whole layout will be your search bar
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_margin="10dp"
android:background="#drawable/your_desired_drawable">
<EditText
android:id="#+id/search_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_toStartOf="#id/clear_btn"
android:background="#null"
android:hint="search..."
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingStart="15dp"
android:paddingEnd="10dp" />
<ImageView
android:id="#+id/clear_btn"
android:layout_width="20dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_marginEnd="15dp"
android:visibility="gone"
android:src="#drawable/ic_baseline_clear_24"/>
</RelativeLayout>
Now this is the functionality of clear button, paste this code in onCreate method.
search_et.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s:CharSequence, start:Int, count:Int, after:Int) {
}
override fun onTextChanged(s:CharSequence, start:Int, before:Int, count:Int) {
}
override fun afterTextChanged(s: Editable) {
if (s.isNotEmpty()){
clear_btn.visibility = VISIBLE
clear_btn.setOnClickListener {
search_et.text.clear()
}
}else{
clear_btn.visibility = GONE
}
}
})

Related

Edit text Password Toggle Android

I am trying to show user the typed password in edit text whose input type is text Password.
I implemented gesturelistener over the toggle icon like this-
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (view.getId())
{
case R.id.ivPasswordToggle:
switch ( motionEvent.getAction() ) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getContext(),"show",Toast.LENGTH_SHORT).show();
etPassword.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
break;
case MotionEvent.ACTION_UP:
etPassword.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT);
Toast.makeText(getContext(),"hide",Toast.LENGTH_SHORT).show();
break;
}
break;
}
return true;
}
i dont know what is wrong, any help will be appreciated.
(updated for AndroidX)
Since the Support Library v24.2.0. you can achivie this very easy
What you need to do is just:
Add the design library to your dependecies
dependencies {
implementation "com.google.android.material:material:1.2.1"
}
Use TextInputEditText in conjunction with TextInputLayout
<com.google.android.material.textfield.TextInputLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/etPasswordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="#+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/password_hint"
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
passwordToggleEnabled attribute will make the password toggle appear
In your root layout don't forget to add xmlns:app="http://schemas.android.com/apk/res-auto"
You can customize your password toggle by using:
app:passwordToggleDrawable - Drawable to use as the password input visibility toggle icon.
app:passwordToggleTint - Icon to use for the password input visibility toggle.
app:passwordToggleTintMode - Blending mode used to apply the background tint.
More details in TextInputLayout documentation.
Please try this code.
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (view.getId())
{
case R.id.ivPasswordToggle:
switch ( motionEvent.getAction() ) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getContext(),"show",Toast.LENGTH_SHORT).show();
etPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
break;
case MotionEvent.ACTION_UP:
etPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
Toast.makeText(getContext(),"hide",Toast.LENGTH_SHORT).show();
break;
}
break;
}
return true;
}
I hope it will work, thanks.
If you don't want any extra bool or dependencies, then
<EditText
android:id="#+id/et_input_pass"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="3dp"
android:layout_marginStart="56dp"
android:layout_marginEnd="56dp"
android:hint="Password"
android:inputType="textPassword"
android:singleLine="true"
android:textSize="13sp"
android:background="#color/transparent"
android:theme="#style/MyEditText" />
and
password_toggle_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (et_input_pass.getTransformationMethod().getClass().getSimpleName() .equals("PasswordTransformationMethod")) {
et_input_pass.setTransformationMethod(new SingleLineTransformationMethod());
}
else {
et_input_pass.setTransformationMethod(new PasswordTransformationMethod());
}
et_input_pass.setSelection(et_input_pass.getText().length());
}
});
that's it!
Try the following method. Here, we are setting a compound drawable which when clicked will show or hide the password:
private boolean passwordShown = false;
private void addPasswordViewToggle() {
getPasswordEditText().setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_RIGHT = 2; //index
if (event.getAction() == MotionEvent.ACTION_UP) {
if (event.getRawX() >= (getPasswordEditText().getRight() - getPasswordEditText().getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
if (passwordShown) {
passwordShown = false;
// 129 is obtained by bitwise ORing InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD
getPasswordEditText().setInputType(129);
// Need to call following as the font is changed to mono-space by default for password fields
getPasswordEditText().setTypeface(Typeface.SANS_SERIF);
getPasswordEditText().setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.locked_icon, 0); // This is lock icon
} else {
passwordShown = true;
getPasswordEditText().setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
getPasswordEditText().setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.unlocked_icon, 0); // Unlock icon
}
return true;
}
}
return false;
}
});
}
fragmentLoginBinding.imageViewEye.setOnClickListener(v -> {
if (!isPasswordVisible) {
fragmentLoginBinding.editTextPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
fragmentLoginBinding.imageViewEye.setImageDrawable(getResources().getDrawable(R.mipmap.feather_eye_crossed));
isPasswordVisible = true;
} else {
fragmentLoginBinding.editTextPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
fragmentLoginBinding.imageViewEye.setImageDrawable(getResources().getDrawable(R.mipmap.feather_eye));
isPasswordVisible = false;
}
});
app:passwordToggleEnabled="true"
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter Password"
android:inputType="textPassword"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
If you want to use an EditText or AppCompatEditText you can implement that desired output by;
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layout_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/spinner_role"
>
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/edit_text_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:autofillHints="#string/password"
android:hint="#string/password"
android:inputType="textPassword"
android:textSize="16sp"
app:backgroundTint="#59A6B6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/button_password_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:src="#drawable/ic_visibility_off"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/register_user_password_et" />
</androidx.constraintlayout.widget.ConstraintLayout>
In your .kt file;
if (registerUserBinding.editTextPassword.transformationMethod.equals(
PasswordTransformationMethod.getInstance()
)
) {
registerUserBinding.registerUserPasswordEt.transformationMethod =
HideReturnsTransformationMethod.getInstance()
registerUserBinding.buttonPasswordToggle.setImageDrawable(
ContextCompat.getDrawable(
registerUserBinding.registerUserPasswordEt.context,
R.drawable.ic_visibility
)
)
} else {
registerUserBinding.editTextPassword.transformationMethod =
PasswordTransformationMethod.getInstance()
registerUserBinding.buttonPasswordToggle.setImageDrawable(
ContextCompat.getDrawable(
registerUserBinding.registerUserPasswordEt.context,
R.drawable.ic_visibility_off
)
)
}
Implement the TextInput like below. The main attribute that gives that feature is app:passwordToggleEnabled="true"
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/resetpasswordactivity_textinputlayout_newpassword"
android:layout_width="0dp"
android:layout_height="60dp"
app:passwordToggleEnabled="true"
android:theme="#style/loginActivityHintStyle"
app:layout_constraintBottom_toTopOf="#+id/resetpasswordactivity_textinputlayout_newconfirmpassword"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/resetpasswordactivity_textinputlayout_resetcode"
app:layout_constraintVertical_bias="0.15">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/resetpasswordactivity_textinputedittext_newpassword"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="Password"
android:inputType="textPassword"
android:labelFor="#id/resetpasswordactivity_textinputedittext_newpassword"
android:maxLength="100"
android:textColor="#drawable/black_inputtext_color"
/>
</com.google.android.material.textfield.TextInputLayout>
This is a little addition to the accepted answer for those, who wondering who to implement custom drawable for toggle
In your resources:
drawable/password_toggle.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:state_checked="true"
android:drawable="#drawable/eye"
app:tint="#color/black_600_8a"/>
<item
android:drawable="#drawable/eye_closed"
app:tint="#color/black_600_8a" />
</selector>
state_checked is the state when password is visible
Note: use app:tint in the drawable and not android:endIconTint in the layout to change the colour of your toggle, as the latter won't work properly with selector
In your layout xml
<com.google.android.material.textfield.TextInputLayout
...
app:endIconMode="password_toggle"
app:endIconDrawable="#drawable/password_toggle">
<com.google.android.material.textfield.TextInputEditText
...
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
Hope this will help someone as much as it helped me!

Hint Alignment to the right of password EditText

I'm working on and activity with arabic language. I want the hint of the username and password to start from the right and I have no problem f typing started from the left but in my UI I want the hint to be of the right side. But when I'm adding the inputType for the EditText the hint moves to the left.I tried solving it programmatically but it didn't work.
Java
EditText password = (EditText) findViewById(R.id.input_password);
password.setTypeface(Typeface.DEFAULT);
XML
<EditText
android:id="#+id/input_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="كلمة المرور"
android:textColorHint="#FFFFFF"
android:inputType="textPassword"
android:background="#null"
android:textColor="#FFFFFF"
android:textSize="20dp"/>
This is a bug in the Android Framework, for EditText fields in Android 4.4+ : https://issuetracker.google.com/issues/37082815 or https://code.google.com/p/android/issues/detail?id=201471. As of July 2016, it is currently unsolved.
However there is a way to workaround it:
To make the hint display properly on the right (in right-to-left/RTL mode), you must remove the InputType property textPassword (InputType.TYPE_TEXT_VARIATION_PASSWORD), when there is no text entered.
To retain the password entry field behaviour of showing dots to conceal typed text, you must dynamically enable InputType.TYPE_TEXT_VARIATION_PASSWORD, when the first character is entered in. And it must be reset when all characters are deleted.
To prevent the UI glitch of Latin character input (LTR text like "abc123") jumping to the left or disappearing altogether, you must explicitly set textDirection to RTL.
Here are the details:
Pre-requisite for your AndroidManifest.xml:
<application
...
android:supportsRtl="true"
... >
</application>
Your XML Layout contains:
<EditText
android:id="#+id/password"
android:inputType="textPassword"
android:hint="סיסמא"
... />
Java code with workaround bug fix:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.login_fragment_layout, container, false);
final EditText password = (EditText) view.findViewById(R.id.password);
// Workaround https://issuetracker.google.com/issues/37082815 for Android 4.4+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && isRTL(getActivity())) {
// Force a right-aligned text entry, otherwise latin character input,
// like "abc123", will jump to the left and may even disappear!
password.setTextDirection(View.TEXT_DIRECTION_RTL);
// Make the "Enter password" hint display on the right hand side
password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
password.addTextChangedListener(new TextWatcher() {
boolean inputTypeChanged;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {
// Workaround https://code.google.com/p/android/issues/detail?id=201471 for Android 4.4+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && isRTL(getActivity())) {
if (s.length() > 0) {
if (!inputTypeChanged) {
// When a character is typed, dynamically change the EditText's
// InputType to PASSWORD, to show the dots and conceal the typed characters.
password.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD |
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
// Move the cursor to the correct place (after the typed character)
password.setSelection(s.length());
inputTypeChanged = true;
}
} else {
// Reset EditText: Make the "Enter password" hint display on the right
password.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
inputTypeChanged = false;
}
}
}
});
return view;
}
public static boolean isRTL(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
// Another way:
// Define a boolean resource as "true" in res/values-ldrtl
// and "false" in res/values
// return context.getResources().getBoolean(R.bool.is_right_to_left);
} else {
return false;
}
}
It should work like this:
Use Gravity Attribute to Adjust the Hint for EditText
<EditText
android:id="#+id/input_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="كلمة المرور"
android:textColorHint="#FFFFFF"
android:gravity="right"
android:inputType="textPassword"
android:background="#null"
android:textColor="#FFFFFF"
android:textSize="20dp"/>
This one works fine for me
android:textAlignment="viewStart"
The hint direction will be at the correct side
add gravity right try this way
<EditText
android:id="#+id/input_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="كلمة المرور"
android:textColorHint="#FFFFFF"
android:inputType="textPassword"
android:background="#null"
android:textColor="#FFFFFF"
android:textSize="20dp"
android:gravity="right"/>
if your API level 17 and higher you can use
android:textDirection="anyRtl"
For AppCompatEditText edit text gravity start worked for me
<androidx.appcompat.widget.AppCompatEditText
......
android:hint="كلمه السر"
android:inputType="textPassword"
android:gravity="start"
.............../>
This will work only above api 16
you can also try, Where you must have stored your current language I used this library com.akexorcist:localizationactivity
if(currentLanguage.country.toLowerCase() == "arabic"){
etPassword.gravity = GravityCompat.END
}else{
etPassword.gravity = GravityCompat.START
}
Use 'gravity' attribute:
<EditText
android:id="#+id/input_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="كلمة المرور"
android:textColorHint="#FFFFFF"
android:gravity="right"
android:inputType="textPassword"
android:background="#null"
android:textColor="#FFFFFF"
android:textSize="20dp"/>
I think you can fix it by adding \u202B to the Hebrew/Arabic (or any other RTL language) text .
Example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText android:hint="Enter a number..." android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:inputType="number"/>
<EditText android:hint="\u202Bהכנס מספר..." android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:inputType="number"/>
</LinearLayout>
Sadly it seems it doesn't get shown on the layout preview, but it worked for me on a real device. Wrote about it here
Here my solution (workaround) for editText with type = password. Work on Android 5, Android 6.
edittext_password = (EditText) rootView.findViewById(R.id.edittext_password);
if (RTLUtils.isLeftToRightLanguage()) {
edittext_password.setGravity(Gravity.START);
} else {
// Force a right-aligned text entry, otherwise latin character input,
// like "abc123", will jump to the left and may even disappear!
edittext_password.setTextDirection(View.TEXT_DIRECTION_RTL);
// Make the hint display on the right hand side
edittext_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
edittext_password.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
isLeftToRight = RTLUtils.isLeftToRightLanguage(charSequence.toString());
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.length() > 0) {
isLeftToRight = RTLUtils.isLeftToRightLanguage(editable.toString());
if (isLeftToRight) {
edittext_password.setGravity(Gravity.START);
edittext_password.setTextDirection(View.TEXT_DIRECTION_LTR);
edittext_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
// Move the cursor to the correct place (after the typed character)
edittext_password.setSelection(editable.length());
} else {
//edittext_password.setGravity(Gravity.END);
edittext_password.setTextDirection(View.TEXT_DIRECTION_RTL);
// When a character is typed, dynamically change the EditText's
// InputType to PASSWORD, to show the dots and conceal the typed characters.
edittext_password.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD |
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
// Move the cursor to the correct place (after the typed character)
edittext_password.setSelection(editable.length());
}
} else { // empty text
if (!RTLUtils.isLeftToRightLanguage()) {
// Must be in this order (first setInputType then setTextDirection)
edittext_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
edittext_password.setTextDirection(View.TEXT_DIRECTION_RTL);
}
}
}
});
public static boolean isLeftToRightLanguage() {
Bidi bidi = new Bidi(Locale.getDefault().getDisplayLanguage(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
if (bidi.isLeftToRight()) {
return true;
} else {
return false;
}
}
public static boolean isLeftToRightLanguage(String text) {
Bidi bidi = new Bidi(text, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
if (bidi.isLeftToRight()) {
return true;
} else {
return false;
}
}
And here result: (Arabic soft keyboard)
and English soft keyboard:

Implementing SearchView as per the material design guidelines

I have been looking for ways to implement a searchview in the activity toolbar (actionbar) as per the material design guidelines.
On clicking on the search icon, the entire toolbar animates to have only the search EditText with white background with suggestions appearing in the main view instead of a drop down.
Here is a screenshot from the guidelines:
Here is a gif from the Gmail Inbox implementation:
I have been looking for code examples and tutorials but so far I have been unsuccesful. How do I go about doing this?
I tried several material SearchView libraries, but none of them worked good as the one from the support library, so I decided to redesign it, after a lot of work, I am pleased with the result:
Here is how you can do it:
1) Add SearchView item to your menu
<item
android:id="#+id/m_search"
android:icon="#drawable/ic_action_search"
android:title="#string/search_title"
app:actionLayout="#layout/search_view_layout"
app:showAsAction="ifRoom|collapseActionView" />
Notice that I'm declaring actionLayout instead of actionViewClass, I figured that this is the only way to set SearchView theme separately from Toolbar theme.
search_view_layout.xml:
<android.support.v7.widget.SearchView
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/SearchViewTheme" />
2) Add the custom SearchView theme to your styles, declare SearchView theme in your Toolbar theme as well:
<style name="SearchViewTheme" parent="Widget.AppCompat.SearchView.ActionBar">
<item name="layout">#layout/toolbar_search_view</item>
<item name="commitIcon">#drawable/ic_search_commit</item>
<item name="colorControlNormal">#color/material_light_active_icon</item>
<item name="colorControlHighlight">#color/material_ripple_light</item>
<item name="autoCompleteTextViewStyle">#style/AutoCompleteTextViewStyle</item>
<item name="suggestionRowLayout">#layout/search_view_suggestion_row</item>
<item name="android:maxWidth">9999dp</item>
</style>
<style name="AutoCompleteTextViewStyle" parent="Widget.AppCompat.Light.AutoCompleteTextView">
<item name="android:popupBackground">#drawable/search_suggestions_bg</item>
<item name="android:popupElevation">0dp</item>
</style>
<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="searchViewStyle">#style/SearchViewTheme</item>
</style>
toolbar_search_view.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingEnd="8dp">
<!-- This is actually used for the badge icon *or* the badge label (or neither) -->
<TextView
android:id="#+id/search_badge"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="2dp"
android:drawablePadding="0dp"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorPrimary"
android:visibility="gone" />
<ImageView
android:id="#+id/search_button"
style="?attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:contentDescription="#string/abc_searchview_description_search"
android:focusable="true" />
<LinearLayout
android:id="#+id/search_edit_frame"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layoutDirection="locale"
android:orientation="horizontal">
<ImageView
android:id="#+id/search_mag_icon"
style="#style/RtlOverlay.Widget.AppCompat.SearchView.MagIcon"
android:layout_width="#dimen/abc_dropdownitem_icon_width"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"
android:visibility="gone" />
<!-- Inner layout contains the app icon, button(s) and EditText -->
<LinearLayout
android:id="#+id/search_plate"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="horizontal">
<view
android:id="#+id/search_src_text"
class="android.support.v7.widget.SearchView$SearchAutoComplete"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginEnd="#dimen/item_list_horizontal_margin"
android:layout_marginStart="#dimen/item_list_horizontal_margin"
android:layout_weight="1"
android:background="#null"
android:dropDownAnchor="#id/anchor_dropdown"
android:dropDownHeight="wrap_content"
android:dropDownHorizontalOffset="0dp"
android:dropDownVerticalOffset="0dp"
android:ellipsize="end"
android:imeOptions="actionSearch"
android:inputType="text|textAutoComplete|textNoSuggestions"
android:maxLines="1"
android:paddingEnd="8dp"
android:textColor="#android:color/black"
android:textColorHint="#color/material_light_hint_text"
android:textSize="20sp" />
<ImageView
android:id="#+id/search_close_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="#string/abc_searchview_description_clear"
android:focusable="true"
android:paddingEnd="8dp"
android:paddingStart="8dp" />
</LinearLayout>
<LinearLayout
android:id="#+id/submit_area"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/search_go_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="#string/abc_searchview_description_submit"
android:focusable="true"
android:paddingEnd="8dp"
android:paddingStart="8dp"
android:visibility="gone" />
<ImageView
android:id="#+id/search_voice_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="#string/abc_searchview_description_voice"
android:focusable="true"
android:paddingEnd="8dp"
android:paddingStart="8dp"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
Notice that I added anchor dropdown view under the Toolbar view, so suggestions will get full screen width.
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:collapseIcon="#drawable/ic_search_collapse"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:theme="#style/ToolbarTheme" />
<View
android:id="#+id/anchor_dropdown"
android:layout_width="match_parent"
android:layout_height="0dp" />
</android.support.design.widget.AppBarLayout>
search_view_suggestion_row.xml:
(change suggestion_divider visibility if you want divider between suggestions):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="58dp"
android:theme="#style/Theme.AppCompat.DayNight">
<!-- Icons come first in the layout, since their placement doesn't depend on
the placement of the text views. -->
<ImageView
android:id="#android:id/icon1"
style="#style/RtlOverlay.Widget.AppCompat.Search.DropDown.Icon1"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:scaleType="centerInside"
android:visibility="invisible" />
<ImageView
android:id="#+id/edit_query"
style="#style/RtlOverlay.Widget.AppCompat.Search.DropDown.Query"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:background="?attr/selectableItemBackground"
android:scaleType="centerInside"
android:visibility="gone" />
<ImageView
android:id="#id/android:icon2"
style="#style/RtlOverlay.Widget.AppCompat.Search.DropDown.Icon2"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:scaleType="centerInside"
android:visibility="gone" />
<!-- The subtitle comes before the title, since the height of the title depends on whether the
subtitle is visible or gone. -->
<TextView
android:id="#android:id/text2"
style="?android:attr/dropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="29dp"
android:layout_alignParentBottom="true"
android:layout_alignWithParentIfMissing="true"
android:gravity="top"
android:maxLines="1"
android:paddingBottom="4dp"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
android:visibility="gone" />
<!-- The title is placed above the subtitle, if there is one. If there is no
subtitle, it fills the parent. -->
<TextView
android:id="#android:id/text1"
style="?android:attr/dropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#android:id/text2"
android:layout_centerVertical="true"
android:ellipsize="end"
android:maxLines="1"
android:scrollHorizontally="false"
android:textColor="?android:textColorPrimary"
android:textSize="16sp" />
<View
android:id="#+id/suggestion_divider"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_alignParentBottom="true"
android:layout_alignStart="#android:id/text1"
android:layout_marginStart="8dp"
android:background="#color/divider_color"
android:visibility="gone" />
The suggestions background and the commit icon are custom made, the rest of the icons I used can be found at: https://material.io/icons/
ic_search_commit.xml:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#color/active_icon_color"
android:pathData="m18.364,16.95l-8.605,-8.605l7.905,-0l-0.007,-2.001l-11.314,0l0,11.314l1.994,-0l0.007,-7.898l8.605,8.605l1.414,-1.414z" />
search_suggestions_bg.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<padding android:top="0.5dp" />
<stroke
android:width="0.5dp"
android:color="#color/divider_color" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/cards_and_dialogs_color" />
</shape>
</item>
</layer-list>
Add following values to your colors.xml (add values-night only if you are using DayNight theme):
values/colors.xml
<color name="material_light_primary_text">#DE000000</color>
<color name="material_light_hint_text">#61000000</color>
<color name="material_light_active_icon">#8A000000</color>
<color name="material_ripple_light">#1F000000</color>
<color name="divider_color">#1F000000</color>
<color name="active_icon_color">#8A000000</color>
<color name="cards_and_dialogs_color">#android:color/white</color>
<color name="quantum_grey_600">#757575</color>
values-night/colors.xml:
<color name="divider_color">#1FFFFFFF</color>
<color name="active_icon_color">#android:color/white</color>
<color name="cards_and_dialogs_color">#424242</color>
3) Last part, make the magic happen in code:
Setup and initialize SearchView in your desired activity
private MenuItem mSearchItem;
private Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
mSearchItem = menu.findItem(R.id.m_search);
MenuItemCompat.setOnActionExpandListener(mSearchItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Called when SearchView is collapsing
if (mSearchItem.isActionViewExpanded()) {
animateSearchToolbar(1, false, false);
}
return true;
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Called when SearchView is expanding
animateSearchToolbar(1, true, true);
return true;
}
});
return true;
}
public void animateSearchToolbar(int numberOfMenuIcon, boolean containsOverflow, boolean show) {
mToolbar.setBackgroundColor(ContextCompat.getColor(this, android.R.color.white));
mDrawerLayout.setStatusBarBackgroundColor(ContextCompat.getColor(this, R.color.quantum_grey_600));
if (show) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int width = mToolbar.getWidth() -
(containsOverflow ? getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_overflow_material) : 0) -
((getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_material) * numberOfMenuIcon) / 2);
Animator createCircularReveal = ViewAnimationUtils.createCircularReveal(mToolbar,
isRtl(getResources()) ? mToolbar.getWidth() - width : width, mToolbar.getHeight() / 2, 0.0f, (float) width);
createCircularReveal.setDuration(250);
createCircularReveal.start();
} else {
TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f, (float) (-mToolbar.getHeight()), 0.0f);
translateAnimation.setDuration(220);
mToolbar.clearAnimation();
mToolbar.startAnimation(translateAnimation);
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int width = mToolbar.getWidth() -
(containsOverflow ? getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_overflow_material) : 0) -
((getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_material) * numberOfMenuIcon) / 2);
Animator createCircularReveal = ViewAnimationUtils.createCircularReveal(mToolbar,
isRtl(getResources()) ? mToolbar.getWidth() - width : width, mToolbar.getHeight() / 2, (float) width, 0.0f);
createCircularReveal.setDuration(250);
createCircularReveal.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mToolbar.setBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimary));
mDrawerLayout.setStatusBarBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimaryDark));
}
});
createCircularReveal.start();
} else {
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
Animation translateAnimation = new TranslateAnimation(0.0f, 0.0f, 0.0f, (float) (-mToolbar.getHeight()));
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(translateAnimation);
animationSet.setDuration(220);
animationSet.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
mToolbar.setBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimary));
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
mToolbar.startAnimation(animationSet);
}
mDrawerLayout.setStatusBarBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimaryDark));
}
}
private boolean isRtl(Resources resources) {
return resources.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}
private static int getThemeColor(Context context, int id) {
Resources.Theme theme = context.getTheme();
TypedArray a = theme.obtainStyledAttributes(new int[]{id});
int result = a.getColor(0, 0);
a.recycle();
return result;
}
Few things to notice about the code:
1) The animation will adjust it's start point based on your set of number of menu items and if the toolbar has overflow icon, it will detect if layout is LTR or RTL automatically.
2) I'm using navigation drawer activity, so I set StatusBar color to mDrawerLayout, if you are using regular activity, you can set StatusBar color this way:
getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.quantum_grey_600));
3) The circular reveal animation will only work on KitKat and above.
It is actually quite easy to do this, if you are using android.support.v7 library.
Step - 1
Declare a menu item
<item android:id="#+id/action_search"
android:title="Search"
android:icon="#drawable/abc_ic_search_api_mtrl_alpha"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
Step - 2
Extend AppCompatActivity and in the onCreateOptionsMenu setup the SearchView.
import android.support.v7.widget.SearchView;
public class YourActivity extends AppCompatActivity {
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_home, menu);
// Retrieve the SearchView and plug it into SearchManager
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return true;
}
...
}
The idea is very simple - you have to write your own AutoCompleteTextView using EditText, TextWatcher and RecyclerView with Filterable adapter.
EditText gives you a text field with ability to input characters
TextWatcher allows you to watch for text changes
RecyclerView can be placed anywhere, so you can show the search results just like on your screenshot
Filterable adapter helps to present data filtered with the entered text
So:
make a layout with EditText on the top, with RecyclerView filling the remaining space. Add the icon, shadow, etc.
add a TextWatcher and update the adapter on each text change
If you'd like to see my solution in action, check out my project on github:
https://github.com/ZieIony/Carbon
The Auto complete demo can be sound in the sample app in 'Demos' section.
Taking a hint from #Zielony's answer I did the following:
1) Instead if using an ActionBar or ToolBar I built my own layout (basically a RelativeLayout with burger menu, search and other menu buttons and a EditText for search)
2) Used a theme without an ActionBar, placed my custom layout at the top of the activity so that it appeared like an ActionBar.
3) In the search button's OnClickListener I do 2 things:
Hide the menu buttons and show the 'search' EditText.
Add a fragment to display search suggestions and search
Show the soft keyboard input
3) Added OnClickListeners for the other menu buttons.
4) Added a TextWatcher on the 'search' EditText to display search hints and results from the server.
This is how it appears now:
I think I've figured it out.
I'm now using just an EditText inside of the Toolbar.
I now have this:
First inside onCreate() of my activity I added the EditText with an image view on the right hand side to the Toolbar like this:
// Setup search container view
searchContainer = new LinearLayout(this);
Toolbar.LayoutParams containerParams = new Toolbar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
containerParams.gravity = Gravity.CENTER_VERTICAL;
searchContainer.setLayoutParams(containerParams);
// Setup search view
toolbarSearchView = new EditText(this);
// Set width / height / gravity
int[] textSizeAttr = new int[]{android.R.attr.actionBarSize};
int indexOfAttrTextSize = 0;
TypedArray a = obtainStyledAttributes(new TypedValue().data, textSizeAttr);
int actionBarHeight = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
a.recycle();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, actionBarHeight);
params.gravity = Gravity.CENTER_VERTICAL;
params.weight = 1;
toolbarSearchView.setLayoutParams(params);
// Setup display
toolbarSearchView.setBackgroundColor(Color.TRANSPARENT);
toolbarSearchView.setPadding(2, 0, 0, 0);
toolbarSearchView.setTextColor(Color.WHITE);
toolbarSearchView.setGravity(Gravity.CENTER_VERTICAL);
toolbarSearchView.setSingleLine(true);
toolbarSearchView.setImeActionLabel("Search", EditorInfo.IME_ACTION_UNSPECIFIED);
toolbarSearchView.setHint("Search");
toolbarSearchView.setHintTextColor(Color.parseColor("#b3ffffff"));
try {
// Set cursor colour to white
// http://stackoverflow.com/a/26544231/1692770
// https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(toolbarSearchView, R.drawable.edittext_whitecursor);
} catch (Exception ignored) {
}
// Search text changed listener
toolbarSearchView.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) {
Fragment mainFragment = getFragmentManager().findFragmentById(R.id.container);
if (mainFragment != null && mainFragment instanceof MainListFragment) {
((MainListFragment) mainFragment).search(s.toString());
}
}
#Override
public void afterTextChanged(Editable s) {
// http://stackoverflow.com/a/6438918/1692770
if (s.toString().length() <= 0) {
toolbarSearchView.setHintTextColor(Color.parseColor("#b3ffffff"));
}
}
});
((LinearLayout) searchContainer).addView(toolbarSearchView);
// Setup the clear button
searchClearButton = new ImageView(this);
Resources r = getResources();
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, r.getDisplayMetrics());
LinearLayout.LayoutParams clearParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
clearParams.gravity = Gravity.CENTER;
searchClearButton.setLayoutParams(clearParams);
searchClearButton.setImageResource(R.drawable.ic_close_white_24dp); // TODO: Get this image from here: https://github.com/google/material-design-icons
searchClearButton.setPadding(px, 0, px, 0);
searchClearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toolbarSearchView.setText("");
}
});
((LinearLayout) searchContainer).addView(searchClearButton);
// Add search view to toolbar and hide it
searchContainer.setVisibility(View.GONE);
toolbar.addView(searchContainer);
This worked, but then I came across an issue where onOptionsItemSelected() wasn't being called when I tapped on the home button. So I wasn't able to cancel the search by pressing the home button. I tried a few different ways of registering the click listener on the home button but they didn't work.
Eventually I found out that the ActionBarDrawerToggle I had was interfering with things, so I removed it. This listener then started working:
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// toolbarHomeButtonAnimating is a boolean that is initialized as false. It's used to stop the user pressing the home button while it is animating and breaking things.
if (!toolbarHomeButtonAnimating) {
// Here you'll want to check if you have a search query set, if you don't then hide the search box.
// My main fragment handles this stuff, so I call its methods.
FragmentManager fragmentManager = getFragmentManager();
final Fragment fragment = fragmentManager.findFragmentById(R.id.container);
if (fragment != null && fragment instanceof MainListFragment) {
if (((MainListFragment) fragment).hasSearchQuery() || searchContainer.getVisibility() == View.VISIBLE) {
displaySearchView(false);
return;
}
}
}
if (mDrawerLayout.isDrawerOpen(findViewById(R.id.navigation_drawer)))
mDrawerLayout.closeDrawer(findViewById(R.id.navigation_drawer));
else
mDrawerLayout.openDrawer(findViewById(R.id.navigation_drawer));
}
});
So I can now cancel the search with the home button, but I can't press the back button to cancel it yet. So I added this to onBackPressed():
FragmentManager fragmentManager = getFragmentManager();
final Fragment mainFragment = fragmentManager.findFragmentById(R.id.container);
if (mainFragment != null && mainFragment instanceof MainListFragment) {
if (((MainListFragment) mainFragment).hasSearchQuery() || searchContainer.getVisibility() == View.VISIBLE) {
displaySearchView(false);
return;
}
}
I created this method to toggle visibility of the EditText and menu item:
public void displaySearchView(boolean visible) {
if (visible) {
// Stops user from being able to open drawer while searching
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
// Hide search button, display EditText
menu.findItem(R.id.action_search).setVisible(false);
searchContainer.setVisibility(View.VISIBLE);
// Animate the home icon to the back arrow
toggleActionBarIcon(ActionDrawableState.ARROW, mDrawerToggle, true);
// Shift focus to the search EditText
toolbarSearchView.requestFocus();
// Pop up the soft keyboard
new Handler().postDelayed(new Runnable() {
public void run() {
toolbarSearchView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
toolbarSearchView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
}
}, 200);
} else {
// Allows user to open drawer again
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
// Hide the EditText and put the search button back on the Toolbar.
// This sometimes fails when it isn't postDelayed(), don't know why.
toolbarSearchView.postDelayed(new Runnable() {
#Override
public void run() {
toolbarSearchView.setText("");
searchContainer.setVisibility(View.GONE);
menu.findItem(R.id.action_search).setVisible(true);
}
}, 200);
// Turn the home button back into a drawer icon
toggleActionBarIcon(ActionDrawableState.BURGER, mDrawerToggle, true);
// Hide the keyboard because the search box has been hidden
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(toolbarSearchView.getWindowToken(), 0);
}
}
I needed a way to toggle the home button on the toolbar between the drawer icon and the back button. I eventually found the method below in this SO answer. Though I modified it slightly to made more sense to me:
private enum ActionDrawableState
{
BURGER, ARROW
}
private void toggleActionBarIcon(final ActionDrawableState state, final ActionBarDrawerToggle toggle, boolean animate) {
if (animate) {
float start = state == ActionDrawableState.BURGER ? 1.0f : 0f;
float end = Math.abs(start - 1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end);
offsetAnimator.setDuration(300);
offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float offset = (Float) animation.getAnimatedValue();
toggle.onDrawerSlide(null, offset);
}
});
offsetAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
toolbarHomeButtonAnimating = false;
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
toolbarHomeButtonAnimating = true;
offsetAnimator.start();
}
} else {
if (state == ActionDrawableState.BURGER) {
toggle.onDrawerClosed(null);
} else {
toggle.onDrawerOpened(null);
}
}
}
This works, I've managed to work out a few bugs that I found along the way. I don't think it's 100% but it works well enough for me.
EDIT: If you want to add the search view in XML instead of Java do this:
toolbar.xml:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
contentInsetLeft="72dp"
contentInsetStart="72dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="72dp"
app:contentInsetStart="72dp"
app:popupTheme="#style/ActionBarPopupThemeOverlay"
app:theme="#style/ActionBarThemeOverlay">
<LinearLayout
android:id="#+id/search_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="#+id/search_view"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="#android:color/transparent"
android:gravity="center_vertical"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingLeft="2dp"
android:singleLine="true"
android:textColor="#ffffff"
android:textColorHint="#b3ffffff" />
<ImageView
android:id="#+id/search_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="#drawable/ic_close_white_24dp" />
</LinearLayout>
onCreate() of your Activity:
searchContainer = findViewById(R.id.search_container);
toolbarSearchView = (EditText) findViewById(R.id.search_view);
searchClearButton = (ImageView) findViewById(R.id.search_clear);
// Setup search container view
try {
// Set cursor colour to white
// http://stackoverflow.com/a/26544231/1692770
// https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(toolbarSearchView, R.drawable.edittext_whitecursor);
} catch (Exception ignored) {
}
// Search text changed listener
toolbarSearchView.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) {
Fragment mainFragment = getFragmentManager().findFragmentById(R.id.container);
if (mainFragment != null && mainFragment instanceof MainListFragment) {
((MainListFragment) mainFragment).search(s.toString());
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
// Clear search text when clear button is tapped
searchClearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toolbarSearchView.setText("");
}
});
// Hide the search view
searchContainer.setVisibility(View.GONE);
Here is how I tried to implement it, please check this out.
https://github.com/Shahroz16/material-searchview
You can use AutoCompleteTextView to achieve this, Follow the link below
How to build Gmail like search box in the action bar?

how do i implement an edittext with clear button at the end in android [duplicate]

Is there any widget like EditText which contains a cross button, or is there any property for EditText by which it is created automatically? I want the cross button to delete whatever text written in EditText.
Use the following layout:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:padding="5dp">
<EditText
android:id="#+id/calc_txt_Prise"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:layout_marginTop="20dp"
android:textSize="25dp"
android:textColor="#color/gray"
android:textStyle="bold"
android:hint="#string/calc_txt_Prise"
android:singleLine="true" />
<Button
android:id="#+id/calc_clear_txt_Prise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_gravity="right|center_vertical"
android:background="#drawable/delete" />
</FrameLayout>
You can also use the button's id and perform whatever action you want on its onClickListener method.
2020 solution via Material Design Components for Android:
Add Material Components to your gradle setup:
Look for latest version from here: https://maven.google.com/
implementation 'com.google.android.material:material:1.3.0'
or if you havent updated to using AndroidX libs, you can add it this way:
implementation 'com.android.support:design:28.0.0'
Then
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_text"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
Pay attention to: app:endIconMode="clear_text"
As discussed here Material design docs
If you happen to use DroidParts, I've just added ClearableEditText.
Here's what it looks like with a custom background & clear icon set to abs__ic_clear_holo_light from ActionBarSherlock:
This is a kotlin solution. Put this helper method in some kotlin file-
fun EditText.setupClearButtonWithAction() {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
val clearIcon = if (editable?.isNotEmpty() == true) R.drawable.ic_clear else 0
setCompoundDrawablesWithIntrinsicBounds(0, 0, clearIcon, 0)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
})
setOnTouchListener(View.OnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_UP) {
if (event.rawX >= (this.right - this.compoundPaddingRight)) {
this.setText("")
return#OnTouchListener true
}
}
return#OnTouchListener false
})
}
And then use it as following in the onCreate method and you should be good to go-
yourEditText.setupClearButtonWithAction()
BTW, you have to add R.drawable.ic_clear or the clear icon at first. This one is from google- https://fonts.google.com/icons?selected=Material%20Icons%20Outlined%3Aclear%3A
Android's support libarary has a SearchView class that does exactly this. (Not derrived from EditText though, so have to use a SearchView.OnQueryTextListener instead of a TextWatcher)
Use in XML like so:
<android.support.v7.widget.SearchView
android:id="#+id/searchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryHint="#string/SearchHint"
app:iconifiedByDefault="false"
app:queryHint="#string/SearchHint" />
Drawable x = getResources().getDrawable(R.drawable.x);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
mEditText.setCompoundDrawables(null, null, x, null);
where, x is:
For drawable resource you can use standard android images :
web archive for http://androiddrawables.com/Menu.html
For example :
android:background="#android:drawable/ic_menu_close_clear_cancel"
If you don't want to use custom views or special layouts, you can use 9-patch to make the (X) button .
Example: http://postimg.org/image/tssjmt97p/ (I don't have enough points to post images on StackOverflow)
The intersection of the right and bottom black pixels represent the content area. Anything outside of that area is padding. So to detect that the user clicked on the x you can set a OnTouchListener like so:
editText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP){
if (motionEvent.getX()>(view.getWidth()-view.getPaddingRight())){
((EditText)view).setText("");
}
}
return false;
}
});
According to your needs this solution can work better in some cases. I prefer to keep my xml less complicated. This also helps if you want to have an icon on the left, as you can simply include it in the 9 patch.
Just put close cross like drawableEnd in your EditText:
<EditText
...
android:drawableEnd="#drawable/ic_close"
android:drawablePadding="8dp"
... />
and use extension to handle click (or use OnTouchListener directly on your EditText):
fun EditText.onDrawableEndClick(action: () -> Unit) {
setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_UP) {
v as EditText
val end = if (v.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL)
v.left else v.right
if (event.rawX >= (end - v.compoundPaddingEnd)) {
action.invoke()
return#setOnTouchListener true
}
}
return#setOnTouchListener false
}
}
extension usage:
editText.onDrawableEndClick {
// TODO clear action
etSearch.setText("")
}
Clear text:
"Text field with a clear text trailing icon."
If set, an icon is displayed when text is present and pressing it clears the input text.
...
app:endIconMode="clear_text">
​
...
​
</com.google.android.material.textfield.TextInputLayout>
I leave it here:
material.io
Example
I did the UI part like below:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_marginTop="9dp"
android:padding="5dp">
<EditText
android:id="#+id/etSearchToolbar"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:textSize="13dp"
android:padding="10dp"
android:textColor="#android:color/darker_gray"
android:textStyle="normal"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:background="#drawable/edittext_bg"
android:maxLines="1" />
<ImageView
android:id="#+id/ivClearSearchText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="6dp"
android:src="#drawable/balloon_overlay_close"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
edittext_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/rounded_edittext_focused.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle" >
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#C9C9CE" />
<corners
android:bottomLeftRadius="15dp"
android:bottomRightRadius="15dp"
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
</shape>
balloon_overlay_close.png
Cross/Clear button hide/show:
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(charSequence.length() > 0){
clearSearch.setVisibility(View.VISIBLE);
}else{
clearSearch.setVisibility(View.GONE);
}
}
#Override
public void afterTextChanged(Editable editable) {}
});
Handle search stuffs (i.e when user clicks search from soft key board)
searchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
String contents = searchBox.getText().toString().trim();
if(contents.length() > 0){
//do search
}else{
//if something to do for empty edittext
}
return true;
}
return false;
}
});
Clear/Cross button
clearSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchBox.setText("");
}
});
Here is complete library with the widget:
https://github.com/opprime/EditTextField
To use it you should add the dependency:
compile 'com.optimus:editTextField:0.2.0'
In the layout.xml file you can play with the widget settings:
xmlns:app="http://schemas.android.com/apk/res-auto"
app:clearButtonMode,can has such values:
never
always
whileEditing
unlessEditing
app:clearButtonDrawable
Sample in action:
Use
android:drawableRight="#android:drawable/ic_input_delete"
You can use this snippet with Jaydip answer for more than one button. just call it after getting a reference to the ET and Button Elements. I used vecotr button so you have to change the Button element to ImageButton:
private void setRemovableET(final EditText et, final ImageButton resetIB) {
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus && et.getText().toString().length() > 0)
resetIB.setVisibility(View.VISIBLE);
else
resetIB.setVisibility(View.INVISIBLE);
}
});
resetIB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
et.setText("");
resetIB.setVisibility(View.INVISIBLE);
}
});
et.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0){
resetIB.setVisibility(View.VISIBLE);
}else{
resetIB.setVisibility(View.INVISIBLE);
}
}
});
}
If you are in frame layout or you can create a frame layout I tried another approach....
<TextView
android:id="#+id/inputSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="#drawable/ic_actionbar"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/back_button"/>
<Button
android:id="#+id/clear_text_invisible_button"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right|center_vertical"
android:background="#color/transparent"
android:layout_alignBaseline="#+id/inputSearch"
android:layout_alignBottom="#+id/inputSearch"
android:layout_alignRight="#+id/inputSearch"
android:layout_alignEnd="#+id/inputSearch"
android:layout_marginRight="13dp"
/>
This is an edit text where I put a cross icon as a right drawable and than UPON it I put a transparent button which clears text.
<EditText
android:id="#+id/idSearchEditText"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_40dp"
android:drawableStart="#android:drawable/ic_menu_search"
android:drawablePadding="8dp"
android:ellipsize="start"
android:gravity="center_vertical"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:paddingStart="16dp"
android:paddingEnd="8dp"
/>
EditText mSearchEditText = findViewById(R.id.idSearchEditText);
mSearchEditText.addTextChangedListener(this);
mSearchEditText.setOnTouchListener(this);
#Override
public void afterTextChanged(Editable aEditable) {
int clearIcon = android.R.drawable.ic_notification_clear_all;
int searchIcon = android.R.drawable.ic_menu_search;
if (aEditable == null || TextUtils.isEmpty(aEditable.toString())) {
clearIcon = 0;
searchIcon = android.R.drawable.ic_menu_search;
} else {
clearIcon = android.R.drawable.ic_notification_clear_all;
searchIcon = 0;
}
Drawable leftDrawable = null;
if (searchIcon != 0) {
leftDrawable = getResources().getDrawable(searchIcon);
}
Drawable rightDrawable = null;
if (clearIcon != 0) {
rightDrawable = getResources().getDrawable(clearIcon);
}
mSearchEditText.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, rightDrawable, null);
}
#Override
public boolean onTouch(View aView, MotionEvent aEvent) {
if (aEvent.getAction() == MotionEvent.ACTION_UP){
if (aEvent.getX() > ( mSearchEditText.getWidth() -
mSearchEditText.getCompoundPaddingEnd())){
mSearchEditText.setText("");
}
}
return false;
}
Here is the simple complete solution in kotlin.
This whole layout will be your search bar
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_margin="10dp"
android:background="#drawable/your_desired_drawable">
<EditText
android:id="#+id/search_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_toStartOf="#id/clear_btn"
android:background="#null"
android:hint="search..."
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingStart="15dp"
android:paddingEnd="10dp" />
<ImageView
android:id="#+id/clear_btn"
android:layout_width="20dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_marginEnd="15dp"
android:visibility="gone"
android:src="#drawable/ic_baseline_clear_24"/>
</RelativeLayout>
Now this is the functionality of clear button, paste this code in onCreate method.
search_et.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s:CharSequence, start:Int, count:Int, after:Int) {
}
override fun onTextChanged(s:CharSequence, start:Int, before:Int, count:Int) {
}
override fun afterTextChanged(s: Editable) {
if (s.isNotEmpty()){
clear_btn.visibility = VISIBLE
clear_btn.setOnClickListener {
search_et.text.clear()
}
}else{
clear_btn.visibility = GONE
}
}
})

How to switch between hide and view password

Is there a clever way to let the user switch between hide and view password in an android EditText?
A number of PC based apps let the user do this.
It is really easy to achieve since the Support Library v24.2.0.
What you need to do is just:
Add the design library to your dependencies
dependencies {
compile "com.android.support:design:24.2.0"
}
Use TextInputEditText in conjunction with TextInputLayout
<android.support.design.widget.TextInputLayout
android:id="#+id/etPasswordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:layout_marginBottom="#dimen/login_spacing_bottom">
<android.support.design.widget.TextInputEditText
android:id="#+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/fragment_login_password_hint"
android:inputType="textPassword"/>
</android.support.design.widget.TextInputLayout>
The passwordToggleEnabled attribute will do the job!
In your root layout don't forget to add xmlns:app="http://schemas.android.com/apk/res-auto"
You can customize your password toggle by using:
app:passwordToggleDrawable - Drawable to use as the password input visibility toggle icon.
app:passwordToggleTint - Icon to use for the password input visibility toggle.
app:passwordToggleTintMode - Blending mode used to apply the background tint.
More details in TextInputLayout documentation.
For AndroidX
Replace android.support.design.widget.TextInputLayout with com.google.android.material.textfield.TextInputLayout
Replace android.support.design.widget.TextInputEditText with com.google.android.material.textfield.TextInputEditText
You can dynamically change the attributes of a TextView. If you would set the XML Atrribute android:password to true the view would show dots if you set it to false the text is shown.
With the method setTransformationMethod you should be able to change this attributes from code. (Disclaimer: I have not tested if the method still works after the view is displayed. If you encounter problems with that leave me a comment for me to know.)
The full sample code would be
yourTextView.setTransformationMethod(new PasswordTransformationMethod());
to hide the password. To show the password you could set one of the existing transformation methods or implement an empty TransformationMethod that does nothing with the input text.
yourTextView.setTransformationMethod(new DoNothingTransformation());
To show the dots instead of the password set the PasswordTransformationMethod:
yourEditText.setTransformationMethod(new PasswordTransformationMethod());
of course you can set this by default in your edittext element in the xml layout with
android:password
To re-show the readable password, just pass null as transformation method:
yourEditText.setTransformationMethod(null);
To show:
editText.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
To hide:
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
After each of these the cursor is reset, so:
editText.setSelection(editText.length());
You can use app:passwordToggleEnabled="true"
here is example given below
<android.support.design.widget.TextInputLayout
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:textColorHint="#color/colorhint"
android:textColor="#color/colortext">
I had the same issue and it is very easy to implement.
All you have to do is wrap your EditText field in a (com.google.android.material.textfield.TextInputLayout) and in that add ( app:passwordToggleEnabled="true" ).
This will show the eye in the EditText field and when you click on it the password will appear and disappear when clicked again.
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColorHint="#B9B8B8"
app:passwordToggleEnabled="true">
<EditText
android:id="#+id/register_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="44dp"
android:backgroundTint="#BEBEBE"
android:hint="Password"
android:inputType="textPassword"
android:padding="16dp"
android:textSize="18sp" />
</com.google.android.material.textfield.TextInputLayout>
Use checkbox and change the input type accordingly.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int start,end;
Log.i("inside checkbox chnge",""+isChecked);
if(!isChecked){
start=passWordEditText.getSelectionStart();
end=passWordEditText.getSelectionEnd();
passWordEditText.setTransformationMethod(new PasswordTransformationMethod());;
passWordEditText.setSelection(start,end);
}else{
start=passWordEditText.getSelectionStart();
end=passWordEditText.getSelectionEnd();
passWordEditText.setTransformationMethod(null);
passWordEditText.setSelection(start,end);
}
}
private boolean isPasswordVisible;
private TextInputEditText firstEditText;
...
firstEditText = findViewById(R.id.et_first);
...
private void togglePassVisability() {
if (isPasswordVisible) {
String pass = firstEditText.getText().toString();
firstEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
firstEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
firstEditText.setText(pass);
firstEditText.setSelection(pass.length());
} else {
String pass = firstEditText.getText().toString();
firstEditText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
firstEditText.setInputType(InputType.TYPE_CLASS_TEXT);
firstEditText.setText(pass);
firstEditText.setSelection(pass.length());
}
isPasswordVisible= !isPasswordVisible;
}
At first this is the screen loaded with an image vector asset visibility
on click it will change to this image visibility off
code for above password switch(xml code)
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/laypass"
android:layout_width="330dp"
android:layout_height="50dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="#+id/editText3"
app:layout_constraintStart_toStartOf="#+id/editText3"
app:layout_constraintTop_toBottomOf="#+id/editText3">
<EditText
android:id="#+id/edit_password"
style="#style/EditTextTheme"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/round"
android:drawableLeft="#drawable/ic_password"
android:drawablePadding="10dp"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:paddingLeft="10dp"
android:paddingRight="15dp"
android:textColor="#color/cyan92a6"
android:textColorHint="#color/cyan92a6"
android:textCursorDrawable="#null"
android:textSize="18sp"
/>
<ImageView
android:id="#+id/show_pass_btn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:alpha=".5"
android:onClick="ShowHidePass"
android:padding="5dp"
android:src="#drawable/ic_visibility"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/laypass"
app:layout_constraintTop_toTopOf="#+id/edit_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
Java code for button operation
public void ShowHidePass(View view) {
if(view.getId()==R.id.show_pass_btn){
if(edit_password.getTransformationMethod().equals(PasswordTransformationMethod.getInstance())){
((ImageView)(view)).setImageResource(R.drawable.ic_visibility_off);
//Show Password
edit_password.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
}
else{
((ImageView)(view)).setImageResource(R.drawable.ic_visibility);
//Hide Password
edit_password.setTransformationMethod(PasswordTransformationMethod.getInstance());
}
}
}
It's work for me.This will help you definitely
showpass.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(!isChecked){
// show password
password_login.setTransformationMethod(PasswordTransformationMethod.getInstance());
Log.i("checker", "true");
}
else{
Log.i("checker", "false");
// hide password
password_login.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
}
}
});
I feel I want answer this question even there some good answers ,
according to documentation TransformationMethod do our mission
TransformationMethod
TextView uses TransformationMethods to do things like replacing the
characters of passwords with dots, or keeping the newline characters
from causing line breaks in single-line text fields.
Notice I use butter knife, but its the same if user check show password
#OnCheckedChanged(R.id.showpass)
public void onChecked(boolean checked){
if(checked){
et_password.setTransformationMethod(null);
}else {
et_password.setTransformationMethod(new PasswordTransformationMethod());
}
// cursor reset his position so we need set position to the end of text
et_password.setSelection(et_password.getText().length());
}
I'm able to add the ShowPassword / HidePassword code with just a few lines, self-contained in a block:
protected void onCreate(Bundle savedInstanceState) {
...
etPassword = (EditText)findViewById(R.id.password);
etPassword.setTransformationMethod(new PasswordTransformationMethod()); // Hide password initially
checkBoxShowPwd = (CheckBox)findViewById(R.id.checkBoxShowPwd);
checkBoxShowPwd.setText(getString(R.string.label_show_password)); // Hide initially, but prompting "Show Password"
checkBoxShowPwd.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
if (isChecked) {
etPassword.setTransformationMethod(null); // Show password when box checked
checkBoxShowPwd.setText(getString(R.string.label_hide_password)); // Prompting "Hide Password"
} else {
etPassword.setTransformationMethod(new PasswordTransformationMethod()); // Hide password when box not checked
checkBoxShowPwd.setText(getString(R.string.label_show_password)); // Prompting "Show Password"
}
}
} );
...
In very simple form:
private fun updatePasswordVisibility(editText: AppCompatEditText) {
if (editText.transformationMethod is PasswordTransformationMethod) {
editText.transformationMethod = null
} else {
editText.transformationMethod = PasswordTransformationMethod()
}
editText.setSelection(editText.length())
}
Hope it helps.
private int passwordNotVisible=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
showPassword = (ImageView) findViewById(R.id.show_password);
showPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText paswword = (EditText) findViewById(R.id.Password);
if (passwordNotVisible == 1) {
paswword.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
passwordNotVisible = 0;
} else {
paswword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordNotVisible = 1;
}
paswword.setSelection(paswword.length());
}
});
}
Try https://github.com/maksim88/PasswordEditText project at github.
You dont even need to change your Java code using it. Just change
EditText
tag to
com.maksim88.passwordedittext.PasswordEditText
in your XML file.
You can SHOW/HIDE password using this below code:
XML CODE:
<EditText
android:id="#+id/etPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="21dp"
android:layout_marginTop="14dp"
android:ems="10"
android:inputType="textPassword" >
<requestFocus />
</EditText>
<CheckBox
android:id="#+id/cbShowPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/etPassword"
android:layout_below="#+id/etPassword"
android:text="#string/show_pwd" />
JAVA CODE:
EditText mEtPwd;
CheckBox mCbShowPwd;
mEtPwd = (EditText) findViewById(R.id.etPassword);
mCbShowPwd = (CheckBox) findViewById(R.id.cbShowPwd);
mCbShowPwd.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// checkbox status is changed from uncheck to checked.
if (!isChecked) {
// show password
mEtPwd.setTransformationMethod(PasswordTransformationMethod.getInstance());
} else {
// hide password
mEtPwd.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
}
}
});
Try this:
First define a flag as global like this:
private boolean isShowPassword = false;
And set listener to handle tap on show and hide password button:
imgPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isShowPassword) {
etPassword.setTransformationMethod(new PasswordTransformationMethod());
imgPassword.setImageDrawable(getResources().getDrawable(R.drawable.ic_eye_hide));
isShowPassword = false;
}else{
etPassword.setTransformationMethod(null);
imgPassword.setImageDrawable(getResources().getDrawable(R.drawable.ic_eye_show));
isShowPassword = true;
}
}
});
show and hide password Edit_Text with check Box
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:inputType="textPassword"
android:id="#+id/edtPass"
android:textSize="20dp"
android:hint="password"
android:padding="20dp"
android:background="#efeaea"
android:layout_width="match_parent"
android:layout_margin="20dp"
android:layout_height="wrap_content" />
<CheckBox
android:background="#ff4"
android:layout_centerInParent="true"
android:textSize="25dp"
android:text="show password"
android:layout_below="#id/edtPass"
android:id="#+id/showPassword"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:gravity="top|right"
android:layout_height="wrap_content" />
</RelativeLayout>
java code
package com.example.root.sql2;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.Toolbar;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
public class password extends AppCompatActivity {
EditText password;
CheckBox show_hide_password;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hide);
findViewById();
show_hide_pass();
}//end onCreate
public void show_hide_pass(){
show_hide_password.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (!b){
// hide password
password.setTransformationMethod(PasswordTransformationMethod.getInstance());
}else{
// show password
password.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
}
}
});
} // end show_hide_pass
public void findViewById(){ // find ids ui and
password = (EditText) findViewById(R.id.edtPass);
show_hide_password = (CheckBox) findViewById(R.id.showPassword);
}//end findViewById
}// end class
Did you try with setTransformationMethod? It's inherited from TextView and want a TransformationMethod as a parameter.
You can find more about TransformationMethods here.
It also has some cool features, like character replacing.
What I did was to
Create an edit text view and a normal text view
Make them overlap with each other by using constraint layout (just like Facebook app login screen)
Attach an onClickListener to the normal text view so that it changes the input type of the edit text view accordingly (Visible / Non-visible)
You may check out this video for a more detailed steps and explanations https://youtu.be/md3eVaRzdIM
Hope it helps :)
Here is my solution without using TextInputEditText and Transformation method.
XML
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
style="#style/FormLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/username" />
<EditText
android:id="#+id/loginUsername"
style="#style/EditTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/ic_person_outline_black_24dp"
android:drawableStart="#drawable/ic_person_outline_black_24dp"
android:inputType="textEmailAddress"
android:textColor="#color/black" />
<TextView
style="#style/FormLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="#string/password" />
<EditText
android:id="#+id/loginPassword"
style="#style/EditTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableEnd="#drawable/ic_visibility_off_black_24dp"
android:drawableLeft="#drawable/ic_lock_outline_black_24dp"
android:drawableRight="#drawable/ic_visibility_off_black_24dp"
android:drawableStart="#drawable/ic_lock_outline_black_24dp"
android:inputType="textPassword"
android:textColor="#color/black" />
</LinearLayout>
Java Code
boolean VISIBLE_PASSWORD = false; //declare as global variable befor onCreate()
loginPassword = (EditText)findViewById(R.id.loginPassword);
loginPassword.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
if (event.getAction() == MotionEvent.ACTION_UP) {
if (event.getRawX() >= (loginPassword.getRight() - loginPassword.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
// your action here
//Helper.toast(LoginActivity.this, "Toggle visibility");
if (VISIBLE_PASSWORD) {
VISIBLE_PASSWORD = false;
loginPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
loginPassword.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_outline_black_24dp, 0, R.drawable.ic_visibility_off_black_24dp, 0);
} else {
VISIBLE_PASSWORD = true;
loginPassword.setInputType(InputType.TYPE_CLASS_TEXT);
loginPassword.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_outline_black_24dp, 0, R.drawable.ic_visibility_black_24dp, 0);
}
return false;
}
}
return false;
}
});
According to this source, if you have migrated your project to AndroidX, then you can replace
compile "com.android.support:design:24.2.0"
with
implementation "com.google.android.material:material:1.0.0"
Then all you have to do is to put the code below to your layout file:
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:hint="#string/hint_text">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
More information about material TextInputLayout can be found here.
To this source, it is recommended to migrate to AndroidX from Android Support Library:
AndroidX is the open-source project that the Android team uses to
develop, test, package, version and release libraries within Jetpack.
AndroidX is a major improvement to the original Android Support
Library. Like the Support Library, AndroidX ships separately from the
Android OS and provides backwards-compatibility across Android
releases. AndroidX fully replaces the Support Library by providing
feature parity and new libraries. In addition AndroidX includes the
following features:
All packages in AndroidX live in a consistent namespace starting with
the string androidx. The Support Library packages have been mapped
into corresponding androidx.* packages. For a full mapping of all the
old classes and build artifacts to the new ones, see the Package
Refactoring page.
Unlike the Support Library, AndroidX packages are separately
maintained and updated. The androidx packages use strict Semantic
Versioning starting with version 1.0.0. You can update AndroidX
libraries in your project independently.
All new Support Library development will occur in the AndroidX
library. This includes maintenance of the original Support Library
artifacts and introduction of new Jetpack components.
A good solution. Set up a button, then use this code:
public void showPassword(View v)
{
TextView showHideBtnText = (TextView) findViewById(R.id.textView1);
if(showHideBtnText.getText().toString().equals("Show Password")){
password.setTransformationMethod(null);
showHideBtnText.setText("Hide");
} else{
password.setTransformationMethod(new PasswordTransformationMethod());
showHideBtnText.setText("Show Password");
}
}
1 - Make a selector file "show_password_selector.xml"
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/pwd_hide"
android:state_selected="true"/>
<item android:drawable="#drawable/pwd_show"
android:state_selected="false" />
</selector>
2 - Aet "show_password_selector" file into imageview.
<ImageView
android:id="#+id/iv_pwd"
android:layout_width="#dimen/_35sdp"
android:layout_height="#dimen/_25sdp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="#dimen/_15sdp"
android:src="#drawable/show_password_selector" />
3 - Put below code in java file.
iv_new_pwd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (iv_new_pwd.isSelected()) {
iv_new_pwd.setSelected(false);
Log.d("mytag", "in case 1");
edt_new_pwd.setInputType(InputType.TYPE_CLASS_TEXT);
} else {
Log.d("mytag", "in case 1");
iv_new_pwd.setSelected(true);
edt_new_pwd.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
}
}
});
You have to ask if the current text is already shown with dots, the function PasswordTransformationMethod.getInstance() allow you to do that.
This is my funtion in kotlin:
fun hideAndShowPassword(editText: EditText, indicator: ImageView) {
if (editText.transformationMethod == PasswordTransformationMethod.getInstance()) {
editText.transformationMethod = HideReturnsTransformationMethod.getInstance()
indicator.setImageDrawable(
ContextCompat.getDrawable(
editText.context,
R.drawable.eye
)
)
indicator.imageTintList =
ContextCompat.getColorStateList(editText.context, R.color.colorTintIcons)
} else {
editText.transformationMethod = PasswordTransformationMethod.getInstance()
indicator.setImageDrawable(
ContextCompat.getDrawable(
editText.context,
R.drawable.eye_off
)
)
indicator.imageTintList =
ContextCompat.getColorStateList(editText.context, R.color.colorTintIcons)
}
editText.setSelection(editText.text.length)
}
It seems that input_layout.isPasswordVisibilityToggleEnabled = true is deprecated. And in my case I did it that way in Kotlin:
input_edit_text.inputType = TYPE_CLASS_TEXT or TYPE_TEXT_VARIATION_PASSWORD
input_layout.endIconMode = END_ICON_PASSWORD_TOGGLE
Where input_edit_text is com.google.android.material.textfield.TextInputEditText and input_layout is com.google.android.material.textfield.TextInputLayout. Of course you should import these asl well:
import android.text.InputType.TYPE_CLASS_TEXT
import android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
import com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE
My may customize the icon with provided methods as these:
input_layout.endIconDrawable = ...
input_layout.setEndIconOnClickListener { }
input_layout.setEndIconOnLongClickListener(...)
I used a OnClickListener() which is associated to the button that I want to use as toogle.
private EditText email_et, contraseña_et;
protected void onCreate(Bundle savedInstanceState) {
....
contraseña_et = (EditText) findViewById(R.id.contraseña_et);
....
vercontra_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int inputType = contraseña_et.getInputType();
if (inputType == 129){
contraseña_et.setInputType(1);
} else {
contraseña_et.setInputType(129);
}
contraseña_et.setSelection(contraseña_et.getText().length());
}
});
Reading docs, the int value seems to be different so I debugged to find the correct values, it's working awesome and is a little bit easier this way.
[Contraseña is password in spanish, btw]
In XML do like this
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="vertical"
>
<RelativeLayout
android:id="#+id/REFReLayTellFriend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="#+id/etpass1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="50dp"
android:fontFamily="#font/frutiger"
android:gravity="start"
android:inputType="textPassword"
android:hint="#string/regpass_pass1"
android:padding="20dp"
android:paddingBottom="10dp"
android:textColor="#000000"
android:textColorHint="#d3d3d3"
android:textSize="14sp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
<ImageButton
android:id="#+id/imgshowhide1"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:background="#drawable/showpass"
android:layout_alignRight="#+id/etpass1"/>
</RelativeLayout>
boolean show=true;
//on image click inside password do this
if(show){
imgshowhide2.setBackgroundResource(0);
imgshowhide2.setBackgroundResource(R.drawable.hide);
etpass2.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
etpass2.setSelection(etpass2.getText().length());
show=false;
}else{
imgshowhide2.setBackgroundResource(0);
imgshowhide2.setBackgroundResource(R.drawable.showpass);
//etpass1.setInputType(InputType.TYPE_TEXT);
etpass2.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD);
etpass2.setSelection(etpass2.getText().length());
show=true;
}
My Kotlin extension . write once use everywhere
fun EditText.tooglePassWord() {
this.tag = !((this.tag ?: false) as Boolean)
this.inputType = if (this.tag as Boolean)
InputType.TYPE_TEXT_VARIATION_PASSWORD
else
(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD)
this.setSelection(this.length()) }
You can keep this method in any file and use it everywhere
use it like this
ivShowPassword.click { etPassword.tooglePassWord() }
where ivShowPassword is clicked imageview (eye) and etPassword is Editext
Add this method:
fun EditText.revertTransformation() {
transformationMethod = when(transformationMethod) {
is PasswordTransformationMethod -> SingleLineTransformationMethod.getInstance()
else -> PasswordTransformationMethod.getInstance()
}
}
Call it will switch between input type state (you may change the Single-Line transformation to your favorite). Usage example:
editText.revertTransformation()

Categories

Resources