简体   繁体   中英

CheckBox set unchecked when scroll listView. My solution interferes whit setOnCheckedChangeListener

I have a ListView with many CheckBox 's, that when are checked at true start a TextToSpeech . Now the problem is that when i scroll in the ListView all the CheckBox that i have checked are reset to unchecked. So have found any tutorials for a solution. But with solution that i have used, the state of the CheckBox is saved in a variable, and when the CheckBox is again visible is rechecked. So the TextToSpeech start again. Here is my code (I know that isn't a good code):

public class MyAdapter extends ArrayAdapter<Model> {
private TreeSet mSeparatorsSet = new TreeSet();
private final List<Model> list;
private final Activity context;
public String textToSay;

public MyAdapter(Activity context, List<Model> list) {
    super(context, R.layout.row, list);

    this.context = context;
    this.list = list;
}

@Override
public int getItemViewType(int position) {
    if (list.get(position).getVersion() == 0) {
        return 0;
    }
    return 1;
}

@Override
public int getViewTypeCount() {
    return 2;
}

static class ViewHolder {
    public TextView text;
    public TextView text2;
    public CheckBox checkbox;
    public TextView textSeparator;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder = null;

    if (this.getItemViewType(position)== 0){
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            viewHolder = new ViewHolder();
            convertView = inflator.inflate(R.layout.title_row, null);
            viewHolder.textSeparator = (TextView) convertView.findViewById(R.id.textView);

            convertView.setTag(viewHolder);
            convertView.setTag(R.id.textView, viewHolder.textSeparator);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.textSeparator.setText(list.get(position).getName());
        return convertView;
    }

    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        convertView = inflator.inflate(R.layout.row, null);
        viewHolder = new ViewHolder();

        viewHolder.text = (TextView) convertView.findViewById(R.id.label);
        viewHolder.text2 = (TextView)convertView.findViewById(R.id.label2);
        viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkBox);

        convertView.setTag(viewHolder);
        convertView.setTag(R.id.label, viewHolder.text);
        convertView.setTag(R.id.checkBox, viewHolder.checkbox);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.checkbox.setTag(position); // This line is important.
    viewHolder.text.setText(list.get(position).getName());
    viewHolder.text2.setText(list.get(position).getName2());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());
    final CheckBox chk = (CheckBox)convertView.findViewById(R.id.checkBox);
    final View finalConvertView = convertView;

    chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            int getPosition = (Integer) buttonView.getTag();
            list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.

            if (isChecked) {
                String textPart1 = " ";
                String textPart2 = " ";
                String textToSay = " ";

                TextView label2 = (TextView) finalConvertView.findViewById(R.id.label2);
                TextView label1 = (TextView) finalConvertView.findViewById(R.id.label);



                textPart1 = label2.getText().toString();
                if ((getPosition + 1) < list.size()) {
                    if(list.get(getPosition+1).getVersion() == 0){
                        textPart2 = list.get(getPosition + 2).getName();
                    } else {
                        textPart2 = list.get(getPosition + 1).getName();
                    }
                }
                textToSay = textPart1 +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        textPart2;

                OneFragment.startSpeak(textToSay);

            }
        }

    });
    return convertView;
}
}

So anyone have an idea how i can solve my problem?


UPDATE


I have found the solution. I have used the method onCheckedChange() for store the result and onClickListener for the events. Here is the new code:

 public class MyAdapter extends ArrayAdapter<Model> {


private TreeSet mSeparatorsSet = new TreeSet();
private final List<Model> list;
private final Activity context;
public String textToSay;
private int mCurrentTtsPosition = -1;

public MyAdapter(Activity context, List<Model> list) {
    super(context, R.layout.row, list);

    this.context = context;
    this.list = list;
}

@Override
public int getItemViewType(int position) {
    if (list.get(position).getVersion() == 0) {
        return 0;
    }
    return 1;
}

@Override
public int getViewTypeCount() {
    return 2;
}

public void onStopTts(){
    mCurrentTtsPosition = -1;
    notifyDataSetChanged();
}

static class ViewHolder {
    public TextView text;
    public TextView text2;
    public CheckBox checkbox;
    public TextView textSeparator;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder = null;

    if (this.getItemViewType(position)== 0){
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            viewHolder = new ViewHolder();
            convertView = inflator.inflate(R.layout.title_row, null);
            viewHolder.textSeparator = (TextView) convertView.findViewById(R.id.textView);

            convertView.setTag(viewHolder);
            convertView.setTag(R.id.textView, viewHolder.textSeparator);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.textSeparator.setText(list.get(position).getName());
        return convertView;
    }

    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        convertView = inflator.inflate(R.layout.row, null);
        viewHolder = new ViewHolder();

        viewHolder.text = (TextView) convertView.findViewById(R.id.label);
        viewHolder.text2 = (TextView)convertView.findViewById(R.id.label2);
        viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkBox);

        convertView.setTag(viewHolder);
        convertView.setTag(R.id.label, viewHolder.text);
        convertView.setTag(R.id.checkBox, viewHolder.checkbox);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.checkbox.setTag(position); // This line is important.
    viewHolder.text.setText(list.get(position).getName());
    viewHolder.text2.setText(list.get(position).getName2());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());
    viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            int getPosition = (Integer) buttonView.getTag();
            list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
        }
    });
    final CheckBox chk = (CheckBox)convertView.findViewById(R.id.checkBox);
    final View finalConvertView = convertView;

    if (position == mCurrentTtsPosition){
        chk.setChecked(true);
    }

    chk.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int getPosition = (Integer) chk.getTag();


            if (chk.isChecked()) {
                //  mCurrentTtsPosition = getPosition;

                String textPart1 = " ";
                String textPart2 = " ";
                String textToSay = " ";

                TextView label2 = (TextView) finalConvertView.findViewById(R.id.label2);
                TextView label1 = (TextView) finalConvertView.findViewById(R.id.label);


                textPart1 = label2.getText().toString();
                if ((getPosition + 1) < list.size()) {
                    if (list.get(getPosition + 1).getVersion() == 0) {
                        textPart2 = list.get(getPosition + 2).getName();
                    } else {
                        textPart2 = list.get(getPosition + 1).getName();
                    }
                }
                textToSay = textPart1 +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        "\n" + "." +
                        textPart2;

                OneFragment.startSpeak(textToSay);

            }
        }
    });

    return convertView;
}
}

