关于NotifyDataSetChanged

3
我一直在编写适配器并尝试使用notifydatasetchanged进行更新。但我面临的问题是,在成功更新适配器后,我可以在listview中看到更改已经生效,但当我从其他片段返回时,它会恢复为以前的数据状态。我听说适配器会重用与相同数据的转换视图,这就导致了问题,但我不知道如何解决。我已经搜索过答案,但找不到类似的内容,因为大多数答案都是关于声明一个新适配器的。 以下是我的代码部分:
1. 片段中的刷新方法
public void toggleRefreshInBackground(ArrayList<HashMap<String, Object>> list) {
    dialog_list.clear();
    dialog_list.addAll(list);
    adapter.update(list);
}

我的适配器中的getView()方法

public class DialogListAdapter extends BaseAdapter {
Context context;
private ImageLoader imageLoader;
private static LayoutInflater inflater;
private ArrayList<HashMap<String, Object>> member_list;
private ArrayList<HashMap<String, Object>> member_list2;
private SparseBooleanArray mSelectedItemsIds;
private ArrayList<Integer> selectedItemPosition;
//private static final int droidGreen = Color.parseColor("#A4C639");
//private BadgeView badge;
Resources res;
String sorting;

public DialogListAdapter(Context c,
                         ArrayList<HashMap<String, Object>>content, String temp_sorting) {

    inflater=(LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.context=c;
    this.member_list = content;

    this.member_list2 = new ArrayList<>();
    this.member_list2.addAll(this.member_list);

    res=c.getResources();

    this.sorting = temp_sorting;
    mSelectedItemsIds = new SparseBooleanArray();
    selectedItemPosition = new ArrayList<>();

}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return member_list.size();
}

@Override
public HashMap<String, Object> getItem(int position) {
    // TODO Auto-generated method stub
    return member_list.get(position);
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

public void update(ArrayList<HashMap<String,Object>> obj) {
    member_list2.clear();
    member_list2.addAll(obj);
    notifyDataSetChanged();
}

public final class DialogListItem{ // view holder
    public TextView read_count;
    public TextView nameView;
    public TextView numberView;
    public TextView statusView;
    public ImageView thumb_image;
    public TextView timeView;
    public TextView senderView;
    public ImageView tick;
    //public BadgeView badge;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    int index;

    if(sorting.equals("D")){
        index = member_list.size()-position-1;
    }else{
        index = position;
    }

    View row = convertView;
    DialogListItem dialogItem=null;
    String textbuff_time = null;
    String textbuff_mess = null;
    String textbuff_sender = null;
    if (convertView==null){
        row=inflater.inflate(R.layout.dialog_list_single, null);
        dialogItem=new DialogListItem();
        dialogItem.read_count=(TextView)row.findViewById(R.id.readcount);
        dialogItem.nameView=(TextView)row.findViewById(R.id.member_name);
        dialogItem.numberView=(TextView)row.findViewById(R.id.tab2number);
        dialogItem.statusView=(TextView)row.findViewById(R.id.tab2status);
        dialogItem.thumb_image=(ImageView)row.findViewById(R.id.tab2image);
        dialogItem.timeView=(TextView) row.findViewById(R.id.tab2date);
        dialogItem.senderView=(TextView) row.findViewById(R.id.tab2sender);
        dialogItem.tick = (ImageView) row.findViewById(R.id.tick);
        row.setTag(dialogItem);
    }
    else{
        dialogItem=(DialogListItem) row.getTag();
    }

    if (mSelectedItemsIds.get(position)) {
        row.setBackgroundColor(context.getResources().getColor(R.color.item_selected));
    } else {
        row.setBackgroundColor(context.getResources().getColor(R.color.item_unselected));
    }

    HashMap<String,Object>items;
    items=member_list.get(index);
    dialogItem.nameView.setText((String)items.get(DBhelper.MEMBER_NAME));
    dialogItem.nameView.setTypeface(null,Typeface.BOLD);
    dialogItem.nameView.setSingleLine(true);
    dialogItem.nameView.setMaxLines(1);
    dialogItem.nameView.setEms(13);
    dialogItem.nameView.setEllipsize(TruncateAt.END);
    dialogItem.numberView.setText((String)items.get(DBhelper.MEMBER_NUMBER));
    String textbuff=(String)items.get(DBhelper.MEMBER_LMESSAGE);
    if (!TextUtils.isEmpty(textbuff)){
        textbuff_time=textbuff.substring(0, 19);
        textbuff_mess=textbuff.substring(20);
        int bound=textbuff_mess.indexOf("½");
        if(bound!=-1){
            textbuff_sender=textbuff_mess.substring(0,bound);
            textbuff_mess=textbuff_mess.substring(bound+2);
        }
        else
            textbuff_sender="";

        dialogItem.statusView.setText(textbuff_mess);

        if (textbuff_sender.equals(context.getResources().getString(R.string.myself))) {
            dialogItem.senderView.setVisibility(View.GONE);
            dialogItem.tick.setVisibility(View.VISIBLE);
        } else {
            textbuff_sender = textbuff_sender + ": ";
            dialogItem.senderView.setVisibility(View.VISIBLE);
            dialogItem.senderView.setText(textbuff_sender);
            dialogItem.tick.setVisibility(View.GONE);
        }

        try {
            dialogItem.timeView.setText(Utility.relativeTime(row.getContext(), textbuff_time));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    else{
        dialogItem.statusView.setText("");
        dialogItem.senderView.setText("");
        dialogItem.timeView.setText("---");
    }

    dialogItem.statusView.setTextColor(Color.GRAY);
    dialogItem.statusView.setTypeface(null,Typeface.NORMAL);
    dialogItem.timeView.setTextColor(Color.GRAY);
    dialogItem.timeView.setTypeface(null,Typeface.NORMAL);
    dialogItem.senderView.setTextColor(Color.GRAY);
    dialogItem.senderView.setTypeface(null,Typeface.NORMAL);
    dialogItem.senderView.getPaint().setTextSkewX(-0.25f);

    String sformat=" "+String.valueOf(items.get(DBhelper.MEMBER_SIZE))+" ";
    dialogItem.read_count.setText(sformat);
    int badge_number=(Integer)items.get(DBhelper.MEMBER_SIZE);
    if(badge_number>0){

        dialogItem.read_count.setVisibility(View.VISIBLE);
        dialogItem.statusView.setTextColor(Color.BLACK);
        dialogItem.statusView.setTypeface(null,Typeface.BOLD);
        dialogItem.timeView.setTextColor(Color.BLACK);
        dialogItem.timeView.setTypeface(null,Typeface.BOLD);
        dialogItem.senderView.setTextColor(Color.BLACK);
        dialogItem.senderView.setTypeface(null,Typeface.BOLD);
        dialogItem.senderView.getPaint().setTextSkewX(-0.25f);
    }
    else{
        dialogItem.read_count.setVisibility(View.GONE);
    }

    StringBuffer link=new StringBuffer(Register.get_current_server_address());
    if(items.get(DBhelper.MEMBER_TYPE).equals(res.getString(R.string.broadcast_chat))){
        dialogItem.nameView.setTextColor(row.getResources().getColor(R.color.tab4_title));
        link.append("uniappSystemFile.asp");
        link.append("?file=").append("broadcast.png");
        //imageLoader.DisplayImage(link.toString(), dialogItem.thumb_image);
        Picasso.with(context).load(link.toString()).transform(new CircleTransform()).resize(200,200).into(dialogItem.thumb_image);
        dialogItem.read_count.setVisibility(View.GONE); // disable broadcast badge
    }
            Picasso.with(context).load(R.drawable.ic_contact).resize(200,200).into(dialogItem.thumb_image);
            Picasso.with(context).load(R.drawable.ic_notif).resize(200, 200).into(dialogItem.thumb_image);
        }else{
            link2 = new IMService(context.getApplicationContext()).group_image_thumb_get(tab2.myphone, (String) items.get(DBhelper.MEMBER_NUMBER));
            dialogItem.nameView.setTextColor(row.getResources().getColor(R.color.tab3_title));
            //imageLoader.DisplayImage(link2, dialogItem.thumb_image);
            Picasso.with(context).load(link2).transform(new CircleTransform()).resize(200, 200).placeholder(R.drawable.ic_group_circle_black_48dp).error(R.drawable.ic_group_circle_black_48dp).into(dialogItem.thumb_image);
        }
    }

public void setSearchPattern(String pattern) {
    filterListByPattern(pattern.trim());
    this.notifyDataSetChanged();
}

private void filterListByPattern(String searchPattern) {

    member_list.clear();
    for (HashMap<String,Object> info : member_list2) {
        boolean add = true;
        do {
            if (searchPattern == null || searchPattern.equals("")) {
                break;
            }
            if (info.get(DBhelper.MEMBER_NAME).toString().toLowerCase().contains(searchPattern)) {
                break;
            }
            add = false;
        } while (false);
        if (add) {
            member_list.add(info);
        }
    }
}

public void resetList() {
    this.member_list2 = new ArrayList<HashMap<String,Object>>();
    this.member_list2.addAll(this.member_list);
    this.notifyDataSetChanged();
}

public void remove(Object object) {
    member_list.remove(object);
    notifyDataSetChanged();
}

public void toggleSelection(int position) {
    selectView(position, !mSelectedItemsIds.get(position));
}

public void removeSelection() {
    mSelectedItemsIds = new SparseBooleanArray();
    selectedItemPosition = new ArrayList<>();
    notifyDataSetChanged();
}

public void selectView(int position, boolean value) {
    if (value) {
        mSelectedItemsIds.put(position, value);
        selectedItemPosition.add(position);
    } else {
        mSelectedItemsIds.delete(position);
        selectedItemPosition.remove(selectedItemPosition.indexOf(position));
    }
    notifyDataSetChanged();
}

public int getSelectedCount() {
    return mSelectedItemsIds.size();
}

public SparseBooleanArray getSelectedIds() {
    return mSelectedItemsIds;
}

public ArrayList<Integer> getItemPosition() {
    return selectedItemPosition;
}

因此,我的问题是为什么当我从其他片段返回到这个片段时,我的适配器和列表视图会显示旧数据,以及如何解决这个问题?

附言:请不要告诉我要像这样声明一个新适配器

adapter = new MyAdapter(list);
adapter.notifyDataSetChanged();

我知道它起作用,但这不是一个好的、适当的方法,因为它是一个繁重的操作,而且在声明新适配器后你甚至不需要使用notifyDataSetChanged。

非常感谢。


为什么不尝试使用 RecyclerView 而不是 ListView 呢? - Sharath kumar
@Anonymous 但是RecyclerView和ListView有什么区别?我仍然需要一个适配器并对其进行更改。 - Harris.C
@匿名 我现在离开了。我将在半个小时后发布整个适配器。 - Harris.C
@Harris.C https://dev59.com/_V8d5IYBdhLWcg3wiSfI#29078116 - IntelliJ Amiya
你是从popBackStack返回还是重新创建的? - Exigente05
显示剩余2条评论
1个回答

0

尝试将setRetainInstance(true);放在您的片段中。

如果上述方法不起作用,请尝试以下方法:onSaveInstanceState() -

在顶部声明,Parcelable state;

保存listview状态,state = listview.onSaveInstanceState(); 在片段的onpause()中或手动更改片段时。 然后在onCreateView中检查state是否为空。如果为空,则设置适配器/获取数据;如果不为空,则设置。

listview.onRestoreInstanceState(state);

另一方面,每次加载片段时,ArrayList 将从空开始。因此,您需要小心保存数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接