How to properly get & set text to editText in expandable recycler view - android

i'm working with expandable recycler view from bignerdranch. Inside my child view, i placed a edit text where user can leave a comment regarding an issue shown on the parent view.
My problem is that, i wanted the user input to be save after the edit text loose focus. (In this case, i have 3 parents, and each parent has 1 editText). But when i input edit text 1 and focus on edit text 2 without inputing... edit text 2 would take up edit text 1 input after it loose focus.
I try using text watcher, and put the codes inside after text changes.. but the app freezes and stopped working after a while. If there a better way for me to save accordingly?
mCatatan is my editText.
#Override
public void onBindChildViewHolder(final ATPChildViewHolder atpChildViewHolder, int i, Object childObject) {
final ATPChild atpChild = (ATPChild) childObject;
final String text = atpChildViewHolder.mCatatanInput.getText().toString();
if(!text.equals("")) {
atpChild.setDetail(text);
atpChildViewHolder.mCatatanInput.setText(atpChild.getDetail());
} else {
atpChildViewHolder.mCatatanInput.setText(atpChild.getDetail());
}
// todo: fixed catatan being saved to another catatan
atpChildViewHolder.mCatatanInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
Log.d(TAG, "onFocusChange: ");
atpChild.setDetail(atpChildViewHolder.mCatatanInput.getText().toString());
atpChildViewHolder.mCatatanInput.setText(atpChild.getDetail());
}
}
});
}

Related

If I assign an EditText to another EditText, why do they point to the same value?

Today I came across this really interesting situation.
Suppose:
An EditText is instantiated from XML.
EditText editText;
editText = findViewByID(R.id.editText_xml_id);
Now, I want to listen for change in focus in the EditText. So I write the following code:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in parent" );
}
});
Everything is good up until this point as when change in focus, the Log is triggered.
Now the interesting part:
Say, I want to put the same focus listener, but twice!
So what I will do is:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in parent: First callback" );
}
});
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in parent: Second callback" );
}
});
What I had expected was, since editText instance has been set to listen to two instances of View.OnFocusChangeListeners I thought the results would arrive in both listeners.
But only later I realized that only the latter listener ( which was set at the latest ) sent the actual callback inside onFocuChange();
This means, when the focus was changed, I was expecting :
Log.e("TAG", "Focus Changed in parent: First callback" );
Log.e("TAG", "Focus Changed in parent: Second callback" );
but what I got was :
Log.e("TAG", "Focus Changed in parent: Second callback" );
With a little thought, I think this happened because the first listener that was set in editText was replaced by the latter one. And thus only one TAG was hit. (Please correct me if I'm wrong on this)
On experimenting further, I thought what if I assign editText to a different EditText variable and then set two unique listeners to each?
So I did this :
EditText childEditText1;
childEditText1 = editText;
Then I assigned two different listeners:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in child" );
}
});
childEditText1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in parent" );
}
});
On changing focus, what I was expecting was both the tags to be hit. This was because now there are two DIFFERENT instances of the same variable, and they each listen to two DIFFERENT listeners. But again, only one was hit.
Expectation:
//Expected
Log.e("TAG", "Focus Changed in child" );
Log.e("TAG", "Focus Changed in parent" );
Reality:
//Reality
Log.e("TAG", "Focus Changed in parent" );
What I am guessing is no matter what, both the EditText instances are pointing to the same memory space ? Or what is it? Because otherwise both the TAGS would have been hit.
Now, this would be as expected if there were some String and its values were being changed.
Like:
String str = "hi";
str1 = str;
str1 = str1 + " there";
Log.e("TAG", "str " + str );
Result: hi
Log.e("TAG", "str1 " + str1 );
Result : hi there
But from above experiment, it was like :
Log.e("TAG", "str " + str );
Result: hi there
//which is not the case
And this bugs my mind a lot.
Please explain why this sort of anomaly with EditText and if there is any technical term for this in Java. And do point to any resource or books that explain such better. I'm not new to Android but this definitely is.
Thanks!
his was because now there are two DIFFERENT instances of the same
variable, and they each listen to two DIFFERENT listeners. But again,
only one was hit. Expectation:
you are calling a setter on the same reference. The last one wins (it overrides the previous one)
Please explain why this sort of anomaly with EditText and if there is
an y technical term for this in Java.And do point to any resource or
books that explains such better. I'm not new to Android but this
definitely is.
Assigning a reference won't copy an object. It is not related to EditText
First question: the first listener that was set in editText was replaced by the latter one :
cause: http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/view/View.java#6318
//view.java
/**
* Register a callback to be invoked when focus of this view changed.
*
* #param l The callback that will run.
*/
public void setOnFocusChangeListener(OnFocusChangeListener l) {
getListenerInfo().mOnFocusChangeListener = l;
}
ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
}
mListenerInfo = new ListenerInfo();
return mListenerInfo;
}
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/view/View.java#4271
and so u can see , there is only one changelistener could be set . and the second one will replace the first one.
second question: upper answer is quite good.
This is a general programming concept.
1- editText.onFocusListener is null.
2- editText.onFocusListener is changed by the below block. It now prints the first Log.
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in child" );
}
});
3- editText.onFocusListener is changed by the below block. It now prints the other Log.
childEditText1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Log.e("TAG", "Focus Changed in parent" );
}
});
This is completely different to something like addOnChangeListener.
The above is a set function which is different to an add Function.
Hope this clears it up!
private EditText editTextone;
private Editext editTexttwo;
editTextone =(EditText) findViewByID(R.id.editText_xml_id_one);
editTexttwo =(EditText) findViewByID(R.id.editText_xml_id_one);

