如何刷新Android listview?

如何刷新Android listview?,android,android-listview,refresh,Android,Android Listview,Refresh,如何在添加/删除动态数据后刷新AndroidListView?修改适配器中的数据后,调用适配器对象 可以在中查看有关如何/何时调用notifyDataSetChanged()的其他详细信息。如果您对ListView刷新仍不满意,可以查看此代码段,这是用于从DB加载ListView的,实际上您所要做的只是在执行任何CRUD操作后重新加载ListView 这不是编写代码的最佳方式,但它会根据您的意愿刷新ListView 如果你找到更好的解决方案,请分享 ....... ...... do your

如何在添加/删除动态数据后刷新Android
ListView

修改适配器中的数据后,调用
适配器对象


可以在中查看有关如何/何时调用
notifyDataSetChanged()
的其他详细信息。

如果您对ListView刷新仍不满意,可以查看此代码段,这是用于从DB加载ListView的,实际上您所要做的只是在执行任何CRUD操作后重新加载ListView 这不是编写代码的最佳方式,但它会根据您的意愿刷新ListView

如果你找到更好的解决方案,请分享

....... ...... do your CRUD Operations.. ...... ..... DBAdapter.open(); DBAdapter.insert_into_SingleList(); // Bring that DB_results and add it to list as its contents.... ls2.setAdapter(new ArrayAdapter(DynTABSample.this, android.R.layout.simple_list_item_1, DBAdapter.DB_ListView)); DBAdapter.close(); ....... ...... 做你的积垢手术。。 ...... ..... DBAdapter.open(); DBAdapter.insert_到_SingleList()中; //将该DB_结果作为其内容添加到列表中。。。。 ls2.设置适配器(新阵列适配器(DynTABSample.this、, android.R.layout.simple_list_item_1,DBAdapter.DB_ListView)); DBAdapter.close();
如果正在使用,请尝试调用游标对象。

我的listview的动态刷新出现了一些问题

在适配器上调用notifyDataSetChanged()

有关如何/何时调用notifyDataSetChanged()的其他详细信息可以在本Google I/O视频中查看

notifyDataSetChanged()在我的情况下无法正常工作[我从另一个类调用了notifyDataSetChanged]。就在这个例子中,我在正在运行的活动(线程)中编辑了ListView。这段视频给出了最后的提示

在我的第二节课上,我用

Runnable run = new Runnable(){
     public void run(){
         contactsActivity.update();
     }
};
contactsActivity.runOnUiThread(run);
从我的活动中访问更新()。此更新包括

myAdapter.notifyDataSetChanged();
告诉适配器刷新视图。 就我所能说的而言,它工作得很好。

您也可以使用这个:

myListView.invalidateViews();

从列表视图中删除数据后,必须调用
refreshDrawableState()
。 以下是一个例子:

final DatabaseHelper db = new DatabaseHelper (ActivityName.this);

db.open();

db.deleteContact(arg3);

mListView.refreshDrawableState();

db.close();
DatabaseHelper
类中的
deleteContact
方法将有点像

public boolean deleteContact(long rowId) {

   return db.delete(TABLE_NAME, BaseColumns._ID + "=" + rowId, null) > 0;

}
请忽略所有的
invalidate()
invalidateViews()
requestLayout()
。。。这个问题的答案。 正确的做法(幸运的是也被标记为正确答案)是

故障排除 如果调用
notifyDataSetChanged()
不起作用,所有布局方法也不会有帮助。相信我,
列表视图
已正确更新。如果无法找到差异,则需要检查适配器中的数据来自何处

如果这只是一个保存在内存中的集合,请在调用
notifyDataSetChanged()
之前检查是否确实从该集合中删除了该项或将其添加到该集合中

如果使用的是数据库或服务后端,则在调用
notifyDataSetChanged()
之前,必须调用该方法再次检索信息(或操作内存中的数据)

问题是,只有在数据集已更改的情况下,
notifyDataSetChanged
才起作用。因此,如果你没有发现正在发生的变化,那就是你要去看的地方。如果需要,调试

ArrayAdapter vs BaseAdapter 我确实发现使用适配器可以让您管理集合,就像使用BaseAdapter一样,效果更好。有些适配器(如ArrayAdapter)已经在管理自己的集合,因此很难找到合适的集合进行更新。在大多数情况下,这只是一个不必要的额外困难

