How can I update the ListView without losing focus in the EditText on the list item? (Android)
I have ListView
where each item contains multiple EditTexts
. I am defining the scale, so one of the EditTexts depends on the EditText in the above item. In the example below, B is set to the same value as A when A was edited. Thus, the user is not actually using the right column.
I can listen for events in A and update B and call accordingly notifyDataSetChanged()
, but then I lose focus of my EditText as the ListView is redrawn.
On the bottom line, I want:
Edit the field A , and then when I tap the the C , I would take A for Bed and , and I would like to focus on the C .
This is the "focus on part C" that I'm having trouble with.
ps Actually there is another EditText on the row, so the focus won't always show on the column with A and C.
Edit: Here is my adapter getItemId()
to answer @aniv's comment.
@Override
public Object getItem(int arg0) {
return arg0;
}
EDIT_2: after the override hasStableIds()
to return true, it works fine when I turn on the A to the third column in another element, but not when I turn from the A to the C . I think my override function is onFocusChange
triggering something because it behaves strangely when the focus changes on that column (which uses the same onFocusChange method). Here's my custom onFocusChangeListener.
private class MyFocusChangeListener implements View.OnFocusChangeListener{
private EditText et;
private ScaleItem item;
private Integer pos;
private MyFocusChangeListener(ScaleItem item, Integer pos){
this.item = item;
this.pos = pos;
}
@Override
public void onFocusChange(View v, boolean hasFocus){
if(!hasFocus){
et = (EditText) v;
Activity_EditCourseGPA a = (Activity_EditCourseGPA) activity;
a.updateMaxOnTextChange(item, pos, et.getText().toString());
} else {
}
}
}
The function it is referring to in my activity (use the EditText field to update the underlying data) ....
public void updateMaxOnTextChange(ScaleItem item, Integer pos, String str){
if(pos < scaleItems.size()){
scaleItems.get(pos + 1).setMax(Double.valueOf(str));
scaleListAdapter.notifyDataSetChanged();
}
}
I am using the position and content of the EditText to update the underlying data at the same position. Here you can see what happens when I change focus on the same column. Very strange.
source to share
First, you need a custom class Grade
public class GradeInfo {
boolean enabled;
String gpa, perc1, perc2;
}
You need to create an object List<GradeInfo>
that will contain a list of objects GradeInfo
, each representing a string. You can use this list in your listview adapter. Your adapter will look like this:
private class GradeAdap extends BaseAdapter {
@Override
public int getCount() {
return gradeList.getSize();
}
@Override
public Object getItem(int position) {
return gradeList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = getLayoutInflater().inflate(R.layout.row_grade, null);
return loadGradeRow(convertView, position);
}
}
Yes, the getView
adapter method calls another method loadGradeRow
:
private View loadGradeRow(final View rowView, final int position) {
CheckBox chk= (CheckBox ) rowView.findViewById(R.id.chk);
...// Declare and initialize other views
listIsRefreshing = true; // Explained below
chk.setChecked(gradeList.get(position).enabled);
...// set views accordingly
listIsRefreshing = false;
txtGpa.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(Editable s) {
if(listIsRefreshing) //JUST REFRESHING, DON'T MIND
return;
gradeList.get(position).perc1 = s.toString();
if(position == gradeList.size()-1) //Dont assign if its the last row
return;
gradeList.get(position+1).perc2 = s.toString();
loadGradeRow(listview.getChildAt(position+1), position+1);
}
});
}
listIsRefreshing
is a boolean value that should be declared in your activity. It needs to be ensured that the value is perc2
only assigned when the user entered the value manually.
source to share