I have three edittext on one layout. When it's empty, then I remove the right drawable. When it isn't empty, I added the drawable. When you click to drawable, I clear the edittext.
When I clicked to rightdrawable, the cursor was stuck, and underline stay colored. Rarely I have a 2-3 cursor. Why?? What I do bad?
BAD:
GOOD:
The Layout:
<EditText
android:id="#+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="#mipmap/ic_launcher"/>
<EditText
android:id="#+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="#mipmap/ic_launcher"/>
<EditText
android:id="#+id/et3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="#mipmap/ic_launcher"/>
The MainActivity
public class MainActivity extends AppCompatActivity {
private DrawableState etstate1;
private DrawableState etstate2;
private DrawableState etstate3;
private EditText et2;
private EditText et1;
private EditText et3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et1 = (EditText)findViewById(R.id.et1);
et2 = (EditText)findViewById(R.id.et2);
et3 = (EditText)findViewById(R.id.et3);
etstate1 = new DrawableState(et1);
etstate2 = new DrawableState(et2);
etstate3 = new DrawableState(et3);
et1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (DrawableClick.isDrawableClick(motionEvent, et1, DRAWABLE_RIGHT)) {
et1.setText("");
etstate1.refreshDrawable();
return true;
}
return false;
}
});
et2.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (DrawableClick.isDrawableClick(motionEvent, et2, DRAWABLE_RIGHT)) {
et2.setText("");
etstate2.refreshDrawable();
return true;
}
return false;
}
});
et3.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (DrawableClick.isDrawableClick(motionEvent, et3, DRAWABLE_RIGHT)) {
et3.setText("");
etstate3.refreshDrawable();
return true;
}
return false;
}
});
et1.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) {}
#Override
public void afterTextChanged(Editable editable) {
etstate1.refreshDrawable();
}
});
et2.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) {}
#Override
public void afterTextChanged(Editable editable) {
etstate2.refreshDrawable();
}
});
et3.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) {}
#Override
public void afterTextChanged(Editable editable) {
etstate3.refreshDrawable();
}
});
}
}
Helper classes:
public class DrawableClick {
public static boolean isDrawableClick(MotionEvent event, EditText editText, DrawablePositions drawablePosition) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (editText.getCompoundDrawables()[drawablePosition.position] != null && event.getX() >= (editText.getRight() - editText.getLeft() - editText.getCompoundDrawables()[drawablePosition.position].getBounds().width())) {
return true;
}
}
return false;
}
public enum DrawablePositions {
DRAWABLE_LEFT(0),
DRAWABLE_TOP(1),
DRAWABLE_RIGHT(2),
DRAWABLE_BOTTOM(3);
private int position;
DrawablePositions(int pos) {
this.position = pos;
}
}
}
Next:
public class DrawableState {
private EditText editText;
private Drawable[] editTextDrawables;
public DrawableState(EditText editText) {
this.editText = editText;
saveDrawableState();
refreshDrawable();
}
public void saveDrawableState() {
this.editTextDrawables = editText.getCompoundDrawables();
}
public void refreshDrawable() {
if (editText.getText().toString().equals("")) {
editText.setCompoundDrawables(null, null, null, null);
editText.clearFocus();
} else {
if (editTextDrawables != null) {
editText.setCompoundDrawables(editTextDrawables[0], editTextDrawables[1], editTextDrawables[2], editTextDrawables[3]);
}
}
}
I found the solution.
Change it
if (DrawableClick.isDrawableClick(motionEvent, et3, DRAWABLE_RIGHT)) {
...
return true;
}
return false;
To:
if (DrawableClick.isDrawableClick(motionEvent, et3, DRAWABLE_RIGHT)) {
...
motionEvent.setAction(MotionEvent.ACTION_CANCEL);
}
return false;
Related
I have recyclerView where i have added a editText. But when I type text to one edittext, text shows another edittext too. Here is the image..
Above image, I type 100 to other item, but it also shows in Settlements
Here is my adapter:
public class AdapterSectionRecycler extends SectionRecyclerViewAdapter<SectionHeader, Child, SectionViewHolder, ChildViewHolder> {
Context context;
private final OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(Child child,Boolean isChecked);
}
public AdapterSectionRecycler(Context context, List<SectionHeader> sectionItemList,OnItemClickListener listener) {
super(context, sectionItemList);
this.context = context;
this.listener = listener;
}
#Override
public SectionViewHolder onCreateSectionViewHolder(ViewGroup sectionViewGroup, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.section_item, sectionViewGroup, false);
return new SectionViewHolder(view);
}
#Override
public ChildViewHolder onCreateChildViewHolder(ViewGroup childViewGroup, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout, childViewGroup, false);
return new ChildViewHolder(view);
}
#Override
public void onBindSectionViewHolder(SectionViewHolder sectionViewHolder, int i, SectionHeader sectionHeader) {
Log.e("name section--",sectionHeader.getSectionText());
sectionViewHolder.name.setText(sectionHeader.getSectionText());
}
#Override
public void onBindChildViewHolder(ChildViewHolder childViewHolder, int i, int i1, Child child) {
childViewHolder.chk_answer.setText(child.getAnswerName());
childViewHolder.tv_surveyAnswerId.setText(String.valueOf(child.getAnswerId()));
childViewHolder.chk_answer.setChecked(false);
childViewHolder.etPercentage.setImeOptions(EditorInfo.IME_ACTION_DONE);
childViewHolder.etsl.setVisibility(View.GONE);
childViewHolder.chk_answer.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
listener.onItemClick(child,true);
}else{
listener.onItemClick(child,false);
}
}
});
childViewHolder.etPercentage.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) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
Here is my Child View holder
public class ChildViewHolder extends RecyclerView.ViewHolder {
CheckBox chk_answer;
EditText etPercentage;
EditText etsl;
TextView tv_surveyAnswerId;
public ChildViewHolder(View itemView) {
super(itemView);
chk_answer = (CheckBox) itemView.findViewById(R.id.chk_answer);
etPercentage = (EditText) itemView.findViewById(R.id.etPercentage);
etsl = (EditText) itemView.findViewById(R.id.etsl);
tv_surveyAnswerId = (TextView) itemView.findViewById(R.id.tv_surveyAnswerId);
}
}
I call from activity:
AdapterSectionRecycler adapterSectionRecycler = new AdapterSectionRecycler(this, sections, new AdapterSectionRecycler.OnItemClickListener() {
#Override
public void onItemClick(Child child, Boolean isChecked) {
}
});
recyclerView_land_conversion.setAdapter(adapterSectionRecycler);
What is the wrong with my code? Please help me..
I have this problem in which I have two variables - 'mobile_input' & 'mobile_input_login'. I also have 2 TextUtils also.
Instead of making two different TextUtils, I want to make one TextUtils. I have searched on the web but there is no relevant question like that.
The code:
mobile_input.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) {
if (TextUtils.isEmpty(s.toString().trim())) {
clear2.setVisibility(View.INVISIBLE);
} else {
clear2.setVisibility(View.VISIBLE);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
mobile_input_login.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) {
if (TextUtils.isEmpty(s.toString().trim())) {
clear4.setVisibility(View.INVISIBLE);
} else {
clear4.setVisibility(View.VISIBLE);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
Thank you for your answer in advance.
You can create a custom class implementing TextWatcher:
public class MyTextWatcher implements TextWatcher {
private View view;
public MyTextWatcher(View view) {
this.view = view;
}
#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 (TextUtils.isEmpty(s.toString().trim())) {
view.setVisibility(View.INVISIBLE);
} else {
view.setVisibility(View.VISIBLE);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
And then use it on both text fields:
mobile_input.addTextChangedListener(new MyTextWatcher(clear2));
mobile_input_login.addTextChangedListener(new MyTextWatcher(clear4));
I hope that answers your question.
I have a ListView that can have new rows appended onto the bottom by calling notifyDataSetChanged(); and increasing the line count by 1. The ListView contains rows of EditTexts.
After calling notifyDataSetChanged(); I want to keep the values that have previously been entered by the user. It seems to be working as long as I don't go back and update one of the values I have already entered after calling notifyDataSetChanged();. Code is below:
public class AddPeopleNewProcedureActivity extends AppCompatActivity {
private ListView addPeopleListView;
private CustomAdapterClass customAdapter;
private FloatingActionButton fab;
private int lineCount;
private EditText personsNameET;
private EditText personsPhoneET;
private List<String> personsName;
private List<String> personsPhone;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addpeoplenew_activity);
setupActivityReferences();
inflateListView();
setupClickListeners();
}
private void setupClickListeners() {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
lineCount = lineCount +1;
customAdapter.notifyDataSetChanged();
}
});
}
private void inflateListView() {
customAdapter = new CustomAdapterClass();
addPeopleListView.setAdapter(customAdapter);
}
private void setupActivityReferences() {
addPeopleListView = (ListView) findViewById(R.id.listViewAddPeople);
fab = findViewById(R.id.fabAddPerson);
lineCount = 1;
personsName = new ArrayList<String>();
personsPhone = new ArrayList<String>();
}
public class CustomAdapterClass extends BaseAdapter {
#Override
public int getCount() {
return lineCount;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null){
view = getLayoutInflater().inflate(R.layout.row_addpersonnew,null);
}
personsNameET = (EditText) view.findViewById(R.id.personNameEditText);
personsPhoneET = (EditText) view.findViewById(R.id.personPhoneNoEditText);
final int rowClicked = i;
if (personsName != null && !personsName.isEmpty() && !(rowClicked >= personsName.size())){
personsNameET.setText(personsName.get(rowClicked));
}
if (personsPhone != null && !personsPhone.isEmpty() && !(rowClicked >= personsPhone.size())){
personsPhoneET.setText(personsPhone.get(rowClicked));
}
personsNameET.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) {
}
#Override
public void afterTextChanged(Editable editable) {
if(!personsName.isEmpty()){
if (!(rowClicked >= personsName.size())){
personsName.set(rowClicked,personsNameET.getText().toString());
System.out.println("Set "+rowClicked + "Value is: " + personsName.get(rowClicked));
}else{
personsName.add(rowClicked,personsNameET.getText().toString());
System.out.println("Added" +rowClicked + "Value is: " + personsName.get(rowClicked));
}
} else{
personsName.add(rowClicked,personsNameET.getText().toString());
System.out.println("Added" +rowClicked + "Value is: " + personsName.get(rowClicked));
}
}
});
personsPhoneET.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) {
}
#Override
public void afterTextChanged(Editable editable) {
}
});
return view;
}
}
}
You are using twice this code snippet in your code. Please remove blank one :
personsPhoneET.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) {
}
#Override
public void afterTextChanged(Editable editable) {
}
});
Do like this :
public class AddPeopleNewProcedureActivity extends AppCompatActivity {
private ListView addPeopleListView;
private CustomAdapterClass customAdapter;
private FloatingActionButton fab;
private int lineCount;
private EditText personsNameET;
private EditText personsPhoneET;
private List<String> personsName;
private List<String> personsPhone;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addpeoplenew_activity);
setupActivityReferences();
inflateListView();
setupClickListeners();
}
private void setupClickListeners() {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
lineCount = lineCount +1;
customAdapter.notifyDataSetChanged();
}
});
}
private void inflateListView() {
customAdapter = new CustomAdapterClass();
addPeopleListView.setAdapter(customAdapter);
}
private void setupActivityReferences() {
addPeopleListView = (ListView) findViewById(R.id.listViewAddPeople);
fab = findViewById(R.id.fabAddPerson);
lineCount = 1;
personsName = new ArrayList<String>();
personsPhone = new ArrayList<String>();
}
public class CustomAdapterClass extends BaseAdapter {
#Override
public int getCount() {
return lineCount;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null){
view = getLayoutInflater().inflate(R.layout.row_addpersonnew,null);
}
personsNameET = (EditText) view.findViewById(R.id.personNameEditText);
personsPhoneET = (EditText) view.findViewById(R.id.personPhoneNoEditText);
final int rowClicked = i;
if (personsName != null && !personsName.isEmpty() && !(rowClicked >= personsName.size())){
personsNameET.setText(personsName.get(rowClicked));
}
if (personsPhone != null && !personsPhone.isEmpty() && !(rowClicked >= personsPhone.size())){
personsPhoneET.setText(personsPhone.get(rowClicked));
}
personsNameET.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) {
}
#Override
public void afterTextChanged(Editable editable) {
if(!personsName.isEmpty()){
if (!(rowClicked >= personsName.size())){
personsName.set(rowClicked,personsNameET.getText().toString());
System.out.println("Set "+rowClicked + "Value is: " + personsName.get(rowClicked));
}else{
personsName.add(rowClicked,personsNameET.getText().toString());
System.out.println("Added" +rowClicked + "Value is: " + personsName.get(rowClicked));
}
} else{
personsName.add(rowClicked,personsNameET.getText().toString());
System.out.println("Added" +rowClicked + "Value is: " + personsName.get(rowClicked));
}
}
});
}
I'm new to Android development. I'm facing a dead end developing an app for a project. Please take some time and help me out.
The problem:
I am generating some EditText views nested in a LinearLayout using a for loop.
For example:
LinearLayout rootView = (LinearLayout) findViewById(R.id.rootview);
for (int i=0,j=10;i<j;i++) {
EditText et = new EditText(this);
rootView.addView(et);
et.setHint("EditText No. "+ i);
et.setId(i);
} // This code is for example purposes only.
Now, I can't seem to understand how I can set an addTextChangedListener on the EditText that is focused at a particular time and set that text on other EditTexts. Please tell me what approach should I adopt to achieve this. I tried my best to explain the problem; however, if there is still any ambiguity, feel free to comment and ask. I'm waiting for a solution to this problem.
In terms of screenshots:
What I have:
What I want:
I hope this clears things up!
**
EDIT:
Thanks to TylerSebastian for the solution. I got it to work. Here is the final code: (Inside OnCreate() method)
final LinearLayout rootView = (LinearLayout) findViewById(R.id.rootview);
for (int i=0,j=10;i<j;i++) {
final EditText et = new EditText(this);
rootView.addView(et);
et.setHint("EditText No. "+ i);
et.setId(i);
final TextWatcher textwatcher = 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) {
}
#Override
public void afterTextChanged(final Editable s) {
for (int i=0;i<10;i++){
EditText view = (EditText) findViewById(i);
if (view != et){
view.setText(s.toString());
}
}
}
};
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
et.addTextChangedListener(textwatcher);
} else {
et.removeTextChangedListener(textwatcher);
}
}
});
}
**
I don't have access to a machine with AS on it atm so no guarantee that the following is bug-free, but this should point you in the right direction:
final LinearLayout rootLayout = ...;
// within your loop
et.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(final Editable s) {
for (int i = 0; i < rootLayout.getChildCount(); i++) {
View view = rootLayout.getChildAt(i);
if (view instanceof EditText && view != et) {
((EditText) view).setText(s.toString());
}
}
}
});
edit: so the above will cause an infinite loop - see my comment below
How about:
final LinearLayout rootLayout = ...;
// again, within your loop
TextWatcher textWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(final Editable s) {
for (int i = 0; i < rootLayout.getChildCount(); i++) {
View view = rootLayout.getChildAt(i);
if (view instanceof EditText && view != et) {
((EditText) view).setText(s.toString());
}
}
}
};
et.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
((EditText) view).addTextChangedListener(textWatcher);
} else {
((EditText) view).removeTextChangedListener(textWatcher);
}
}
});
basically, only the focused element will have the textwatcher
first add a LinearLayout in your XML like that
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
then create a new class
public class EditTextCust extends RelativeLayout {
EditText status;
public EditTextCust(Context context, Model post, int inputType,TextWatcher textWatcher) {
super(context);
inflate(context, R.layout.edit_text_cust, this);
status = (EditText) findViewById(R.id.editText);
status.setInputType(inputType);
post.setData(status.getText().toString());
status.setHint(post.getHint());
status.addTextChangedListener(textWatcher);
}
public String getText() {
return status.getText().toString();
}
public EditTextCust(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextCust(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
and creat new XML file names edit_text_cust for this custom view class
<EditText
android:id="#+id/dateEditText"
android:layout_width="match_parent"
android:background="#android:color/transparent"
android:padding="#dimen/_5sdp"
android:layout_height="match_parent"
android:textSize="#dimen/_12sdp" />
and creat model class to set your data
public class Model {
String hint;
String id;
String data;
public String getHint() {
return hint;
}
public void setHint(String hint) {
this.hint = hint;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
and in your class inside the for loop but this code
Model model = new Model();
model.setHint("HINT");
model.setId("1");
editTextCust = new EditTextCust(this, editTextCustModel, InputType.TYPE_CLASS_NUMBER, 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) {
// getText from here use
s.toString();
}
#Override
public void afterTextChanged(Editable s) {
}
});
linearLayout.addView(editTextCust);
it's work with me correctly, and if you didn't understand any thing from this code just add comment and i will help you :)
How can I change the stroke color of a Button when two EditText are not empty?
Code:
if (editText1.getText().toString().trim().length() > 0 && editText2.getText().toString().trim().length() > 0) {
btn.setBackgroundResources(R.drawable.change_stroke);
} else {
btn.setBackgroundResources(R.drawable.change_normal);
}
You should implement and register a TextWatcher for each EditText.
With some code:
// lookup for Views
final EditText e1 = (EditText) rootView.findViewById(R.id.editText);
final EditText e2 = (EditText) rootView.findViewById(R.id.editText2);
final Button btn = (Button) rootView.findViewById(R.id.button);
// TextWatcher definitions (to react on text changes)
TextWatcher tw = 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) {
if (e1.getText().length() > 0 && e2.getText().length() > 0) {
btn.setBackgroundResources(R.drawable.change_stroke);
} else {
btn.setBackgroundResources(R.drawable.change_normal);
}
}
#Override
public void afterTextChanged(Editable s) { }
}
// text watcher registration to the 2 EditText
e1.addTextChangedListener(tw);
e2.addTextChangedListener(tw);
use text watcher . onTextChanged do your magic there.
private class MyTextWatcher implements TextWatcher {
private View view;
private MyTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//set the default button stroke color
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//set the final button stroke color
}
}
}
Define your colors using drawable file or in the resource file