界面线程 确实,这必须从UI线程调用。其他答案有关于如何实现这一点的例子。但是,只有当您从UI线程外部处理这些信息时,才需要这样做。它来自服务或非UI线程。在简单的情况下,您将通过单击按钮或其他活动/片段更新数据。因此仍然在UI线程中。没必要总是把那辆车开进去

快速示例项目 可在以下网址找到。只需在Android Studio(gradle)中克隆并打开该项目。该项目有一个维护活动,即使用所有随机数据构建一个
ListView
。可以使用“操作”菜单刷新此列表

我为这个示例ModelObject创建的适配器实现公开了数据集合

public class MyListAdapter extends BaseAdapter {

    /**
     * this is our own collection of data, can be anything we 
     * want it to be as long as we get the abstract methods 
     * implemented using this data and work on this data 
     * (see getter) you should be fine
     */
    private List<ModelObject> mData;

    /**
     * our ctor for this adapter, we'll accept all the things 
     * we need here
     *
     * @param mData
     */
    public MyListAdapter(final Context context, final List<ModelObject> mData) {
        this.mData = mData;
        this.mContext = context;
    }

    public List<ModelObject> getData() {
        return mData;
    }

    // implement all abstract methods here
}
公共类MyListAdapter扩展BaseAdapter{
/**
*这是我们自己收集的数据,可以是我们想要的任何东西
*只要我们有抽象的方法,我们就希望它存在
*使用此数据实现并处理此数据
*(见盖特)你应该没事的
*/
私有列表数据;
/**
*对于此适配器,我们将接受所有内容
*我们需要这里
*
*@param mData
*/
公共MyListAdapter(最终上下文、最终列表mData){
this.mData=mData;
this.mContext=上下文;
}
公共列表getData(){
返回mData;
}
//在这里实现所有抽象方法
}
来自main活动的代码

public class MainActivity extends Activity {

    private MyListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView list = (ListView) findViewById(R.id.list);

        // create some dummy data here
        List<ModelObject> objects = getRandomData();
        // and put it into an adapter for the list
        mAdapter = new MyListAdapter(this, objects);
        list.setAdapter(mAdapter);

        // mAdapter is available in the helper methods below and the 
        // data will be updated based on action menu interactions