Edit text loosing focus after typing something

I am inflating edit text in adapter class within of a list view. View is looking cool multiple edit text are appearing properly but when I do focus on the edit text or if I try to type something it loosing focus I tried to adding listeners, changing manifest file but nothing works for me.
following code is not working for me
#Override
public View getChildView(int position, int i1, boolean b, View view,
ViewGroup viewGroup) {
EditText comment = view.findViewById(R.id.txtRecordComment);
comment.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (lastFocussedPosition == -1 || lastFocussedPosition == position) {
lastFocussedPosition = position;
edittext.requestFocus();
}
}
}, 200);
} else {
lastFocussedPosition = -1;
}
}
});
return view;
}
please help me to resolve this issue
Since you are using a ListView, it is bound to happen with your current code implementation.
You must remember that if your EditText is in a ListView, every key down will result in the edit text losing and getting focus because all the views are redrawn, so the edit text representing whatever row used to be focused is now a completely different object.
To get the expected behaviour, declare a variable in your adapter: int focusedRow. In getView method of your adapter, add an onFocusChanged listener to the EditText and when that edit text gains focus, set focusedRow = whatever row the focused EditText happens to be in.
Also set any edit text that is in the currentlyFocusedRow to be focused.
Update:
If you have multiple EditTexts, add an onFocusChanged listener to each edit text.
Add below code in Android Manifest file
<activity android:name=".ActivityName"
android:label="#string/app_name"
android:windowSoftInputMode="adjustPan">
Hope this will work

Appending Text to Android TextView but Non-Editable

I want to append text to an android EditText view but I want that text to not be present in the popup editor. To be clear I want to put units in the EditText. So for example "10 gallons" but when the popup editor is displayed I only want to see and edit "10". Then when the value is returned I want the " gallons" appended back on to the view.
Is this possible in an automatic way or do I have to track onTouch() events and have a listener for the keyboard and manually append the units again?
I believe the onFocusChange method for EditText views would detect when a user is editing the text field. Try something like this..
EditText et = (EditText) findViewById(R.id.editText);
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if (b) {
((EditText)view).setText(String.valueOf(value));
} else {
value = Integer.valueOf(((EditText)view).getText().toString());
((EditText)view).setText(value + " gallons");
}
}
});

EditText - change background color of text (and only text - not the whole view)

When a user enters information in an EditText, and moves to the next EditText, the information is highlighted as shown below:
The code for this:
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
v.setBackgroundColor(Color.WHITE);
((EditText) v).setTextColor(Color.BLACK);
} else {
//v.setBackgroundColor(Color.LTGRAY); //also works like this
((EditText) v).setBackgroundColor(Color.LTGRAY);
((EditText) v).setTextColor(Color.BLACK);
}
}
});
Which is called in the onCreate method like this:
edittext = (EditText) findViewById(R.id.editText1);
However, It would be much better if the background color only applied to the text itself, rather than the view, like this (from the gmail app):
Does anybody have any suggestions on how to apply the background color to the text only (not the whole EditText view) as above?
Thanks.
You can achieve what you want by using a BackgroundColorSpan. You can find more information here:
http://developer.android.com/reference/android/text/style/BackgroundColorSpan.html
To use spans you need to build a SpannableString which you can do using a SpannableStringBuilder:
http://developer.android.com/reference/android/text/SpannableStringBuilder.html

How to check value entered in the Second EditText is Smaller or not in Android

I have two Edit Text fields in my application,if i enter 50 in first edit Text then in the second edit text i want to give permission to enter values less than 50 when the user enters a value in the second edit text, i want to give alert to the user if it is bigger than first edit text value.
How can i do this,means i need to check and show the alert when he enter the values i don't want to show the alert when we press any other fields...
For example:in field 1 if user enter 35
in field2 he has enter value less than 35 only...
initialize both edittext's, lets called them myEditText1 and myEditText2
in myEditText2 set a listener, there should be some kind of listener for when the text changes. Look for something like setOnTextChangedListener, here is how it would be used (this is pseudocode)
myEditText2.setOnTextChangedListener(new OnTextChangedListener(){
#Override
public void OnTextChanged(View v)
{
int i = Integer.valueOf(myEditText1.getText().toString());
int j = Integer.valueOf(myEditText2.getText().toString());
if(j >= i)
{
myEditText2.setText(""); //this automatically sets the editText2 field back to empty
}
}
});
this will only allow the user to enter numerical values lower than the value in the first edit text.
But you need to make sure that the inputType: of both of your editText fields is set to numeric.
You can compare numbers onFocuseChange of second edit text.
editText2.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus) {
// here place code for comparison and calling alert
}
}
});

Categories

Resources