一行中的按钮单击侦听器会影响RecyclerView中其他行中的其他按钮

时间:2019-03-02 08:59:49

标签: java android android-recyclerview

我正在尝试为老师构建一个应用程序,以显示他们所教课程的成绩单。它可以通过互联网吸引学生,并且效果很好。

问题是当他们想为学生提交“缺席”时,应用程序使缺席按钮和当前按钮不可见,而TextView将在他们的位置可见。现在,当他们单击每行中的缺席按钮时,它会正确消失,但当前按钮不会消失。另一行中的另一个存在按钮消失。有什么问题。

这是我的适配器:

public class CourseListAdapter extends RecyclerView.Adapter<CourseListAdapter.MyViewHolder> {

      List<CourseStruct> courses;
      CourseListAdapter courseListAdapter;

      TextView number, name, status;
      ImageView absent, present, addNote;
      ViewGroup root;
      private static CourseListener clickListener;

      public CourseListAdapter(List<CourseStruct> courses, CourseListener listener) {
        this.courses = courses;
        this.clickListener = listener;
      }


      public interface CourseListener {
        void onAbsentClick(int position, View view);

        void onPresentClick(int position, View view);

        void onAddNoteClick(int position, View view);
      }

      @Override
      public MyViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
          .inflate(R.layout.adapter_score_list, parent, false);
        MyViewHolder viewHolder = new MyViewHolder(itemView);
        return viewHolder;
      }

      @Override
      public void onBindViewHolder(final MyViewHolder holder, int position) {
        holder.setIsRecyclable(true);
        CourseStruct course = courses.get(position);
        name.setText(course.getFirstName() + " " + course.getLastName());
        number.setText("." + (course.getNo() + 1));
      }

      public void setOnItemClickListener(CourseListener courseListener) {
        CourseListAdapter.clickListener = courseListener;
      }

      @Override
      public int getItemCount() {
        return courses.size();
      }

      public void setStatusVisiblity(int visibility) {
        status.setVisibility(visibility);
      }

      public void setAbsentVisiblity(int visibility) {
        status.setVisibility(visibility);
      }

      public void setPresentVisiblity(View view, int visibility) {
        ViewGroup viewGroup = (ViewGroup) view.getRootView();
        status = (TextView) viewGroup.findViewById(R.id.scoreStatus);
        status.setVisibility(visibility);
      }

      public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {


        public MyViewHolder(View view) {
          super(view);
          view.setOnClickListener(this);
          view.setOnLongClickListener(this);
          root = (ViewGroup) view;
          number = (TextView) view.findViewById(R.id.scoreListNo);
          name = (TextView) view.findViewById(R.id.scoreListName);
          status = (TextView) view.findViewById(R.id.scoreStatus);
          absent = (ImageView) view.findViewById(R.id.imgAbsent);
          present = (ImageView) view.findViewById(R.id.imgPresent);
          absent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              clickListener.onAbsentClick(getAdapterPosition(), v);
              if (v.getId() == absent.getId()) {
                TransitionManager.beginDelayedTransition((ViewGroup) v.getRootView());
                v.setVisibility(View.INVISIBLE);
                present.setVisibility(View.INVISIBLE);
                status.setText("غایب");
                status.setVisibility(View.VISIBLE);
              }
            }
          });
          present.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              clickListener.onPresentClick(getAdapterPosition(), v);

            }
          });
          addNote = (ImageView) view.findViewById(R.id.imgNoteAdd);
          name.setTypeface(Fonts.sansMobileBold);
          status.setTypeface(Fonts.sansMobileBold);
        }

        @Override
        public void onClick(View v) {
        }

        @Override
        public boolean onLongClick(View v) {
          return true;
        }
      }

    }

1 个答案:

答案 0 :(得分:0)

这仅仅是因为您没有在absent中为项目保存presentonBindViewHolder的状态。因此,每当您的项目视图被回收时,它将在您的项目列表中显示不正确的更改。

您可以使用SparseBooleanArray来保持状态。这里是示例:

public class CourseListAdapter extends RecyclerView.Adapter<CourseListAdapter.MyViewHolder> {

  List<CourseStruct> courses;

  // Holding all flags for present or absent
  SparseBooleanArray mPresentFlags;

  ...

  public CourseListAdapter(List<CourseStruct> courses, CourseListener listener) {
    this.courses = courses;
    this.clickListener = listener;

    // initialize flags.
    mPresentFlags = new SparseBooleanArray();
  }

  ...

  @Override
  public MyViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
     ...
  }

  @Override
  public void onBindViewHolder(final MyViewHolder holder, int position) {
    int itemPosition = holder.getAdapterPosition();
    CourseStruct course = courses.get(itemPosition);
    name.setText(course.getFirstName() + " " + course.getLastName());
    number.setText("." + (course.getNo() + 1));

    // SparseBooleanArray.get() will return false when we didn't save
    // value for the itemPosition key.
    boolean isPresent = mPresentFlags.get(itemPosition); 

    if(isPresent) {
       //TODO: set the view for present state.
    } else {
       // is absent
       TransitionManager.beginDelayedTransition((ViewGroup) v.getRootView());
       v.setVisibility(View.INVISIBLE);
       present.setVisibility(View.INVISIBLE);
       status.setText("غایب");
       status.setVisibility(View.VISIBLE);
    }
  }

  ...

  public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {


    public MyViewHolder(View view) {
      super(view);
      ...

      absent.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          clickListener.onAbsentClick(getAdapterPosition(), v);

          // is absent
          mPresentFlags.put(getAdapterPosition(), false);

          // you can call notifyItemChanged(getAdapterPosition())
          // to update the view.

        }
      });

      present.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          clickListener.onPresentClick(getAdapterPosition(), v);

          // is present
          mPresentFlags.put(getAdapterPosition(), true);

          // you can call notifyItemChanged(getAdapterPosition())
          // to update the view.
        }
      });

    }

    ...
  }

}