如何刷新一个Android列表视图后添加/删除动态数据?


当前回答

您需要使用该列表的单个对象,您要在ListView中扩展该对象的数据。如果reference是change,那么notifyDataSetChanged()不起作用。无论何时你从列表视图中删除元素,也要从你正在使用的列表中删除它们,无论它是ArrayList<>还是其他什么,然后调用 你的适配器类对象上的notifyDataSetChanged()。

所以这里看看我如何管理它在我的适配器见下面

public class CountryCodeListAdapter extends BaseAdapter implements OnItemClickListener{

private Context context;
private ArrayList<CountryDataObject> dObj;
private ViewHolder holder;
private Typeface itemFont;
private int selectedPosition=-1;
private ArrayList<CountryDataObject> completeList;

public CountryCodeListAdapter(Context context, ArrayList<CountryDataObject> dObj) {
    this.context = context;
    this.dObj=dObj;
    completeList=new  ArrayList<CountryDataObject>();
    completeList.addAll(dObj);
    itemFont=Typeface.createFromAsset(context.getAssets(), "CaviarDreams.ttf");
}

@Override
public int getCount() {
    return dObj.size();
}

@Override
public Object getItem(int position) {
    return dObj.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
    if(view==null){
        holder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.states_inflator_layout, null);
        holder.textView = ((TextView)view.findViewById(R.id.stateNameInflator));
        holder.checkImg=(ImageView)view.findViewById(R.id.checkBoxState);
        view.setTag(holder);
    }else{
        holder = (ViewHolder) view.getTag();
    }
    holder.textView.setText(dObj.get(position).getCountryName());
    holder.textView.setTypeface(itemFont);

    if(position==selectedPosition)
     {
         holder.checkImg.setImageResource(R.drawable.check);
     }
     else
     {
         holder.checkImg.setImageResource(R.drawable.uncheck);
     }
    return view;
}
private class ViewHolder{
    private TextView textView;
    private ImageView checkImg;
}

public void getFilter(String name) {
    dObj.clear();
    if(!name.equals("")){
    for (CountryDataObject item : completeList) {
        if(item.getCountryName().toLowerCase().startsWith(name.toLowerCase(),0)){
            dObj.add(item);
        }
    }
    }
    else {
        dObj.addAll(completeList);
    }
    selectedPosition=-1;
    notifyDataSetChanged();
    notifyDataSetInvalidated(); 
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    Registration reg=(Registration)context;
    selectedPosition=position;
    reg.setSelectedCountryCode("+"+dObj.get(position).getCountryCode());
    notifyDataSetChanged();
}
}

其他回答

在“dataArray”中添加/删除动态数据后:

如果你使用ArrayAdapter

adapter.notifyDataSetChanged();

如果你使用了扩展ArrayAdapter的customAdapter

adapter.clear();
adapter.addAll(dataArray);
adapter.notifyDataSetChanged();

如果你使用一个扩展BaseAdapter的customAdapter

adapter.clear();
adapter.getData().addAll(dataArray);
adapter.getData().notifyDataSetChanged();

如果你想从一个服务中更新UI listview,那么在你的Main活动中使适配器静态,并这样做:

@Override
public void onDestroy() {
    if (MainActivity.isInFront == true) {
        if (MainActivity.adapter != null) {
            MainActivity.adapter.notifyDataSetChanged();
        }

        MainActivity.listView.setAdapter(MainActivity.adapter);
    }
}    

我认为这取决于你对刷新的定义。您的意思是应该刷新GUI显示,还是应该刷新子视图,以便您可以通过编程调用getChildAt(int)并获得与适配器中内容对应的视图?

如果希望刷新GUI显示,则调用适配器上的notifyDataSetChanged()。下次重绘时,GUI将被刷新。

如果您希望能够调用getChildAt(int)并获得反映适配器中的内容的视图,则调用layoutChildren()。这将导致从适配器数据重构子视图。

如果我在这里谈论我的场景,上面的答案都不会起作用,因为我有一个显示db值列表的活动,同时还有一个删除按钮,当按下删除按钮时,我想从列表中删除该项。

最酷的是,我没有使用回收器视图,而是使用了一个简单的列表视图,该列表视图在适配器类中初始化。因此,调用notifyDataSetChanged()不会在适配器类内部执行任何操作,甚至不会在初始化了适配器对象的活动类中执行任何操作,因为delete方法位于适配器类中。

因此,解决方案是在适配器类getView方法中从适配器中删除对象(仅删除特定对象,但如果您想删除所有对象,则调用clear())。

为了让你们了解我的代码是什么样的,

public class WordAdapter extends ArrayAdapter<Word> {
  Context context;

  public WordAdapter(Activity context, ArrayList<Word> words) {}
    //.......

    @NonNull
    @Override
    public View getView(final int position, View convertView, ViewGroup group) {
      //.......
     ImageButton deleteBt = listItemView.findViewById(R.id.word_delete_bt);
     deleteBt.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             if (vocabDb.deleteWord(currentWord.id)) {
                //.....
             } else{
                //.....
             }
             remove(getItem(position)); // <---- here is the trick ---<
             //clear() // if you want to clear everything
         }
    });
 //....

注意:这里remove()和getItem()方法继承自Adapter类。

Remove() -删除所单击的特定项 getItem(position) -用于获取项目(在这里,这是我的Word对象 我已经添加到列表)从点击的位置。

这就是我如何在活动类中将适配器设置为listview,

    ArrayList<Word> wordList = new ArrayList();
    WordAdapter adapter = new WordAdapter(this, wordList);

    ListView list_view = (ListView) findViewById(R.id.activity_view_words);
    list_view.setAdapter(adapter);

如果您正在使用SimpleCursorAdapter,请尝试在Cursor对象上调用requery()。