1

Inutile de dire que je suis tombé sur beaucoup de solutions proposées pour ce problème particulier. J'ai enlevé scrollListener et l'ai implémenté dans mon fragment, j'ai utilisé notifyItemRangeInserted au lieu de notifyDataSetChanged. La chose est, aucune de ces solutions n'a fonctionné pour moi ... Je montre un ensemble de vidéos youtube dans mon application. Mon ensemble de données est en effet mis à jour; chose est quand je défiler vers le bas, à un moment donné la position de défilement se déplace vers le haut-à-dire le premier élément de mon jeu de données Voici un extrait de mon activité:Mise à jour de l'ensemble de données dans recyclerview tout en faisant défiler envoie le défilement vers le haut

private void setUpRecyclerView() 
{ 
    mRecyclerView.setHasFixedSize(true); 
    linearLayoutManager = new LinearLayoutManager(getActivity()); 
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    mRecyclerView.setLayoutManager(linearLayoutManager); 
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      super.onScrolled(recyclerView, dx, dy); 
      totalItemCount = linearLayoutManager.getItemCount(); 
      lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); 
      if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) 
      { 
       loadMorePosts(); 
       loading = true; 
      } 
     } 
    }); 

    initAdapter(); 
} 

private void initAdapter() 
{ 
    adapter = new MyAdapter(mDataSet, getActivity()); 
    mRecyclerView.setAdapter(adapter); 
    skeletonScreen = Skeleton.bind(mRecyclerView) 
      .adapter(adapter) 
      .shimmer(true) 
      .angle(30) 
      .duration(1200) 
      .count(10) 
      .load(R.layout.youtube_item) 
      .show(); 
} 

private void loadVideos(final OnLoadPlayListCallback videosCallback, String pageToken) 
{ 
    Call<FullChannelPlayListData> mcallPlayList = mYouTubeService.getPlayList(
      Tags.VALUE_SNIPPET, 
      20, 
      mPlayListId, 
      getActivity().getResources().getString(R.string.youtube_data_api_key), 
      pageToken 
      ); 

    mcallPlayList.enqueue(new Callback<FullChannelPlayListData>() { 
     @Override 
     public void onResponse(Call<FullChannelPlayListData> call, Response<FullChannelPlayListData> response) { 
      if (response.code() == 200) 
      { 
       Log.d("FullPlayListSuccessful", response.message()); 
       videosCallback.onSuccessfulRequest(response.body()); 
      } 
      else Log.d("FullPlayListUnsuccess", response.message()); 

     } 

     @Override 
     public void onFailure(Call<FullChannelPlayListData> call, Throwable t) { 
      videosCallback.onFailureRequest(t); 
     } 
    }); 
} 

@Override 
public void onSuccessfulRequest(FullChannelPlayListData fullChannelPlayListData) 
{ 
    Log.d(TAG, "onSuccessfulRequest Item size = "+ fullChannelPlayListData.getItems().size()); 
    if (StringUtils.isNotEmpty(mNextPageToken)) 
     removeFooter(); 

    for (FullPlayListItems mItem: fullChannelPlayListData.getItems()) 
    { 
     FullPlayListItems randomItem = getVideoFromDataSet(mItem.getSnippet().getResourceId().getVideoId(), mDataSet); 
     if (randomItem == null) { 
      mDataSet.add(mItem); 
     } 
    } 

    adapter.notifyItemRangeInserted(adapter.getItemCount(), mDataSet.size()); 

    mRecyclerView.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      skeletonScreen.hide(); 
     } 
    }, 2000); 


    mNextPageToken = fullChannelPlayListData.getNextPageToken(); 
    setLoaded(); 

} 

public void setLoaded() { 
    loading = false; 
} 

je pourrais utiliser vraiment utiliser un peu d'aide ...

