Q:

Event Listener inside ListView with ViewHolder pattern trigger wrong item

I'm creating a ListView with my CustomAdapter. Each of the ListView's row have a toggle button which I used from this library. So here's my adapter code
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    Attendance attendance = getItem(position);

    if(convertView==null){
        convertView = LayoutInflater.from(context).inflate(R.layout.student_attendance_list_model,parent,false);
        holder = new ViewHolder();
        holder.studentName = (TextView)convertView.findViewById(R.id.student_name);
        holder.studentSchool = (TextView)convertView.findViewById(R.id.student_school);
        holder.bulletIcon = (ImageView) convertView.findViewById(R.id.bullet_img);
        holder.toggleButton = (TriStateToggleButton) convertView.findViewById(R.id.tri_state_toggle);
        holder.yesText = (TextView)convertView.findViewById(R.id.yes_btn);
        holder.noText = (TextView)convertView.findViewById(R.id.no_btn);
        holder.toggleButton.setOnToggleChanged(new TriStateToggleButton.OnToggleChanged() {
            @Override
            public void onToggle(TriStateToggleButton.ToggleStatus toggleStatus, boolean b) {
                switch (toggleStatus){
                    case off:
                        holder.yesText.setTextColor(context.getResources().getColor(R.color.green));
                        holder.noText.setTextColor(context.getResources().getColor(R.color.black_text));
                        break;
                    case mid:
                        holder.noText.setTextColor(context.getResources().getColor(R.color.black_text));
                        holder.yesText.setTextColor(context.getResources().getColor(R.color.black_text));
                        break;
                    case on:
                        holder.noText.setTextColor(context.getResources().getColor(R.color.trial_color));
                        holder.yesText.setTextColor(context.getResources().getColor(R.color.black_text));
                        break;
                }
            }
        });
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder)convertView.getTag();
    }
    holder.toggleButton.setOnToggleChanged(new TriStateToggleButton.OnToggleChanged() {
        @Override
        public void onToggle(TriStateToggleButton.ToggleStatus toggleStatus, boolean b) {
            LogHelper.debug(getClass(),"pos = "+position);
            switch (toggleStatus){
                case off:
                    holder.yesText.setTextColor(context.getResources().getColor(R.color.green));
                    holder.noText.setTextColor(context.getResources().getColor(R.color.black_text));
                    break;
                case mid:
                    holder.noText.setTextColor(context.getResources().getColor(R.color.black_text));
                    holder.yesText.setTextColor(context.getResources().getColor(R.color.black_text));
                    break;
                case on:
                    holder.noText.setTextColor(context.getResources().getColor(R.color.trial_color));
                    holder.yesText.setTextColor(context.getResources().getColor(R.color.black_text));
                    break;
            }
        }
    });

    holder.studentName.setText(attendance.getUserInformation().getFullName());
    holder.studentSchool.setText(attendance.getUserInformation().getSchool());
    try {
        switch (attendance.getUserInformation().getStatus()) {
            case ("enroll"):
                holder.bulletIcon.setImageResource(R.drawable.enrollment_circle);
                break;
            case ("transfer"):
                holder.bulletIcon.setImageResource(R.drawable.transfer_circle);
                break;
            case ("trial"):
                holder.bulletIcon.setImageResource(R.drawable.trial_circle);
                break;
            case ("replace"):
                holder.bulletIcon.setImageResource(R.drawable.replacement_circle);
                break;
        }
    }catch (Exception e){e.printStackTrace();}

    switch (attendance.getAttend()){
        case ("true"):
            holder.yesText.setTextColor(context.getResources().getColor(R.color.green));
            holder.noText.setTextColor(context.getResources().getColor(R.color.black_text));
            holder.toggleButton.setToggleOff();
            break;
        case ("false"):
            holder.noText.setTextColor(context.getResources().getColor(R.color.trial_color));
            holder.yesText.setTextColor(context.getResources().getColor(R.color.black_text));
            holder.toggleButton.setToggleOn();
            break;
        default:
            //holder.toggleButton.setMidColor(context.getResources().getColor(R.color.grey_87));
            holder.toggleButton.setToggleMid();
            holder.noText.setTextColor(context.getResources().getColor(R.color.black_text));
            holder.yesText.setTextColor(context.getResources().getColor(R.color.black_text));
            break;
    }
    return convertView;
}

class ViewHolder {
    TextView studentName;
    TextView studentSchool;
    ImageView bulletIcon;
    TriStateToggleButton toggleButton;
    TextView yesText;
    TextView noText;

}

When I change the toggle state it returns the correct row's position, but its yesText and noText is not changing color. Instead the yesText and noText in the last item is triggered to change its color every time I clicked on any toggle.
Button onClick get wrong position in viewholder patterned listview 
link above have quite the same problem as mine, but I don't understand about the implementation of notifyDataSetChanged() in my case.
Thanks

A:

Remove code to set text color from switch block in toggleChangeListener and instead update object at that position with "true","false" and default value and after it just call notifyDataSetChanged

