Progressbar从endlessrecycleview中快速删除

时间:2016-09-20 17:43:35

标签: android youtube-api infinite-scroll

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

目前,我正在尝试制作显示YouTube视频的endlessrecycleview经典实现(使用主题)。

我当前的方法存在的问题是,我无法弄清楚为什么ProgressBar很快就会隐藏endlessrecyleview

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

...

private void getYoutubeVideos() {
    Thread thread = new Thread(new Runnable() {
      @Override public void run() {
        try {
          videoEntries = videoPresenter.getYoutubeVideoList(getActivity());
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
    thread.start();
    try {
      thread.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

...

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

2 个答案:

答案 0 :(得分:1)

它不起作用,因为你启动一个新线程并让你的UI线程在你调用join()时等待它完成。

你基本上阻止了UI线程,因此adapter.getVideos().add(null);adapter.getVideos().remove(size - 1);会立即被一个接一个地调用,并且它永远不会在屏幕上正确绘制。

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

One&#34; easy&#34;方法是使用AsyncTaskhttps://developer.android.com/reference/android/os/AsyncTask.html),但如果您不知道自己在做什么,那么它们可能会分担潜在的内存泄漏问题。< / p>

正确的方法是让来自适配器的数据可以是subscribed/unsusbribed并让后台线程添加数据。但这是一个更大的重构,而不是答案的范围。

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

另外,我建议使用这个库https://github.com/eyeem/RecyclerViewTools(我创建的)。它完全支持heades / footers和EndlessScroll开箱即用,并且可以使你的一些代码变得更容易。

答案 1 :(得分:0)

好的,Async是地狱,所以我做了一个代码重构来使用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 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);
          }
        }
      }
    });
  }