RecyclerView的适配器在更改阵列后不会更新数据

问题描述

我有一个抽象类“ ListItem”,带有两个子类-“ Header”(Data)和“ Event”。根据情况,该数组应显示为“标题”-“此数据的事件”,或仅显示为事件。 创建的“事件”类的对象从单独的活动传递到主片段。如果只需要显示事件,则只需将其写入数组并更新适配器数据即可。如果在创建类对象之后,我需要以“标题”-“事件”的形式显示它和现有事件,则由于某种原因适配器不会更新,因此不会显示新事件。如果您关闭应用程序并重新打开它,该事件将以正常形式显示,并带有标题

这是我的RV适配器

public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;
private static final String TAG = "myLogs";

private ArrayList<ListItem> list;


final SparseBooleanArray selectedItems = new SparseBooleanArray();
private int currentSelectedPos;

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM",myDateFormatSymbols);

public EventAdapter(ArrayList<ListItem> items){
    list = items;
}


public ArrayList<ListItem> getItems(){
    return list;
}

private EventAdapterListener itemClickListener;

public interface EventAdapterListener {
    void onItemClick(int position);
    void onItemLongClick(int position);
}

public void setListener(EventAdapterListener listener){
        itemClickListener = listener;
}


private OnItemCheckedListener OnItemChecked;
public interface OnItemCheckedListener {
    void onItemChecked(int position,boolean isImportant);
}

public void setonItemCheckedListener (OnItemCheckedListener listener){
    OnItemChecked = listener;
}


public static class EventViewHolder extends RecyclerView.ViewHolder{
   public TextView TVtitle;
   public TextView TVcomment;
   public CheckBox CBimportance;
   public TextView TVdate;


   //public EventViewHolder(@NonNull View itemView,final EventAdapterListener listener) {
   public EventViewHolder(@NonNull View itemView) {
       super(itemView);
   }
}

public void removeAllObjectsOf(Class<? extends ListItem> cls) {
    Iterator itr = list.iterator();
    while (itr.hasNext()) {
        if (itr.next().getClass().equals(cls)) {
            itr.remove();
        }
    }
    notifyDataSetChanged();
}

Comparator<ListItem> dateComparator = new Comparator<ListItem>() {
    @Override
    public int compare(ListItem event,ListItem t1) {
        return ((Event)(event)).Date.compareto(((Event)t1).Date);
    }
};

Comparator<ListItem> importanceComparator = new Comparator<ListItem>() {
    @Override
    public int compare(ListItem event,ListItem t1) {
        return ((Event)(event)).IsImportant.compareto(((Event)t1).IsImportant);
    }
};

Comparator<ListItem> nameComparator = new Comparator<ListItem>() {
    @Override
    public int compare(ListItem event,ListItem t1) {
        return ((Event)(event)).Name.compareto(((Event)t1).Name);
    }
};

Comparator<ListItem> completenessComparator = new Comparator<ListItem>() {
    @Override
    public int compare(ListItem event,ListItem t1) {
        return ((Event)(event)).IsComplete.compareto(((Event)t1).IsComplete);
    }
};

public void sortBy(Comparator<ListItem> comparator,ArrayList<ListItem> list) {
    removeAllObjectsOf(Header.class);
    Collections.sort(list,comparator);
}


public void groupByDate()
{

    ArrayList<ListItem> result = new ArrayList<>();

    removeAllObjectsOf(Header.class);
    sortBy(dateComparator,list);
    ArrayList<Long> dates = new ArrayList<>();
    for (ListItem event: list)
    {
        if (!(dates.contains(((Event)event).getDate())))
        {
            dates.add(((Event)event).getDate());
            ArrayList<ListItem> ei = getItemsbyDate(list,((Event)event).getDate());
            Header header = new Header();
            header.setHeader(String.valueOf(((Event)event).getDate()));
            result.add(header);
            result.addAll(ei);
        }
    }

    list = result;
    notifyDataSetChanged();
}

