问题描述
当用户滚动到末尾时尝试加载更多项目时,将显示并删除进度对话框,然后再次显示,然后显示更多项目,但是仍未从回收者视图中删除进度对话框。有时会删除进度对话框,但仍然需要更多时间在回收者视图中显示更多项目。我正在使用firestore addOnSuccessListener从云Firestore检索项目并将其添加到arraylist,然后将高级广告添加到该arraylist并将数据添加到回收站适配器。
显示回收者视图项的活动MovieLists.java
public class MovieLists extends AppCompatActivity implements ItemInterface{
//nothing important just a comment
boolean runshowMovieOnce = true;
Query mQuery;
int loaderPosition;
DocumentSnapshot lastVisible;
String docId,catName,titleName;
ItemInterface itemInterface;
DatabaseReference listData;
String VideoId;
Movielistadapter movielistadapter;
RecyclerView movieLists;
// List of native ads that have been successfully loaded.
private List<UnifiednativeAd> mNativeAds = new ArrayList<>();
List<Object> itemDatas = new ArrayList<>();
linearlayoutmanager layoutManager;
// The number of native ads to load.
public static final int NUMBER_OF_ADS = 2;
// The AdLoader used to load ads.
private AdLoader adLoader;
int index = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_lists);
MaterialToolbar mToolBar = (MaterialToolbar) findViewById(R.id.imagePreviewToolbar);
setSupportActionBar(mToolBar);
docId = getIntent().getStringExtra("documentId");
catName = getIntent().getStringExtra("catName");
titleName = getIntent().getStringExtra("titleName");
if (getSupportActionBar() != null) {
getSupportActionBar().setdisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.back_button);
getSupportActionBar().setTitle(titleName);
}
movieLists = (RecyclerView)findViewById(R.id.movie_lists);
layoutManager = new linearlayoutmanager(this,linearlayoutmanager.VERTICAL,false);
itemInterface = this;
loadMovies();
}
@Override
public void onFirebaseLoadSuccess(List<Object> itemDataList) {
loadNativeAds();
}
@Override
public void onFirebaseLoadFailed(String message) {
}
@SuppressLint("MissingPermission")
private void loadNativeAds() {
AdLoader.Builder builder = new AdLoader.Builder(this,"ca-app-pub-3940256099942544/8135179316");
adLoader = builder.forUnifiednativeAd(
new UnifiednativeAd.OnUnifiednativeAdLoadedListener() {
@Override
public void onUnifiednativeAdLoaded(UnifiednativeAd unifiednativeAd) {
// A native ad loaded successfully,check if the ad loader has finished loading
// and if so,insert the ads into the list.
mNativeAds.add(unifiednativeAd);
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
}
}
}).withAdListener(
new AdListener() {
@Override
public void onAdFailedToLoad(int errorCode) {
// A native ad Failed to load,insert the ads into the list.
Log.e("MainActivity","The prevIoUs native ad Failed to load. Attempting to"
+ " load another.");
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
}
}
}).build();
// Load the Native ads.
adLoader.loadAds(new AdRequest.Builder().build(),NUMBER_OF_ADS);
}
private void insertAdsInMenuItems() {
if (mNativeAds.size() <= 0) {
return;
}
int offset = 3;
for (UnifiednativeAd ad : mNativeAds) {
if (index<itemDatas.size()) {
itemDatas.add(index,ad);
}
index = index + offset;
}
//index = itemDatas.size() - 3;
if (runshowMovieOnce){
showMoviesList();
}
runshowMovieOnce = false;
}
private void showMoviesList() {
movieLists.setLayoutManager(layoutManager);
movielistadapter = new Movielistadapter(movieLists,MovieLists.this,itemDatas);
movieLists.setHasFixedSize(true);
movieLists.setAdapter(movielistadapter);
movielistadapter.setLoadMore(new ILoadMore() {
@Override
public void onLoadMore() {
itemDatas.add(null);
movieLists.post(new Runnable() {
public void run() {
movielistadapter.notifyItemInserted(itemDatas.size() - 1);
Log.d("load position insert",""+(itemDatas.size()-1));
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
itemDatas.remove(itemDatas.size()-1);
movielistadapter.notifyItemRemoved(itemDatas.size() - 1);
Log.d("load position rem",""+(itemDatas.size()-1));
int prevIoUsListSize = itemDatas.size();
Log.d("prevIoUsListSize",""+prevIoUsListSize);
loadMovies();
int newListSize = itemDatas.size();
Log.d("newListSize",""+newListSize);
movielistadapter.notifyDataSetChanged();
movielistadapter.setLoaded();
}
},5000);
}
});
}
private void loadMovies() {
FirebaseFirestore mFirestore = FirebaseFirestore.getInstance();
CollectionReference mPostsCollection = mFirestore.collection(catName).document(docId).collection("listItem");
//Defining Query cursors
if (lastVisible == null){
mQuery = mPostsCollection.orderBy("pr",Query.Direction.ASCENDING)
.limit(6);
}else {
mQuery = mPostsCollection.orderBy("pr",Query.Direction.ASCENDING)
.startAfter(lastVisible)
.limit(6);
}
mQuery.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
for (QueryDocumentSnapshot documentSnapshot : documentSnapshots){
ItemData itemData = documentSnapshot.toObject(ItemData.class);
itemDatas.add(itemData);
Log.d("movie name",itemData.getVn());
}
// Get the last visible document
if (documentSnapshots.size() > 0)
lastVisible = documentSnapshots.getDocuments()
.get(documentSnapshots.size() -1);
onFirebaseLoadSuccess(itemDatas);
}
});
}
}
Movielistadapter.java
public class Movielistadapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<Object> itemDatas;
Context context;
String urlStart = "https://i1.ytimg.com/vi/";
String urlLast = "/mqdefault.jpg";
private static final int MOVIE_ITEM_VIEW_TYPE = 0;
private static final int UNIFIED_NATIVE_AD_VIEW_TYPE = 1;
private final int VIEW_TYPE_LOADING = 2;
boolean isLoading;
ILoadMore loadMore;
int visibleThreshold ;
int lastVisibleItem,totalItemCount;
View itemV;
public Movielistadapter(RecyclerView recyclerView,Context context,@NonNull List<Object> itemData) {
this.itemDatas = itemData;
this.context = context;
final linearlayoutmanager linearlayoutmanager = (linearlayoutmanager)recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView,int dx,int dy) {
super.onScrolled(recyclerView,dx,dy);
totalItemCount = linearlayoutmanager.getItemCount();
visibleThreshold = linearlayoutmanager.getChildCount();
lastVisibleItem = linearlayoutmanager.findLastVisibleItemPosition();
if (!isLoading && (visibleThreshold + lastVisibleItem) >= totalItemCount){
if (loadMore != null){
loadMore.onLoadMore();
isLoading = true;
}
}
}
});
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
switch (viewType) {
case UNIFIED_NATIVE_AD_VIEW_TYPE:
View unifiednativeLayoutView = LayoutInflater.from(
parent.getContext()).inflate(R.layout.ad_unified,parent,false);
return new UnifiednativeAdViewHolder(unifiednativeLayoutView);
case VIEW_TYPE_LOADING:
View viewL = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading,false);
return new LoadingViewHolder(viewL);
case MOVIE_ITEM_VIEW_TYPE:
// Fall through.
default: {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_movie_list,false);
return new Movielistadapter.MovieListsMyViewHolder(view);
}
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder myViewHolder,int i) {
//int viewType = getItemViewType(i);
if (myViewHolder instanceof Movielistadapter.MovieListsMyViewHolder){
MovieListsMyViewHolder movieListsMyViewHolder = (MovieListsMyViewHolder) myViewHolder;
ItemData model = (ItemData)itemDatas.get(i);
movieListsMyViewHolder.txt_item_title.setText(model.getVn());
String urlImage = urlStart + model.getVi() + urlLast;
Log.e("urlImage",urlImage);
Glide.with(context)
.load(urlImage)
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.centerCrop()
.diskCacheStrategy(diskCacheStrategy.AUTOMATIC)
.into(movieListsMyViewHolder.img_title);
movieListsMyViewHolder.setiItemClickListener(new IItemClickListener() {
@Override
public void onItemclickListener(View view,int position) {
ItemData itemData = new ItemData(model.getVi(),model.getVn(),model.getVd(),model.getPr(),model.getTc(),model.getVvc());
Log.d("Tmdb ID",String.valueOf(model.getTc()));
MovieDetails.startActivity(context,((MovieListsMyViewHolder) myViewHolder).transformationLayout,itemData);
}
});
}else if (myViewHolder instanceof UnifiednativeAdViewHolder){
Object recyclerViewItems = itemDatas.get(i);
UnifiednativeAd nativeAd = (UnifiednativeAd) recyclerViewItems;
populateNativeAdView(nativeAd,((UnifiednativeAdViewHolder) myViewHolder).getAdView());
}else if (myViewHolder instanceof LoadingViewHolder){
LoadingViewHolder loadingViewHolder = (LoadingViewHolder)myViewHolder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
@Override
public int getItemCount() {
return itemDatas.size();
}
public class MovieListsMyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
AppCompatTextView txt_item_title;
ImageView img_title;
IItemClickListener iItemClickListener;
CardView itemCardView;
TransformationLayout transformationLayout;
public void setiItemClickListener(IItemClickListener iItemClickListener) {
this.iItemClickListener = iItemClickListener;
}
public MovieListsMyViewHolder(@NonNull View itemView) {
super(itemView);
itemV = itemView;
txt_item_title = (AppCompatTextView) itemView.findViewById(R.id.item_movie_Title);
img_title = (ImageView)itemView.findViewById(R.id.item_movie_Image);
//itemCardView = (CardView)itemView.findViewById(R.id.item_cardview);
//itemCardView.setonClickListener(this);
transformationLayout = (TransformationLayout)itemView.findViewById(R.id.transformationMovieLayout);
transformationLayout.setonClickListener(this);
}
@Override
public void onClick(View view){
iItemClickListener.onItemclickListener(view,getAdapterPosition());
}
}
private void populateNativeAdView(UnifiednativeAd nativeAd,UnifiednativeAdView adView) {
// Some assets are guaranteed to be in every UnifiednativeAd.
((TextView) adView.getHeadlineView()).setText(nativeAd.getHeadline());
((TextView) adView.getBodyView()).setText(nativeAd.getBody());
((Button) adView.getCallToActionView()).setText(nativeAd.getCallToAction());
// These assets aren't guaranteed to be in every UnifiednativeAd,so it's important to
// check before trying to display them.
NativeAd.Image icon = nativeAd.getIcon();
if (icon == null) {
adView.getIconView().setVisibility(View.INVISIBLE);
} else {
((ImageView) adView.getIconView()).setimageDrawable(icon.getDrawable());
adView.getIconView().setVisibility(View.VISIBLE);
}
if (nativeAd.getPrice() == null) {
adView.getPriceView().setVisibility(View.INVISIBLE);
} else {
adView.getPriceView().setVisibility(View.VISIBLE);
((TextView) adView.getPriceView()).setText(nativeAd.getPrice());
}
if (nativeAd.getStore() == null) {
adView.getStoreView().setVisibility(View.INVISIBLE);
} else {
adView.getStoreView().setVisibility(View.VISIBLE);
((TextView) adView.getStoreView()).setText(nativeAd.getStore());
}
if (nativeAd.getStarrating() == null) {
adView.getStarratingView().setVisibility(View.INVISIBLE);
} else {
((ratingBar) adView.getStarratingView())
.setrating(nativeAd.getStarrating().floatValue());
adView.getStarratingView().setVisibility(View.VISIBLE);
}
if (nativeAd.getAdvertiser() == null) {
adView.getAdvertiserView().setVisibility(View.INVISIBLE);
} else {
((TextView) adView.getAdvertiserView()).setText(nativeAd.getAdvertiser());
adView.getAdvertiserView().setVisibility(View.VISIBLE);
}
// Assign native ad object to the native view.
adView.setNativeAd(nativeAd);
}
@Override
public int getItemViewType(int position) {
//DocumentSnapshot itemData = getItem(position);
Object recyclerViewItem = itemDatas.get(position);
if (recyclerViewItem instanceof UnifiednativeAd) {
return UNIFIED_NATIVE_AD_VIEW_TYPE;
}else if (itemDatas.get(position) == null){
return VIEW_TYPE_LOADING;
}else {
return MOVIE_ITEM_VIEW_TYPE;
}
}
public void setLoadMore(ILoadMore loadMore){
this.loadMore = loadMore;
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
public LoadingViewHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progressBar);
}
}
public void setLoaded(){
isLoading = false;
}
}
解决方法
短期答案:您的代码中发生了很多事情。如果只想删除loadingProgress,请在void viewsLoaded()
的LoadingViewHolder内添加一个progressbar.setVisibility(View.GONE)
方法,如果{Heller}不是,则在on if(myViewHolder instanceof LoadingViewHolder)
的onBindViewHolder方法内,调用viewsLoaded()方法。定位为适配器上的最后一个。
长期答案:如果要提高性能,请阅读有关如何使用DiffUtil.ItemCallback<>
而不是使用用于简单小型数据集的notifydatasetchanged()的信息。您在活动中有一个objectData列表,在适配器上有另一个,请阅读有关使用LiveData,数据绑定和MVVM模式的信息。
我建议您首先应该在Scroll View Listener中获得linearLayoutManager
。
另一个建议是不调用 movieListAdapter.notifyItemInserted(itemDatas.size() - 1);
在Runnable内部进行异步,因为在将null添加到列表后,应通知适配器
itemsData.add(null);
movieListAdapter.notifyItemInserted(itemsData.size() - 1);
另一行在itemDatas.remove(itemDatas.size()-1)
从列表中删除项目后,列表大小将减小一。
所以这是正确的:
movieListAdapter.notifyItemRemoved(itemDatas.size());
我希望这些会有所帮助。