Friday, 21 August 2020

Not able to display items properly in recycler view (pagination issue)

When I try to load more items when the user had scrolled to the end, a progress dialog is displayed and removed and then again displayed and then more items are displayed but progress dialog is still not removed from recycler view. And sometimes progress dialog is removed but still, it takes more time to display more items in recycler view. I'm using firestore addOnSuccessListener to retrieve items from cloud firestore and adding it to an arraylist and then adding native ads advanced to that arraylist and add the data to the recycler adapter.

Activity where recycler view items are displayed, 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, check if the ad loader has finished loading
                        // and if so, 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, parent, 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, parent, 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;
    }

}

ScreenCapture of how recyclerview is displaying items



from Not able to display items properly in recycler view (pagination issue)

No comments:

Post a Comment