如何更新ListView而不会失去焦点在列表项中的EditText? (机器人)

时间:2014-10-19 23:22:37

标签: android listview android-listview android-edittext android-view

我有ListView,其中每个项目包含多个EditTexts。我正在定义一个比例,因此其中一个EditTexts依赖于上面项目中的EditText。在下面的示例中,当 A 被编辑时, B 设置为与 A 相同的值。因此,用户实际上并未使用正确的列。

我能够收听 A 中的事件并更新 B 并相应地调用notifyDataSetChanged(),但之后我失去了我的EditText作为ListView的焦点被重新绘制。

enter image description here

底线,我想要的是:

修改字段 A ,当我点击字段 C 时,我想要 A 的值来申请 B ,我想集中精力去 C

这是“焦点转到C”部分,我遇到了麻烦。

P.S。行上实际上有另一个EditText,因此焦点不会总是转到具有A和C的列。

编辑:这是我的适配器的getItemId()方法,以帮助回答@ aniv的评论。

@Override
    public Object getItem(int arg0) {
        return arg0;
    }

EDIT_2:覆盖hasStableIds()后返回true,当我从 A 转到另一个项目的第三列时效果很好,但是当我从 A < / strong>到 C 。我认为我的onFocusChange覆盖正在弄乱一些东西,因为它只是在更改该列中的焦点时行为奇怪(在其中共享相同的onFocusChange方法)。这是我的自定义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 {

          }
      }
}

它在我的活动中引用的功能(使用EditText字段更新基础数据)....

public void updateMaxOnTextChange(ScaleItem item, Integer pos, String str){
    if(pos < scaleItems.size()){
        scaleItems.get(pos + 1).setMax(Double.valueOf(str));
        scaleListAdapter.notifyDataSetChanged();
    }
}

我使用EditText位置和内容来更新相同位置的基础数据。以下是我在同一列中更改焦点时会发生什么的一瞥。很奇怪。

enter image description here

1 个答案:

答案 0 :(得分:0)

首先,您需要一个自定义类Grade

public class GradeInfo {
  boolean enabled;
  String gpa, perc1, perc2;
}

您需要创建一个List<GradeInfo>对象,该对象将包含GradeInfo个对象的列表,每个对象代表一行。您可以在listview的适配器中使用此列表。您的适配器将如下所示:

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);
    }
}

是的,适配器的getView方法调用另一种方法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是一个布尔值,需要在您的活动中声明。只有当用户手动输入值时,才需要确保将值分配给perc2