Store the position in global int (mCurrentTtsPosition) before you call startSpeak if mCurrentTtsPosition != currentPosition. Use this mCurrentTtsPosition to recheck the view on getView, but in this case, don't call startSpeak. Reset mCurrentTtsPosition to -1 with public method of your adapter called by your fragment when the playing is finished.

public class MyAdapter extends ArrayAdapter<Model> {


private TreeSet mSeparatorsSet = new TreeSet();
  private final List<Model> list;
  private final Activity context;
  public String textToSay;
  private int mCurrentTtsPosition = -1;

  public MyAdapter(Activity context, List<Model> list) {
      super(context, R.layout.row, list);

      this.context = context;
      this.list = list;
  }

  @Override
  public int getItemViewType(int position) {
      if (list.get(position).getVersion() == 0) {
          return 0;
      }
      return 1;
  }

  @Override
  public int getViewTypeCount() {
      return 2;
  }

  public void onStopTts(){
    mCurrentTtsPosition = -1;
    notifyDataSetChanged();
  }

  static class ViewHolder {
      public TextView text;
      public TextView text2;
      public CheckBox checkbox;
      public TextView textSeparator;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder viewHolder = null;

      if (this.getItemViewType(position)== 0){
          if (convertView == null) {
              LayoutInflater inflator = context.getLayoutInflater();
              viewHolder = new ViewHolder();
              convertView = inflator.inflate(R.layout.title_row, null);
              viewHolder.textSeparator = (TextView) convertView.findViewById(R.id.textView);

              convertView.setTag(viewHolder);
              convertView.setTag(R.id.textView, viewHolder.textSeparator);

          } else {
              viewHolder = (ViewHolder) convertView.getTag();
          }
          viewHolder.textSeparator.setText(list.get(position).getName());
          return convertView;
      }

      if (convertView == null) {
          LayoutInflater inflator = context.getLayoutInflater();
          convertView = inflator.inflate(R.layout.row, null);
          viewHolder = new ViewHolder();

          viewHolder.text = (TextView) convertView.findViewById(R.id.label);
          viewHolder.text2 = (TextView)convertView.findViewById(R.id.label2);
          viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkBox);

          convertView.setTag(viewHolder);
          convertView.setTag(R.id.label, viewHolder.text);
          convertView.setTag(R.id.checkBox, viewHolder.checkbox);
      } else {
          viewHolder = (ViewHolder) convertView.getTag();
      }

      viewHolder.checkbox.setTag(position); // This line is important.
      viewHolder.text.setText(list.get(position).getName());
      viewHolder.text2.setText(list.get(position).getName2());
      viewHolder.checkbox.setChecked(list.get(position).isSelected());
      final CheckBox chk = (CheckBox)convertView.findViewById(R.id.checkBox);
      final View finalConvertView = convertView;

      if (position == mCurrentTtsPosition){
        chk.setChecked(true);
      }

      chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
          @Override
          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
              int getPosition = (Integer) buttonView.getTag();
              list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.

              if (isChecked && getPosition != mCurrentTtsPosition) {
                  mCurrentTtsPosition = getPosition;

                  String textPart1 = " ";
                  String textPart2 = " ";
                  String textToSay = " ";

                  TextView label2 = (TextView) finalConvertView.findViewById(R.id.label2);
                  TextView label1 = (TextView) finalConvertView.findViewById(R.id.label);



                  textPart1 = label2.getText().toString();
                  if ((getPosition + 1) < list.size()) {
                      if(list.get(getPosition+1).getVersion() == 0){
                          textPart2 = list.get(getPosition + 2).getName();
                      } else {
                          textPart2 = list.get(getPosition + 1).getName();
                      }
                  }
                  textToSay = textPart1 +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          "\n" + "." +
                          textPart2;

                  OneFragment.startSpeak(textToSay);

              }
          }

      });
      return convertView;
  }
}

hi Please add One more field in your list like "selected" and set it to false and check like below. also change the value of "selected" true on checked.

change the getView() like below.

if(list.get(position).getSelected()){
// set the checkbox selected
}else{
// set the checkbox unselected
}

and in setOnCheckedChangeListener() add bellow

if(isChecked){
list.get(position).put("selected",true));
}else{
list.get(position).put("selected",false));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM