RecyclerView 不更新数据
RecyclerView not updating the data
我在更新 RecyclerView 数据时遇到问题,我猜 notifyDataSetChanged() 有问题,但我不知道是什么。
RecyclerView 一旦创建就为空,没有任何变化。
这是我的代码:
EditFriends2 (once i have it working i erase the "2" ;) )
public class EditFriendsActivty2 extends AppCompatActivity {
private static final String TAG = EditFriendsActivty2.class.getSimpleName();
private ParseUser mCurrentUser;
private ParseRelation<ParseUser> mFriendsRelation;
private List<ParseUser> mFriends;
private List<ParseUser> mUsers;
private FriendsAdapter adapter;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_friends_activty2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
adapter = new FriendsAdapter(mUsers, mFriends);
mRecyclerView.setAdapter(adapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(EditFriendsActivty2.this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
showFriendsList();
}
@Override
protected void onResume() {
super.onResume();
showFriendsList();
}
private void showFriendsList() {
mCurrentUser = ParseUser.getCurrentUser();
mFriendsRelation = mCurrentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.orderByAscending(ParseConstants.KEY_USERNAME);
query.setLimit(1000);
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
// Success
mUsers = list;
downloadFriends();
} else {
Toast.makeText(EditFriendsActivty2.this, R.string.error_toast, Toast.LENGTH_SHORT).show();
Log.i(TAG, e.getMessage());
}
}
});
}
private void downloadFriends() {
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
mFriends = list;
// Here i'm updating the RecyclerView, when i have the data about users and friends
adapter.notifyDataSetChanged();
} else {
Log.i(TAG, e.getMessage());
}
}
});
}
}
我的适配器:
public class FriendsAdapter extends RecyclerView.Adapter<FriendsAdapter.FriendsViewHolder> {
private static final String TAG = FriendsAdapter.class.getSimpleName();
private List<ParseUser> mUsers;
private List<ParseUser> mFriends;
public FriendsAdapter(List<ParseUser> users, List<ParseUser> friends){
mUsers = users;
mFriends = friends;
}
@Override
public FriendsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate((R.layout.friends_list_item), parent, false);
FriendsViewHolder viewHolder = new FriendsViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(FriendsViewHolder holder, int position) {
if(mUsers != null) {
holder.bindFriends(mUsers.get(position));
}
}
@Override
public int getItemCount() {
return 0;
}
public class FriendsViewHolder extends RecyclerView.ViewHolder {
public TextView mNameLabel;
public CheckBox mCheckBox;
public FriendsViewHolder(View itemView) {
super(itemView);
mNameLabel = (TextView) itemView.findViewById(R.id.nameLabel);
mCheckBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
public void bindFriends (ParseUser user){
mNameLabel.setText(user.getUsername());
mCheckBox.setChecked(false);
for (ParseUser friend : mFriends){
if(friend.getObjectId().equals(user.getObjectId())){
mCheckBox.setChecked(true);
break;
}
}
}
}
}
谁能帮我解决一下?提前致谢!
最初在创建 FriendsAdapter
时,您的 mFriends
和 mUsers
列表是 null
?
当您收到数据响应时,您正在用新的引用替换当前的 mUsers
和 mFriends
列表。而 RecyclerView 将继续指向旧列表。
解决方案一:
确保 mFriends
和 mUsers
不是 null
开头。
然后您可以执行 mFriends.addAll(newFriends)
和 mUsers.addAll(newUsers)
来添加收到的新朋友和用户。然后执行 adapter.notifyDataSetChanged()
方案二:
在您的 FriendsAdapter
中添加一个方法来告诉 RecyclerView 您有一个新列表 adapter.showNewFriends(mFriends)
。如果您需要将用户作为另一个参数或在您首先获取它们时调用另一个方法,请添加用户。在此适配器方法中,您可以调用 notifyDataSetChanged()
.
问题是您从未真正更改适配器的列表。看看Activity
里面的这一行class:
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
mFriends = list;
// Here i'm updating the RecyclerView, when i have the data about users and friends
adapter.notifyDataSetChanged();
} else {
Log.i(TAG, e.getMessage());
}
}
});
你设置的mFriends
对象是Activity里面的一个变量,和Adapter里面的不一样。我建议在您的适配器中添加这样的方法:
public void swapFriends(List<ParseUser> friends) {
mFriends = friends;
notifyDataSetChanged();
}
然后您可以在 findInBackground()
方法中调用它,如下所示:
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
adapter.swapFriends(list);
} else {
Log.i(TAG, e.getMessage());
}
}
});
编辑: 另一个问题可能在于您的 getItemCount()
方法。你总是returning 0。你需要return你想显示的好友数量。将其更改为:
@Override
public int getItemCount() {
return mFriends.size();
}
我在更新 RecyclerView 数据时遇到问题,我猜 notifyDataSetChanged() 有问题,但我不知道是什么。 RecyclerView 一旦创建就为空,没有任何变化。
这是我的代码:
EditFriends2 (once i have it working i erase the "2" ;) )
public class EditFriendsActivty2 extends AppCompatActivity {
private static final String TAG = EditFriendsActivty2.class.getSimpleName();
private ParseUser mCurrentUser;
private ParseRelation<ParseUser> mFriendsRelation;
private List<ParseUser> mFriends;
private List<ParseUser> mUsers;
private FriendsAdapter adapter;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_friends_activty2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
adapter = new FriendsAdapter(mUsers, mFriends);
mRecyclerView.setAdapter(adapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(EditFriendsActivty2.this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
showFriendsList();
}
@Override
protected void onResume() {
super.onResume();
showFriendsList();
}
private void showFriendsList() {
mCurrentUser = ParseUser.getCurrentUser();
mFriendsRelation = mCurrentUser.getRelation(ParseConstants.KEY_FRIENDS_RELATION);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.orderByAscending(ParseConstants.KEY_USERNAME);
query.setLimit(1000);
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
// Success
mUsers = list;
downloadFriends();
} else {
Toast.makeText(EditFriendsActivty2.this, R.string.error_toast, Toast.LENGTH_SHORT).show();
Log.i(TAG, e.getMessage());
}
}
});
}
private void downloadFriends() {
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
mFriends = list;
// Here i'm updating the RecyclerView, when i have the data about users and friends
adapter.notifyDataSetChanged();
} else {
Log.i(TAG, e.getMessage());
}
}
});
}
}
我的适配器:
public class FriendsAdapter extends RecyclerView.Adapter<FriendsAdapter.FriendsViewHolder> {
private static final String TAG = FriendsAdapter.class.getSimpleName();
private List<ParseUser> mUsers;
private List<ParseUser> mFriends;
public FriendsAdapter(List<ParseUser> users, List<ParseUser> friends){
mUsers = users;
mFriends = friends;
}
@Override
public FriendsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate((R.layout.friends_list_item), parent, false);
FriendsViewHolder viewHolder = new FriendsViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(FriendsViewHolder holder, int position) {
if(mUsers != null) {
holder.bindFriends(mUsers.get(position));
}
}
@Override
public int getItemCount() {
return 0;
}
public class FriendsViewHolder extends RecyclerView.ViewHolder {
public TextView mNameLabel;
public CheckBox mCheckBox;
public FriendsViewHolder(View itemView) {
super(itemView);
mNameLabel = (TextView) itemView.findViewById(R.id.nameLabel);
mCheckBox = (CheckBox) itemView.findViewById(R.id.checkBox);
}
public void bindFriends (ParseUser user){
mNameLabel.setText(user.getUsername());
mCheckBox.setChecked(false);
for (ParseUser friend : mFriends){
if(friend.getObjectId().equals(user.getObjectId())){
mCheckBox.setChecked(true);
break;
}
}
}
}
}
谁能帮我解决一下?提前致谢!
最初在创建 FriendsAdapter
时,您的 mFriends
和 mUsers
列表是 null
?
当您收到数据响应时,您正在用新的引用替换当前的 mUsers
和 mFriends
列表。而 RecyclerView 将继续指向旧列表。
解决方案一:
确保 mFriends
和 mUsers
不是 null
开头。
然后您可以执行 mFriends.addAll(newFriends)
和 mUsers.addAll(newUsers)
来添加收到的新朋友和用户。然后执行 adapter.notifyDataSetChanged()
方案二:
在您的 FriendsAdapter
中添加一个方法来告诉 RecyclerView 您有一个新列表 adapter.showNewFriends(mFriends)
。如果您需要将用户作为另一个参数或在您首先获取它们时调用另一个方法,请添加用户。在此适配器方法中,您可以调用 notifyDataSetChanged()
.
问题是您从未真正更改适配器的列表。看看Activity
里面的这一行class:
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
mFriends = list;
// Here i'm updating the RecyclerView, when i have the data about users and friends
adapter.notifyDataSetChanged();
} else {
Log.i(TAG, e.getMessage());
}
}
});
你设置的mFriends
对象是Activity里面的一个变量,和Adapter里面的不一样。我建议在您的适配器中添加这样的方法:
public void swapFriends(List<ParseUser> friends) {
mFriends = friends;
notifyDataSetChanged();
}
然后您可以在 findInBackground()
方法中调用它,如下所示:
mFriendsRelation.getQuery().findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> list, ParseException e) {
if (e == null) {
adapter.swapFriends(list);
} else {
Log.i(TAG, e.getMessage());
}
}
});
编辑: 另一个问题可能在于您的 getItemCount()
方法。你总是returning 0。你需要return你想显示的好友数量。将其更改为:
@Override
public int getItemCount() {
return mFriends.size();
}