android - 关于 NotifyDataSetChanged

标签 android listview android-fragments android-adapter

我一直在研究适配器并尝试使用 notifydatasetchanged 更新它。但我面临的问题是,在我成功更新适配器后,我可以在 ListView 中看到所做的更改,然后它会在我从其他 fragment 返回后变回以前的数据。我听说适配器将使用导致问题的相同数据重用转换 View ,但我不知道如何解决这个问题。我已经搜索了答案,但找不到任何类似的东西,因为大多数答案都是关于声明新适配器的。 以下是我的部分代码:

1.fragment中的refresh方法

public void toggleRefreshInBackground(ArrayList<HashMap<String, Object>> list) {
    dialog_list.clear();
    dialog_list.addAll(list);
    adapter.update(list);
}

2.我的适配器的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;
}

所以,我的问题是为什么我的适配器和 ListView 在我从其他 fragment 返回到这个 fragment 后会显示旧数据,以及如何解决这个问题?

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

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

我知道它有效,但这不是一个好的和合适的方法,因为它是一项繁重的操作,您甚至不需要在声明新适配器后使用 notifyDataSetChanged。

非常感谢

最佳答案

尝试放置 setRetainInstance(true); 在你的 fragment 中。

如果上述方法不起作用,请尝试使用 onSaveInstanceState(),如下所示 -

在顶部声明,Parcelable状态;

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

listview.onRestoreInstanceState(state);

另一方面,每次加载 fragment 时,ArrayList 都会从空开始。所以你需要小心保存数据。

关于android - 关于 NotifyDataSetChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46108849/

相关文章:

Android:调用相机 Intent 后 Activity 被破坏

android - 通过 Intent 传递纬度/经度

javascript - 无法查看列表的最后一项

java - 将 fragment 添加到 Activity 中

java - 使用 ViewPager 将 RecyclerView 添加到 Tabs fragment

android - 在 fragment 中点击OptionsMenu项时不需要的导航

android - 如何像 float 按钮一样在 Snackbar 上方移动 View

android - Google Gson 2.4 minifyEnable 真正的问题

java - 如何在cordova插件中拥有多个java文件

android - 在 Flutter 的垂直列表中添加动态高度水平 ListView