Android Progressbar快速从EndlesRecycleView中删除

Android Progressbar快速从EndlesRecycleView中删除,android,youtube-api,infinite-scroll,Android,Youtube Api,Infinite Scroll,基本上,我在我的项目中使用了MVP和RxJava,但由于缺少Youtube API的Rx版本,我没有使用我的MVP方法 目前,我正在尝试制作一个显示youtube视频的endlessrecycleview的经典实现(使用线程) 我当前方法的问题是,我无法理解为什么ProgressBar会很快从endlessRecycleView中隐藏 private void setupRecyclerView() { mYoutubeVideoRecyclerView.setAdapter(adapt

基本上,我在我的项目中使用了MVPRxJava,但由于缺少Youtube API的Rx版本,我没有使用我的MVP方法

目前,我正在尝试制作一个显示youtube视频的
endlessrecycleview
的经典实现(使用线程)

我当前方法的问题是,我无法理解为什么
ProgressBar
会很快从
endlessRecycleView
中隐藏

private void setupRecyclerView() {
    mYoutubeVideoRecyclerView.setAdapter(adapter);
    mYoutubeVideoRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    mYoutubeVideoRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        if (true && !(hasFooter())) {
          LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
          //position starts at 0
          if (layoutManager.findLastCompletelyVisibleItemPosition()
              == layoutManager.getItemCount() - 2) {
            Log.d(TAG, "ProgressBar - item INSERTED At index = " + adapter.getItemCount());
            adapter.getVideos().add(null);
            recyclerView.getAdapter().notifyItemInserted(adapter.getItemCount() - 1);

            // TODO: 9/20/16  the bellow 2 lines make the progressbar not being displayed
            getYoutubeVideos();
            displayDataOrShowMessage();
          }
        }
      }
    });
  }

public void showVideos(列出视频){
Log.d(标记,“ProgressBar-添加项之前的适配器数据大小=“+Adapter.getItemCount());
试一试{
int size=adapter.getItemCount();
d(标记,“ProgressBar-从索引中删除的项=“+adapter.getItemCount());
adapter.getVideos().remove(大小-1);//删除页脚
适配器。添加视频(视频);
notifyItemRangeChanged(大小-1,adapter.getItemCount()-size);
}捕获(阵列索引边界外异常e){
适配器。添加视频(视频);
adapter.notifyDataSetChanged();
}
Log.d(标记“ProgressBar-添加项后的适配器数据大小=“+Adapter.getItemCount()”);
myoutubevideoryclerview.requestFocus();
progressBar.setVisibility(View.INVISIBLE);
infoTextView.setVisibility(View.INVISIBLE);
myoutubevideoryclerview.setVisibility(View.VISIBLE);
d(标记“showVideos——数据设置为列表”);
}

它不起作用,因为在调用
join()
时,您启动了一个新线程,并使UI线程等待它完成

实际上,您正在阻止UI线程,因此
adapter.getVideos().add(null)
适配器.getVideos().remove(大小-1)
被一个接一个地立即调用,它永远不会正确地显示在屏幕上

您需要做的是让该线程自由运行,不要
join()
它,并将
视频
传递回UI线程,然后将它们添加到适配器。当然,说起来容易做起来难

一种“简单”的方法是使用
AsyncTask
(),但是如果您不知道自己在做什么,那么这些任务也会有潜在内存泄漏的问题

正确的方法是让适配器中的数据成为可以
订阅/不贿赂的对象,并让后台线程添加数据。但这是一个更大的重构,而不是答案的范围

我知道这不是一个完整的答案,但我希望它能为你指明方向


此外,我建议使用(我创建的)这个库。它完全支持heades/footers和endlesscrool-out-of-the-box,应该会让您的一些代码更容易。

好的,异步是地狱,所以我进行了代码重构以使用Rx版本:

public void getYoutubeVideoList(final Context context, Boolean isRefresh) {
    MalitelApplication application = MalitelApplication.get(videoMvpView.getContext());
    MalitelService malitelService = application.getMalitelService(Constants.malitelYoutubeUrl);
    subscription = application.getYoutubeConnector().getYoutubeVideosObservable(isRefresh)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(application.defaultSubscribeScheduler())
        .subscribe(new Observer<List<VideoEntry>>() {
          @Override public void onCompleted() {
          }

          @Override public void onError(Throwable e) {
            videoMvpView.showMessage(R.string.probleme_connection);
          }

          @Override public void onNext(List<VideoEntry> videos) {
            videoMvpView.showVideos(videos);
            videoMvpView.showSelectedVideo((videos.get(0)).getText());
          }
        });
  }
public void getYoutubeVideoList(最终上下文,布尔值isRefresh){
MalitelApplication=MalitelApplication.get(videoMvpView.getContext());
MaliteService MaliteService=application.getMaliteService(Constants.malitelYoutubeUrl);
subscription=application.getYoutubeConnector().getYoutubeVideosObservable(isRefresh)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(application.defaultSubscribeScheduler())
.订阅(新观察员){
@覆盖已完成的公共void(){
}
@覆盖公共无效onError(可丢弃的e){
videoMvpView.showMessage(R.string.probleme\u连接);
}
@覆盖公共void onNext(列出视频){
videoMvpView.showVideos(视频);
videoMvpView.showSelectedVideo((videos.get(0)).getText());
}
});
}

public Observable getYoutubeVideosObservable(最终布尔值为refresh){
返回Observable.create(newobservable.OnSubscribe(){
@覆盖公共无效呼叫(用户)
private void displayDataOrShowMessage() {
    if (videoEntries != null) {
      showVideos(videoEntries);
      showSelectedVideo((videoEntries.get(0)).getVideoId());
    } else {
      showMessage(R.string.probleme_connection);
      ((VideoPlayerFragment) (getActivity()).getFragmentManager().findFragmentByTag("video_player"))
          .pause();
    }
  }
public void showVideos(List<VideoEntry> videos) {
    Log.d(TAG, "ProgressBar - Adapter data size before adding items = " + adapter.getItemCount());
    try {
      int size = adapter.getItemCount();
      Log.d(TAG, "ProgressBar - item REMOVED from index = " + adapter.getItemCount());
      adapter.getVideos().remove(size - 1);//removes footer
      adapter.addVideos(videos);
      adapter.notifyItemRangeChanged(size - 1, adapter.getItemCount() - size);
    } catch (ArrayIndexOutOfBoundsException e) {
      adapter.addVideos(videos);
      adapter.notifyDataSetChanged();
    }
    Log.d(TAG, "ProgressBar - Adapter data size after adding items = " + adapter.getItemCount());

    mYoutubeVideoRecyclerView.requestFocus();
    progressBar.setVisibility(View.INVISIBLE);
    infoTextView.setVisibility(View.INVISIBLE);
    mYoutubeVideoRecyclerView.setVisibility(View.VISIBLE);
    Log.d(TAG, "showVideos -- data is set to list");
  }
public void getYoutubeVideoList(final Context context, Boolean isRefresh) {
    MalitelApplication application = MalitelApplication.get(videoMvpView.getContext());
    MalitelService malitelService = application.getMalitelService(Constants.malitelYoutubeUrl);
    subscription = application.getYoutubeConnector().getYoutubeVideosObservable(isRefresh)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(application.defaultSubscribeScheduler())
        .subscribe(new Observer<List<VideoEntry>>() {
          @Override public void onCompleted() {
          }

          @Override public void onError(Throwable e) {
            videoMvpView.showMessage(R.string.probleme_connection);
          }

          @Override public void onNext(List<VideoEntry> videos) {
            videoMvpView.showVideos(videos);
            videoMvpView.showSelectedVideo((videos.get(0)).getText());
          }
        });
  }
public Observable<List<VideoEntry>> getYoutubeVideosObservable(final Boolean isRefresh) {
    return Observable.create(new Observable.OnSubscribe<List<VideoEntry>>() {
      @Override public void call(Subscriber<? super List<VideoEntry>> subscriber) {
        try {
          search =
              youtube.search().list("id,snippet").setChannelId(Constants.malitelYoutubeChannelId);
          search.setKey(DeveloperKey.DEVELOPER_KEY);
          search.setType("video");
          search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
          search.setFields(
              "items(id/videoId,snippet/title,snippet/description,snippet/thumbnails/default/url),"
                  + "nextPageToken,pageInfo,prevPageToken");

          if (!isRefresh) {
            search.setPageToken(nextPageToken);
          } else {
            totalResults = 0;
          }
        } catch (IOException e) {
          Log.d(TAG, "Could not initialize: " + e);
        }

        // Call the API and print results.
        SearchListResponse searchResponse = null;
        List<SearchResult> searchResultList = null;
        try {
          searchResponse = search.execute();

          if (searchResponse != null) {
            searchResultList = searchResponse.getItems();
            nextPageToken = searchResponse.getNextPageToken();
            if (nextPageToken != null) Log.d(TAG, nextPageToken);
          }

          if (searchResultList != null) {
            fillVideoEntry(searchResultList.iterator());
          }

          if (mVideoEntries != null) {
            totalResults += mVideoEntries.size();
            Log.d(TAG, "totalResults : " + totalResults);
          }

          if (!subscriber.isUnsubscribed()) {
            subscriber.onNext(mVideoEntries);
            subscriber.onCompleted();
          }
        } catch (IOException e) {
          if (!subscriber.isUnsubscribed()) {
            subscriber.onError(e);
          }
        }
      }
    });
  }