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.

enter image description here

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.

enter image description here

+3


source to share


1 answer


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.

0


source







All Articles