public ArrayList<ListItem> getItemsbyDate(ArrayList<ListItem> items,Long date){
    ArrayList<ListItem> result = new ArrayList<>();

    for (ListItem ci : items){
        if (((Event)ci).getDate().equals(date)){
            result.add(ci);
        }
    }

    return result;
}

public void removeItem(int position) {
    list.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position,list.size());
}

@Override
public int getItemViewType(int position) {
    if (isPositionHeader(position))
        return TYPE_HEADER;
    return TYPE_ITEM;
}

private boolean isPositionHeader(int position) {
    return list.get(position) instanceof Header;
}

private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){

    @Override
    public String[] getMonths() {
        return new String[]{"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"};
    }

};


@NonNull
@Override
public EventViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) { 
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    if (viewType == TYPE_HEADER){
        View v = inflater.inflate(R.layout.group_layout,parent,false);
        return new VHHeader(v);
    } else {
        View v = inflater.inflate(R.layout.list_item_cardview,false);
        return new VHItem(v);
    }
}

@Override
public void onBindViewHolder(@NonNull EventViewHolder holder,final int position)
{
    if (holder instanceof VHHeader){
        Header currentItem = (Header) list.get(position);
        VHHeader VHheader = (VHHeader) holder;
        VHheader.txtTitle.setText(simpleDateFormat.format(Long.parseLong(currentItem.getHeader())));
    } else if (holder instanceof VHItem) {
        final Event event = (Event) list.get(position);
        VHItem VHitem = (VHItem) holder;
        VHitem.txtName.setText(event.getName());
        VHitem.txtDate.setText(simpleDateFormat.format(event.getDate()));
        VHitem.TVcomment.setText(event.getComment());

        VHitem.CBimportance.setonCheckedchangelistener(null);

        VHitem.CBimportance.setChecked(event.getImportant());

        VHitem.CBimportance.setonCheckedchangelistener(new CompoundButton.OnCheckedchangelistener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton,boolean b) {
                event.IsImportant = b;
                OnItemChecked.onItemChecked(position,b);
            }
        });


        VHitem.itemView.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (selectedItems.size() > 0 && itemClickListener != null){
                    itemClickListener.onItemClick(position);
                }
            }
        });

        VHitem.itemView.setonLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                if (itemClickListener != null){
                    itemClickListener.onItemLongClick(position);
                }
                return true;
            }
        });

        if (currentSelectedPos == position) currentSelectedPos = -1;
    }
}

@Override
public int getItemCount() {
    return (list == null) ? 0 : list.size();
}

void deleteEvents(){
    List<ListItem> selectedEvents = new ArrayList<>();
    for (ListItem item : list){
        if (item instanceof Event){
            if (((Event) item).getSelected()){
                selectedEvents.add(item);
            }
        }

    }

    list.removeAll(selectedEvents);

    //notifyDataSetChanged();
    currentSelectedPos = -1;

    deleteEmptyHeaders();

}


public int getCountofheaderItems(Header header)
{
    int k = 0;
    for (ListItem item: list)
    {
        if (item instanceof Event){
            if (((Event) item).Date.equals(Long.parseLong(header.getHeader()))){
                k++;
            }
        }
    }
    return k;
}

void deleteEmptyHeaders(){
    List<Header> headers = new ArrayList<>();
    for (ListItem event : list){
        if (event instanceof Header){
            if (getCountofheaderItems((Header)event) == 0){
                headers.add((Header)event);
            }
        }
    }
    list.removeAll(headers);
}

void toggleSelection(int position) {
    if (getItemViewType(position) == TYPE_ITEM){
        currentSelectedPos = position;
        if (selectedItems.get(position)) {
            selectedItems.delete(position);
            ((Event)list.get(position)).setSelected(false);
        } else {
            selectedItems.put(position,true);
            ((Event)list.get(position)).setSelected(true);
        }
        notifyItemChanged(position);
    }

}


