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