        // you could also keep the reference to the android ListView 
        // object instead and use the {@link ListView#getAdapter()} 
        // method instead. However you would have to cast that adapter 
        // to your own instance every time
    }

    /**
     * helper to show what happens when all data is new
     */
    private void reloadAllData(){
        // get new modified random data
        List<ModelObject> objects = getRandomData();
        // update data in our adapter
        mAdapter.getData().clear();
        mAdapter.getData().addAll(objects);
        // fire the event
        mAdapter.notifyDataSetChanged();
    }

    /**
     * helper to show how only changing properties of data 
     * elements also works
     */
    private void scrambleChecked(){
        Random random = new Random();
        // update data in our adapter, iterate all objects and 
        // resetting the checked option
        for( ModelObject mo : mAdapter.getData()) {
            mo.setChecked(random.nextBoolean());
        }
        // fire the event
        mAdapter.notifyDataSetChanged();
    }
}
公共类MainActivity扩展活动{
私人Mylistapter mAdapter;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView列表=(ListView)findViewById(R.id.list);
//在这里创建一些虚拟数据
列表对象=getRandomData();
//并将其放入列表的适配器中
mAdapter=新的MyListAdapter(此为对象);
列表.setAdapter(mAdapter);
//mAdapter在下面的帮助器方法和
//数据将根据操作菜单交互进行更新
//您还可以保留对android ListView的引用
//对象,并使用{@link ListView#getAdapter()}
//方法。但是您必须强制转换该适配器
//每次都是你自己的例子
}
/**
*帮助器来显示发生了什么
@Override
public void onDestroy() {
    if (MainActivity.isInFront == true) {
        if (MainActivity.adapter != null) {
            MainActivity.adapter.notifyDataSetChanged();
        }

        MainActivity.listView.setAdapter(MainActivity.adapter);
    }
}    
private List<List<SomeNewArray>> arrayList;
List<SomeNewArray> array1= getArrayList(...);
List<SomeNewArray> array2= getArrayList(...);
arrayList.clear();
arrayList.add(array1);
arrayList.add(array2);
notifyDataSetChanged();
LinearLayout results = (LinearLayout)findViewById(R.id.results);
ListView lv = new ListView(this);
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
SimpleAdapter adapter = new SimpleAdapter( this, list, R.layout.directory_row, 
                new String[] { "name", "dept" }, new int[] { R.id.name, R.id.dept } );

for (...) { 
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", name);
    map.put("dept", dept);
    list.add(map);
}

lv.setAdapter(adapter);
results.removeAllViews();     
results.addView(lv);
runOnUiThread(run);
run = new Runnable() {
    public void run() {
        //reload content
        arraylist.clear();
        arraylist.addAll(db.readAll());
        adapter.notifyDataSetChanged();
        listview.invalidateViews();
        listview.refreshDrawableState();
    }
};
public class ResultGpRowAdapter extends ArrayAdapter<RaceResult> {

    Context context;
    int resource;
    List<RaceResult> data=null;

        public ResultGpRowAdapter(Context context, int resource, List<RaceResult> objects)           {
        super(context, resource, objects);

        this.context = context;
        this.resource = resource;
        this.data = objects;
    }

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

        ........
        }

        //my own method to populate data           
        public void myAddAll(List<RaceResult> items) {

        for (RaceResult item:items){
            super.add(item);
        }
    }
public class ResultsGp extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...........
    ...........
    ListView list = (ListView)findViewById(R.id.resultsGpList); 

    ResultGpRowAdapter adapter = new ResultGpRowAdapter(this,  R.layout.activity_result_gp_row, new ArrayList<RaceResult>()); //Empty data

   list.setAdapter(adapter);

   .... 
   ....
   ....
   //LOAD a ArrayList<RaceResult> with data

   ArrayList<RaceResult> data = new ArrayList<RaceResult>();
   data.add(new RaceResult(....));
   data.add(new RaceResult(....));
   .......

   adapter.myAddAll(data); //Your list will be udpdated!!!
if (mEventListView.getAdapter() == null) {
    EventLogAdapter eventLogAdapter = new EventLogAdapter(mContext, events);
    mEventListView.setAdapter(eventLogAdapter);
} else {
    ((EventLogAdapter)mEventListView.getAdapter()).refill(events);
}

public void refill(List<EventLog> events) {
    mEvents.clear();
    mEvents.addAll(events);
    notifyDataSetChanged();
}
public class Fragment01 extends android.support.v4.app.Fragment implements ...
{
    private ListView                listView;
    private ArrayAdapter<String>    arrayAdapter_string;

...

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    ...
    this.listView= (ListView) super.getActivity().findViewById(R.id.fragment01_listView);
    ...
    this.arrayAdapter_string= new ArrayAdapter<String>(super.getActivity(), R.layout.dispositivo_ble_item, R.id.fragment01_item_textView_titulo);
    this.listView.setAdapter(this.arrayAdapter_string);
}


@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
    ...
    super.getActivity().runOnUiThread(new RefreshListView(device));
}


private class RefreshListView implements Runnable
{
    private BluetoothDevice bluetoothDevice;

    public RefreshListView(BluetoothDevice bluetoothDevice)
    {
        this.bluetoothDevice= bluetoothDevice;
    }

    @Override
    public void run()
    {
        Fragment01.this.arrayAdapter_string.add(new String(bluetoothDevice.toString()));
        Fragment01.this.arrayAdapter_string.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();
}
}
/**
 * Notifies the attached observers that the underlying data has been changed
 * and any View reflecting the data set should refresh itself.
 */
    expandableAdapter = baseFragmentParent.setupEXLVAdapter();
    baseFragmentParent.setAdapter(expandableAdapter);
    expandableAdapter.notifyDataSetChanged(); 
myListView.setAdapter(new MyListAdapter(...));
  myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override public void onItemClick(AdapterView<?> parent, android.view.View view, int position, long id) {
           myArrayList.remove(position);
           myArrayAdapter.notifyDataSetChanged();
        }
    });
 override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)

       // some controls needed
        programList = usersDBHelper.readProgram(model.title!!)
        notesAdapter = DailyAdapter(this, programList)
        notesAdapter.notifyDataSetChanged()
        listview_act_daily.adapter = notesAdapter
    }
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
         }
    });
 //....
    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);