class VHHeader extends EventAdapter.EventViewHolder {
    TextView txtTitle;

    public VHHeader(View itemView) {
        super(itemView);
        this.txtTitle = (TextView) itemView.findViewById(R.id.tvTitleGroup);
    }
}

class VHItem extends EventAdapter.EventViewHolder {
    TextView txtName;
    TextView txtDate;
    TextView TVcomment;
    CheckBox CBimportance;
    public VHItem(View itemView) {
        super(itemView);
        this.txtName = (TextView) itemView.findViewById(R.id.tvTitle);
        this.txtDate = (TextView) itemView.findViewById(R.id.tvDate);
        this.TVcomment = (TextView) itemView.findViewById(R.id.tvComment);
        this.CBimportance = (CheckBox) itemView.findViewById(R.id.cbIconImportant);
    }
}

}

这是我的MainFragment:

private final static String ONLY_EVENTS = "ONLY_EVENTS";
private final static String GROUP_EVENTS_BY_DATE = "GROUP_EVENTS_BY_DATE";
ArrayList<ListItem> events;
private String ShowMode = ONLY_EVENTS;
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_first_new,container,false);

    events = read(this.getActivity(),PROCESSED_EVENTS);
    if (events == null)
        events = new ArrayList<ListItem>();



    rvEvent = view.findViewById(R.id.recyclerview);
    rvEvent.setHasFixedSize(true);
    lmEvent = new linearlayoutmanager(this.getContext());
    adapterEvent = new EventAdapter(events);

    rvEvent.setLayoutManager(lmEvent);

    rvEvent.setAdapter(adapterEvent);

    ShowEvents(ShowMode);
    initSwipe();
    

 

    return view;
}

public void ShowEvents(String mode){
    switch (mode){
        case ONLY_EVENTS:
            adapterEvent.removeAllObjectsOf(Header.class);
            break;
        case GROUP_EVENTS_BY_DATE:
             adapterEvent.groupByDate();
            break;

    }
}
    public void onActivityResult(int requestCode,int resultCode,@Nullable Intent data) {
    super.onActivityResult(requestCode,resultCode,data);
    if (resultCode == Activity.RESULT_OK && requestCode == 1) {
        Event nd = (Event) data.getSerializableExtra("class");

        events.add(nd);

        write(this.getActivity(),events,PROCESSED_EVENTS);

        if (ShowMode.equals(GROUP_EVENTS_BY_DATE))
            adapterEvent.groupByDate();

        adapterEvent.notifyDataSetChanged();
    }
}


public static void write(Context context,ArrayList<ListItem> events,String Key) {
    Gson gson = new Gson();
    String jsonString = gson.toJson(events);
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = pref.edit();

    editor.putString(Key,jsonString);
    editor.apply();
}

public static ArrayList<ListItem> read(Context context,String Key) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
    String jsonString = pref.getString(Key,"");

    Gson gson = new Gson();
    Type type = new Typetoken<ArrayList<Event>>() {
    }.getType();
    ArrayList<ListItem> list = gson.fromJson(jsonString,type);
    return list;
}

这是从活动发送事件的方式:

Intent intent = new Intent(NewEvent.this,FirstFragment.class);
                    //intent.putExtra("name",(String) etName.getText().toString());
                    objectEvent = new Event(etName.getText().toString(),date,etComment.getText().toString(),etType.getText().toString(),etNotif.getText().toString(),swIsComplete.isChecked(),false);
                    intent.putExtra("class",objectEvent);
                    setResult(RESULT_OK,intent);
                    finish();

UPD。在执行行OnActivityResult之后的adapterEvent.groupByDate();中,没有任何变化。更改在适配器中的数组list中进行,但是由于某些原因,更改不会进入片段中使用的数组。在ShowEvents过程中,同一行代码起作用,然后更改数组。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)