1

J'ai un problème avec la mise à jour des données RecyclerView, je suppose qu'il y a quelque chose qui ne va pas avec notifyDataSetChanged(), mais je n'ai aucune idée de quoi. RecyclerView est juste vide une fois créé et rien ne change.RecyclerView ne pas mettre à jour les données

Voici mon code:

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()); 
      } 
     } 
    }); 
} 
} 

Mon adaptateur:

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; 
       } 
     } 
    } 
} 

} 

Quelqu'un peut-il me aider à résoudre ce problème? Merci à l'avance!

+0

Il y a deux problèmes ici. La raison pour laquelle il est toujours vide est que vous avez défini 'getItemCount()' pour renvoyer 0. La raison pour laquelle il ne sera pas mis à jour est que vous modifiez la liste d'amis dans l'activité, pas dans l'adaptateur. Voir ma réponse pour la solution à chacun. – AdamMc331

+0

Ne pas oublier d'accepter une réponse si elle finit par vous aider, @ Yogurt33 – d0nut

Répondre

1

Le problème est que vous ne changez jamais la liste des adaptateurs. Regardez cette ligne dans la classe Activity:

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()); 
     } 
    } 
}); 

L'objet mFriends que vous définissez est une variable dans l'activité, ce n'est pas le même que celui à l'intérieur de l'adaptateur. Je vous recommande d'ajouter une méthode comme dans votre adaptateur:

public void swapFriends(List<ParseUser> friends) { 
    mFriends = friends; 
    notifyDataSetChanged(); 
} 

Ensuite, vous pouvez l'appeler dans votre méthode findInBackground() comme ceci:

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()); 
     } 
    } 
}); 

EDIT: Un autre problème réside probablement dans votre getItemCount() méthode. Vous renvoyez toujours 0. Vous devez renvoyer le nombre d'amis que vous souhaitez afficher. Changez-le en:

@Override 
public int getItemCount() { 
    return mFriends.size(); 
} 
+1

Merci!J'ai complètement manqué la méthode getItemCount(). Maintenant, cela fonctionne parfaitement – Yogurt33

1

Initialement lors de la création du FriendsAdapter vos listes mFriends et mUsers sont null?

Lorsque vous recevez la réponse de données, vous remplacez vos listes actuelles mUsers et mFriends par de nouvelles références. Alors que le RecyclerView continuera à pointer vers les anciennes listes.

Solution 1:

Assurez-vous mFriends et mUsers ne sont pas null pour commencer.

Vous pouvez ensuite faire mFriends.addAll(newFriends) et mUsers.addAll(newUsers) pour ajouter les nouveaux amis et utilisateurs une fois reçus. Effectuez ensuite la adapter.notifyDataSetChanged()

Solution 2:

Ajouter une méthode dans votre FriendsAdapter pour dire au RecyclerView que vous avez une nouvelle liste adapter.showNewFriends(mFriends). Ajoutez des utilisateurs si vous en avez besoin en tant que paramètre supplémentaire ou appel d'une autre méthode lorsque vous les récupérez en premier. Dans cette méthode d'adaptateur, vous pouvez alors appeler notifyDataSetChanged().