我的 ListView 只有在我点击它后才会更新
My ListView only updates after I click on it
我打电话
adapter.notifyDataSetChanged();
但直到我单击列表视图滚动它,然后列表视图更新,才会发生任何事情。我想让它自动更新..我该怎么办?
我试过这个answer但是对我没用
Obs:我正在使用自定义阵列适配器。它是一个聊天应用程序,需要自动更新其在线用户。
以下是我使用调用 AsyncTask 的按钮声明适配器和数组适配器 (onCreate) 的方式,我在 AsyncTask 内部调用 notifyDataSetChanged 但在 onPostExecute
:
peopleList = (ListView) findViewById(R.id.peopleList);
adapter = new MyAdapter(this, people);
peopleList.setAdapter(adapter);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ConnectAndLoad(MainActivity.this).execute();
}
});
这是我的适配器:
public class PeopleAdapter extends ArrayAdapter<People> {
private ArrayList<People> events_list = new ArrayList<>();
Context context;
public PeopleAdapter(Context context, ArrayList<People> users) {
super(context, 0, users);
this.context = context;
this.events_list = users;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
People user = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.people_list, parent, false);
}
TextView tvName = (TextView) convertView.findViewById(R.id.name);
TextView tvStatus = (TextView) convertView.findViewById(R.id.status);
tvName.setText(user.name);
tvStatus.setText(user.status);
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "You Clicked " + events_list.get(position).name, Toast.LENGTH_SHORT).show();
Intent i = new Intent(context, ConversationActivity.class);
i.putExtra("user", events_list.get(position).name);
context.startActivity(i);
}
});
return convertView;
}
}
最后是调用 notifyDataSetChanged 的 AsyncTask 的 onPostExecute,每次用户的状态发生变化时,它应该将新用户添加到人员列表,然后调用 notifyDataSetChanged(它将新人员添加到列表并它实际上改变了数据集,唯一的问题是我只有在单击列表视图后才能看到更新的列表!):
protected void onPostExecute(Boolean boo) {
roster.addRosterListener(new RosterListener() {
public void entriesDeleted(Collection<String> addresses) {
}
public void entriesUpdated(Collection<String> addresses) {
}
public void entriesAdded(Collection<String> addresses) {
}
@Override
public void presenceChanged(Presence presence) {
people.add(new People(presence.getFrom(), presence.getStatus()));
adapter.notifyDataSetChanged();
}
});
dialog.dismiss();
}
EDIT:我按照@savepopulation 所说的进行操作,将 adapter.notifyDataSetChanged();
从 presenceChanged 中移除,它起作用了。但我需要将它放在 presenceChanged 中,以便在用户在线和离线时更新。如果你们有任何建议,请告诉我:)
我们开始吧。
首先,当您调用 adapter.notifyDataSetChanged();
ListView
或 RecyclerView
时,如果您的数据发生变化或您的某些方法(例如 onClick
或 onItemClickListene
r仅在您单击视图或滚动视图后才有效,这意味着某些东西正在阻止您的 UiThread,并且您的 UiThread 在您中断后会被解除阻止。
这可能是由您的通知电话引起的。您正在尝试在之前的通知操作完成之前通知您的适配器。我认为这会导致您的问题。
我不知道是否有其他有效的方法来实现您要实现的目标,但如果您必须在 presenceChanged
方法中通知,只需通知项目哪个数据已更改。
您可以使用RecyclerView
代替ListView
并使用notifyItemChanged
方法。只需通知更改的项目。不要通知整个列表。这可以解决您的问题。您也可以从 onPresenceChanged
方法中获取通知方法。这解决了您的问题,但不适合您的业务。
如果通知单个更改的项目对您不起作用,您可能需要更改您的实现。
祝你好运。
我打电话
adapter.notifyDataSetChanged();
但直到我单击列表视图滚动它,然后列表视图更新,才会发生任何事情。我想让它自动更新..我该怎么办?
我试过这个answer但是对我没用
Obs:我正在使用自定义阵列适配器。它是一个聊天应用程序,需要自动更新其在线用户。
以下是我使用调用 AsyncTask 的按钮声明适配器和数组适配器 (onCreate) 的方式,我在 AsyncTask 内部调用 notifyDataSetChanged 但在 onPostExecute
:
peopleList = (ListView) findViewById(R.id.peopleList);
adapter = new MyAdapter(this, people);
peopleList.setAdapter(adapter);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ConnectAndLoad(MainActivity.this).execute();
}
});
这是我的适配器:
public class PeopleAdapter extends ArrayAdapter<People> {
private ArrayList<People> events_list = new ArrayList<>();
Context context;
public PeopleAdapter(Context context, ArrayList<People> users) {
super(context, 0, users);
this.context = context;
this.events_list = users;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
People user = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.people_list, parent, false);
}
TextView tvName = (TextView) convertView.findViewById(R.id.name);
TextView tvStatus = (TextView) convertView.findViewById(R.id.status);
tvName.setText(user.name);
tvStatus.setText(user.status);
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "You Clicked " + events_list.get(position).name, Toast.LENGTH_SHORT).show();
Intent i = new Intent(context, ConversationActivity.class);
i.putExtra("user", events_list.get(position).name);
context.startActivity(i);
}
});
return convertView;
}
}
最后是调用 notifyDataSetChanged 的 AsyncTask 的 onPostExecute,每次用户的状态发生变化时,它应该将新用户添加到人员列表,然后调用 notifyDataSetChanged(它将新人员添加到列表并它实际上改变了数据集,唯一的问题是我只有在单击列表视图后才能看到更新的列表!):
protected void onPostExecute(Boolean boo) {
roster.addRosterListener(new RosterListener() {
public void entriesDeleted(Collection<String> addresses) {
}
public void entriesUpdated(Collection<String> addresses) {
}
public void entriesAdded(Collection<String> addresses) {
}
@Override
public void presenceChanged(Presence presence) {
people.add(new People(presence.getFrom(), presence.getStatus()));
adapter.notifyDataSetChanged();
}
});
dialog.dismiss();
}
EDIT:我按照@savepopulation 所说的进行操作,将 adapter.notifyDataSetChanged();
从 presenceChanged 中移除,它起作用了。但我需要将它放在 presenceChanged 中,以便在用户在线和离线时更新。如果你们有任何建议,请告诉我:)
我们开始吧。
首先,当您调用 adapter.notifyDataSetChanged();
ListView
或 RecyclerView
时,如果您的数据发生变化或您的某些方法(例如 onClick
或 onItemClickListene
r仅在您单击视图或滚动视图后才有效,这意味着某些东西正在阻止您的 UiThread,并且您的 UiThread 在您中断后会被解除阻止。
这可能是由您的通知电话引起的。您正在尝试在之前的通知操作完成之前通知您的适配器。我认为这会导致您的问题。
我不知道是否有其他有效的方法来实现您要实现的目标,但如果您必须在 presenceChanged
方法中通知,只需通知项目哪个数据已更改。
您可以使用RecyclerView
代替ListView
并使用notifyItemChanged
方法。只需通知更改的项目。不要通知整个列表。这可以解决您的问题。您也可以从 onPresenceChanged
方法中获取通知方法。这解决了您的问题,但不适合您的业务。
如果通知单个更改的项目对您不起作用,您可能需要更改您的实现。
祝你好运。