MISE à JOUR classe MyAdapter

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> 
{ 

    private List<FullPlayListItems> mDataSet; 
    private Context mActivity; 
    private static final int YOUTUBE_ITEM_VIEW_TYPE = 0; 
    private static final int PROGRESS_BAR_ITEM_VIEW_TYPE = 1; 

    public MyAdapter(List<FullPlayListItems> mDataSet, Context mActivity) { 
     this.mDataSet = mDataSet; 
     this.mActivity = mActivity; 
    } 


    public class ProgressViewHolder extends RecyclerView.ViewHolder 
    { 
     @BindView(R.id.pBarLoadMorePosts) 
     ProgressBar pBarLoadMore; 

     public ProgressViewHolder(View itemView) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 
     } 
    } 


    @Override 
    public int getItemViewType(int position) { 
     return mDataSet.get(position) != null ? YOUTUBE_ITEM_VIEW_TYPE : PROGRESS_BAR_ITEM_VIEW_TYPE; 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    { 
     RecyclerView.ViewHolder viewHolder; 
     if (viewType == PROGRESS_BAR_ITEM_VIEW_TYPE) 
     { 
      View pBarLayoutView = LayoutInflater.from(parent.getContext()) 
        .inflate(R.layout.footer_loader, parent, false); 
      viewHolder = new ProgressViewHolder(pBarLayoutView); 
     } 
     else 
     { 
      View postItemLayoutView = LayoutInflater.from(parent.getContext()) 
        .inflate(R.layout.youtube_item, parent, false); 
      viewHolder = new YoutubeItemViewHolder(postItemLayoutView); 
     } 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) 
    { 
     int viewType = getItemViewType(position); 
     FullPlayListItems mVideoItem = mDataSet.get(position); 

     switch (viewType) 
     { 
      case PROGRESS_BAR_ITEM_VIEW_TYPE: 
       ProgressViewHolder progressViewHolder = (ProgressViewHolder) holder; 
       progressViewHolder.pBarLoadMore.getIndeterminateDrawable().setColorFilter(CoreApplication.getRes().getColor(R.color.colorPrimary), PorterDuff.Mode.SRC_IN); 
       break; 
      case YOUTUBE_ITEM_VIEW_TYPE: 
      default: 
       YoutubeItemViewHolder youtubeItemViewHolder = (YoutubeItemViewHolder) holder; 
       youtubeItemViewHolder.mVideoTitle.setText(mVideoItem.getSnippet().getTitle()); 
       youtubeItemViewHolder.sdvYoutubeThumbnail.setImageURI(Uri.parse(mVideoItem.getSnippet().getThumbnails().getHigh().getUrl())); 

     } 
    } 


    @Override 
    public int getItemCount() { 
     return mDataSet != null ? mDataSet.size() : 0; 
    } 

    public class YoutubeItemViewHolder extends RecyclerView.ViewHolder 
    { 
     TextView mVideoTitle; 
     SimpleDraweeView sdvYoutubeThumbnail; 

     public YoutubeItemViewHolder(View itemView) 
     { 
      super(itemView); 
      mVideoTitle = (TextView)itemView.findViewById(R.id.tv_video_title); 
      sdvYoutubeThumbnail = (SimpleDraweeView)itemView.findViewById(R.id.sdv_thumbnail); 
     } 
    } 
} 

Et voici mon onViewCreated:

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    mPlayListId = getArguments().getString(Tags.YT_CHANNEL_PLAYLIST_ID); 
    setUpRecyclerView(); 
    // Like I said initially mNextPageToken is empty 
    loadVideos(this, mNextPageToken); 
} 
+0

Comment mettre à jour votre jeu de données de l'adaptateur dans loadMorePost() –

+0

Il est juste la demande de réseau à l'aide retrofit ... Dans le cas où tout est réussi, je viens à condition que le rappel pour le succès request..So depuis mon l'adaptateur a déjà été initialisé dans onViewCreated, j'ai juste besoin de mettre à jour le itemCount à l'intérieur onSuccessfulRequest() –

+0

Pourriez-vous partager ce code pour référence –

Répondre

0

Notez simplement le changement de données dans la méthode onSuccessfulRequest().

adapter.notifyDataSetChanged(); 
+0

Cela ne fonctionne pas non plus (Ceci est la première chose que j'ai fait initialement) ... C'est pourquoi j'ai décidé de donner un essai aux autres méthodes de notification selon plusieurs après avoir lu ici sur SO des utilisateurs qui ont rencontré le même problème –

+0

avez-vous effacer votre jeu de données? – Saneesh

+0

Non ... juste mettre à jour –

0

Je ne connais pas cette réponse qui vous est utile. de toute façon s'il vous plaît essayer,

Ajouter cette méthode à votre MyAdapter

public void addItem(VideoSectionsActivity item){ 
mDataSet.add(item); 
notifyItemInserted(mDataSet.size() - 1); 
} 

Et changer votre onSuccessfulRequest()

@Override 
public void onSuccessfulRequest(FullChannelPlayListData fullChannelPlayListData) 
{ 
    Log.d(TAG, "onSuccessfulRequest Item size = "+ fullChannelPlayListData.getItems().size()); 
    if (StringUtils.isNotEmpty(mNextPageToken)) 
     removeFooter(); 

    for (FullPlayListItems mItem: fullChannelPlayListData.getItems()) 
    { 
     FullPlayListItems randomItem = getVideoFromDataSet(mItem.getSnippet().getResourceId().getVideoId(), mDataSet); 
     if (randomItem == null) { 
      adapter.addItem(mItem); 
     } 
    } 



    mRecyclerView.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      skeletonScreen.hide(); 
     } 
    }, 2000); 


    mNextPageToken = fullChannelPlayListData.getNextPageToken(); 
    setLoaded(); 

} 

Mise à jour

Et réorganiser également votre code d'activité

private void setUpRecyclerView() 
{ 
    mRecyclerView.setHasFixedSize(true); 
    linearLayoutManager = new LinearLayoutManager(getActivity()); 
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    mRecyclerView.setLayoutManager(linearLayoutManager); 
    initAdapter(); 
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      super.onScrolled(recyclerView, dx, dy); 
      totalItemCount = linearLayoutManager.getItemCount(); 
      lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); 
      if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) 
      { 
       loadMorePosts(); 
       loading = true; 
      } 
     } 
    }); 

}

+0

Même chose ici mate .....l'ensemble de données est mis à jour mais, en faisant défiler vers le bas, la position de défilement se déplace soudainement vers le haut (1er élément) de ma liste –