I have an EditText box that I want to change the background color and drawable left of when the character count is greater than or equal to 4. As seen in my code snippet below I used a TextWatcher to capture typing events and at the moment the background color changes, but the setCompoundDrawable does not change the drawable on the EditText box.
Am I doing something wrong, or is it a glitch of some sort?
final EditText input = (EditText)view.findViewById( R.id.editText );
input.addTextChangedListener( new TextWatcher() {
#Override
public void beforeTextChanged( CharSequence charSequence, int i, int i2, int i3 ) { }
#Override
public void onTextChanged( CharSequence charSequence, int start, int count, int after ) { }
#Override
public void afterTextChanged( Editable editable ) {
if(editable.length() <= 3 ){
input.setBackgroundColor( getResources().getColor( R.color.edittext_background_red) );
input.setCompoundDrawables( getResources().getDrawable( R.drawable.ic_cross ), null, null, null );
}else if(editable.length() >= 4 ){
input.setBackgroundColor( getResources().getColor( R.color.edittext_background_green ));
input.setCompoundDrawables( getResources().getDrawable( R.drawable.ic_tick ), null, null, null );
}
}
} );
use setCompoundDrawablesWithIntrinsicBounds(...) or call setBounds on your left Drawable before calling setCompoundDrawables
Related
To support RTL even in older version of Android, I can simply do the following for TextView.
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
textView, 0, 0, R.drawable.baseline_recommend_24, 0
);
But, what about Button? Is there something like ButtonCompat class?
Currently, I am getting warning from compiler, on old API, if I write the code the following way.
// button is type Button.
button.setCompoundDrawablesRelativeWithIntrinsicBounds(
smallLockedIconResourceId, 0, 0, 0
);
I tried to build my own utility class since I cannot find an official one.
public class ButtonCompat {
public static void setCompoundDrawablesRelativeWithIntrinsicBounds(Button button, int start, int top, int end, int bottom) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
button.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
} else {
if (isLeftToRight()) {
button.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
} else {
button.setCompoundDrawablesWithIntrinsicBounds(end, top, start, bottom);
}
}
}
public static Drawable[] getCompoundDrawablesRelative(#NonNull Button button) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return button.getCompoundDrawablesRelative();
} else {
if (isLeftToRight()) {
return button.getCompoundDrawables();
} else {
// If we're on RTL, we need to invert the horizontal result like above
final Drawable[] compounds = button.getCompoundDrawables();
final Drawable start = compounds[2];
final Drawable end = compounds[0];
compounds[0] = start;
compounds[2] = end;
return compounds;
}
}
}
}
I am using this method to determine left/ right
https://stackoverflow.com/a/26550588/72437
public static boolean isLeftToRight() {
return MyApplication.instance().getResources().getBoolean(R.bool.is_left_to_right);
}
I have made a sample chat layout which just adds the EditText input to a RecyclerView, but as you see in this picture after the fifth item it doesn't work the way it shoud (the numbers are the EditText outputs)
Fragment class =>
Boolean me = true ;
Boolean seen = false ;
#Override
public void onClick(View view) {
if (view.getId() == R.id.send_button) {
me = !me ;
seen = !seen ;
sendMessage();
}
}
private void sendMessage(){
String editTextString = editText.getText().toString() ;
Calendar calendar = Calendar.getInstance() ;
String time = calendar.get(Calendar.HOUR) + ":" + calendar.get(Calendar.MINUTE) ;
first_message.setVisibility(View.GONE);
if (editTextString.equals("")){
return;
}
E08Object object = new E08Object();
object.setMessage(editText.getText().toString());
object.setDate(time);
object.setMe(me);
object.setSeen(seen);
list.add(object) ;
adapter.notifyDataSetChanged();
fragment_recyclerView.smoothScrollToPosition(list.size());
editText.setText("");
}
Adapter class =>
#Override
public void onBindViewHolder(#NonNull VH holder, int position) {
holder.textView.setText(list.get(position).getMessage());
holder.timeTextVIew.setText(list.get(position).getDate());
if (!list.get(position).getMe()) {
holder.seenImage.setVisibility(View.GONE);
holder.fragmentParent.setBackground(ContextCompat.getDrawable(Application.getContext() , R.drawable.person_message_rounded));
}
}
Please check. You must reset value in else block inside bindViewHolder as the views are recycled.
if (!list.get(position).getMe()) {
holder.seenImage.setVisibility(View.GONE);
holder.fragmentParent.setBackground(ContextCompat.getDrawable(Application.getContext() , R.drawable.person_message_rounded));
} else {
holder.seenImage.setVisibility(View.VISIBLE);
holder.fragmentParent.setBackground(ContextCompat.getDrawable(Application.getContext() , R.drawable.THE_DEFAULT_DRAWABLE));
}
This should help if this issue is due to recycling. Let me know if this helps. Also, better to attach the item layout and the recycler layout.
This question already has answers here:
How to remove drawableleft
(6 answers)
Closed 4 years ago.
I have read many answers in Stack but none of them can't help me, so please don't mark it as Duplicate ,I have EditText, and I want to make visible drawable left when the length of inserted data in EditTextView become equals to 11.
If you want to visible/invisible drawable left on user typing then do like this:
EditText et = (EditText)view.findViewById(R.id.edt);
et.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable editable) {
if(editable.length() >= 11){
// visible
et.setCompoundDrawablesWithIntrinsicBounds(R.drawable.your_icon, 0, 0, 0);
}
else {
// hide
et.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
});
You can use the setCompoundDrawables method to do this:
Drawable img = getContext().getResources().getDrawable(R.drawable.add_more);
img.setBounds(0, 0, 60, 60);
edittext.setCompoundDrawables(img, null, null, null);
if (edittext.lenght == 11) {
img.setVisible(false, false);
}
I hope it will help you!
I'm trying to get a character count of an EditText (numberRoom). When user would insert 8 characters button should switch from state Disabled and color 0xBBFFFFFF to state Enabled and color 0xFFFFFFFF.
I've tried few method and I think the best one I've found is that one below. However button has state Enabled and color 0xFFFFFFFF even when input is empty. What's wrong there?
public class Join_room_screen extends Activity {
EditText numberRoom;
Button goToRoom;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.joinroom);
numberRoom = (EditText) findViewById(R.id.roomNumber);
goToRoom = (Button) findViewById(R.id.goToRoom);
TextWatcher watcher = new LocalTextWatcher();
goToRoom.addTextChangedListener(watcher);
updateButtonState();
}
void updateButtonState() {
boolean enabled = checkEditText(numberRoom);
goToRoom.setBackgroundColor(0xFFFFFFFF);
goToRoom.setEnabled(enabled);
}
private boolean checkEditText(EditText edit) {
return ((edit.getText().toString()).length() == 8 );
}
private class LocalTextWatcher implements TextWatcher {
public void afterTextChanged(Editable s) {
updateButtonState();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
}
However in properties I've
In this function the enabled variable is never used so the background colour and enabled states are always set.
void updateButtonState() {
boolean enabled = checkEditText(numberRoom);
goToRoom.setBackgroundColor(0xFFFFFFFF);
goToRoom.setEnabled(enabled);
}
I would replace with something like
void updateButtonState() {
boolean enabled = checkEditText(numberRoom);
if (enabled) {
goToRoom.setBackgroundColor(0xFFFFFFFF);
goToRoom.setEnabled(enabled);
} else {
//change them back to disabled state
}
}
You have one problem in updateButtonState(), it always sets one color to your button. I see, you have already solved that.
The other problem is that you set TextChangeListener not to an EditText, but somewhy to a Button.
The EditText should be watched.
numberRoom.addTextChangedListener(watcher);
instead of
goToRoom.addTextChangedListener(watcher);
I have a EditText box in which i want to control the cursor and modify the text programmatically
I have 12 button keypad made using 12 buttons in a GridView. With each button press I have a specific text which is to be inserted in EditText box at cursor position. For this i need cursor position so that i can insert the my custom text in the EditText view
I have two buttons for moving cursor position left/right by one character. Alternatively the cursor can also be set by touching EditText view (as EditText is supposed to behave)
Also i want the current position of cursor in EditText whenever Cursor position changes (I think i have to implement some kind of interface but i dont know how)
What i have tried so far
I am storing the key presses in an ArrayList<String>
I am setting the edittext.setText(String) everytime a key is pressed
can get the editable text through getText() but setText() only accepts strings.
Hence i am confused. What should i do to fulfill all my requirements.
PS: I am a Android beginner, and am making my 2nd app (which is a scientific calculator if it helps)
also if anyone volunteers to review my code, I'll be deeply obliged to him
I dont know why you need the cursor position of the textview but take a look at this question here : Get Cursor Position in Android in Edit Text?
Actually you can edit the text in the textview on code by getting the input or if you want you can implement the TextWatcher interface to know what every input the user type in your textview like this one:
private class CheckText implements TextWatcher {
#Override
public void afterTextChanged(Editable s) {
//triggers after the user changed the input on text
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//triggers before the user changed the input on text
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//triggers when the user changed the input on text
}
}
To set any number in EditText use Wrapper class then set it on EditText using toString().
For set position you can use editText.setSelection(position);
It is how I did something similar
Stored id of all the button in a array as shown below.
int[] kbdButtons = { R.id.button1, R.id.button2, R.id.button3,
R.id.button4, R.id.button5, R.id.button6, R.id.button7,
R.id.button8, R.id.button9, R.id.button10, R.id.button11,
R.id.button12, R.id.button13, R.id.button14, R.id.button15}
2.Then added custom Onclicklistner to all buttons in the kbdButtons array
for (int i = 0; i < kbdButtons.length; i++) {
Button buttonNum = (Button) dialoglayout
.findViewById(kbdButtons[i]);
buttonNum.setOnClickListener(hindiKbdBtnsClick);
}
and here is the declaration of custom clicklistner
private OnClickListener hindiKbdBtnsClick = new OnClickListener() {
#Override
public void onClick(View v) {
int btnId = v.getId();
if (isShift && btnId != R.id.kbdKeyLeftShift
&& btnId != R.id.kbdKeyRightShift) {
sNotPressedView.setVisibility(View.VISIBLE);
sPressedView.setVisibility(View.GONE);
isShift = false;
}
if (btnId == R.id.kbdKeyLeftShift || btnId == R.id.kbdKeyRightShift) {
if (!isShift) {
sNotPressedView.setVisibility(View.GONE);
sPressedView.setVisibility(View.VISIBLE);
isShift = true;
} else {
sNotPressedView.setVisibility(View.VISIBLE);
sPressedView.setVisibility(View.GONE);
isShift = false;
}
} else if (btnId == R.id.kbdKeySpace || btnId == R.id.kbdKeyEnter) {
hkEditText.append(" ");
} else if (btnId == R.id.kbdKeyBackSpace) {
String txt_curr_val = hkEditText.getText().toString();
if (txt_curr_val.length() != 0)
txt_curr_val = txt_curr_val.substring(0,
txt_curr_val.length() - 1);
hkEditText.setText(txt_curr_val);
hkEditText.setSelection(txt_curr_val.length());
}else if (btnId == R.id.kbdKeyHide) {
mDialog.hide();
}else {
Button b = (Button) v;
String btnText = b.getText().toString();
hkEditText.append(btnText);
}
}
};
Explanation - hkEditText is my editText view i.e.
EditText hkEditText = (EditText)FindViewById(R.id.myEdittextId);
-see I just appended the text written on the button that is pressed at that time.
-you can also see the functionality of some special buttons like space, shift and enter