Android Progressbar快速从EndlesRecycleView中删除
基本上,我在我的项目中使用了MVP和RxJava,但由于缺少Youtube API的Rx版本,我没有使用我的MVP方法 目前,我正在尝试制作一个显示youtube视频的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
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);
}
}
}
});
}