I have Recyclerview showing media but when I scrolls items flickers or vibrates. I have tried many options mentioned in post like
My xml code :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:background="?attr/card_backgroundColor"
tools:context=".ui.matcheduser.GalleryViewFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeToRefresh"
android:layout_alignParentTop="true"
android:layout_above="@+id/progress_circular"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rcGallery"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
android:layoutAnimation="@anim/layout_animation"
android:background="?attr/card_backgroundColor" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/tv_no_galleries"
style="@style/TextViewHeadStyle"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_gravity="center_vertical"
android:gravity="center"
android:text="Gallery data is empty."
android:textColor="?attr/customIconColorST"
android:textSize="16sp" />
<ProgressBar
android:id="@+id/progress_circular"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:background="?attr/popupBackgroundColor"
android:visibility="gone" />
</RelativeLayout>
And code for Adapter:
private void initViews() {
mBinding.swipeToRefresh.post(() -> mBinding.swipeToRefresh.setRefreshing(true));
mViewModel.getGalleriesFromDB(mSettings.getUserId()).observe(getViewLifecycleOwner(), new Observer<List<GalleryModel>>() {
@Override
public void onChanged(List<GalleryModel> galleryModels) {
mBinding.progressCircular.setVisibility(View.GONE);
LOG.i(TAG, "Set Adapter : " + galleryModels.size());
if (mAdapter == null && galleryModels.size() > 0) {
galleryModelList = galleryModels;
mBinding.tvNoGalleries.setVisibility(View.GONE);
mAdapter = new GalleryAdapter(mContext, galleryModels, GalleryViewFragment.this, requireActivity());
mAdapter.setHasStableIds(true);
mBinding.rcGallery.setNestedScrollingEnabled(false);
isNextFetchAllowed = false;
mBinding.rcGallery.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
mBinding.rcGallery.setAdapter(mAdapter);
} else if (galleryModels.size() > 0) {
galleryModelList = galleryModels;
if (isDataChanged) {
generalViewModel.setGalleryChange(galleryModelList);
}
isNextFetchAllowed = false;
mAdapter.addItem(galleryModels);
}
if (mBinding.swipeToRefresh.isRefreshing()) {
mBinding.swipeToRefresh.setRefreshing(false);
}
}
});
mBinding.rcGallery.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == 0 && !recyclerView.canScrollVertically(1)) {
onBottomReached(Integer.parseInt(mViewModel.pageFetch));
}
}
});
mBinding.swipeToRefresh.setOnRefreshListener(() -> {
if (NetworkUtility.isConnected(mContext)) {
mViewModel.fetchNextGalleryList(mViewModel.STARTING_PAGE, mSettings.getDeviceId());
galleryModelList.clear();
} else {
mBinding.swipeToRefresh.setRefreshing(false);
Toast.makeText(mContext, mContext.getResources().getString(R.string.internet_error), Toast.LENGTH_LONG).show();
}
});
mViewModel.noDataFound().observe(getViewLifecycleOwner(), aBoolean -> {
if (aBoolean) {
mBinding.progressCircular.setVisibility(View.GONE);
mViewModel.setNoDataFound(false);
if (mViewModel.pageFetch.equalsIgnoreCase("0")) {
mBinding.swipeToRefresh.setRefreshing(false);
mBinding.tvNoGalleries.setVisibility(View.VISIBLE);
} else {
mBinding.tvNoGalleries.setVisibility(View.GONE);
}
}
});
mViewModel.getServerErrorValue().observe(getViewLifecycleOwner(), errorString -> {
if (!errorString.isEmpty()) {
mBinding.swipeToRefresh.setRefreshing(false);
mBinding.tvNoGalleries.setVisibility(View.VISIBLE);
mBinding.tvNoGalleries.setText(errorString);
mViewModel.resetServerErrorValue();
}
});
mViewModel.getDuplicateError().observe(getViewLifecycleOwner(), errorCode -> {
if (errorCode == 501) {
UtilHelper.resetSettingAndLogout(requireActivity(), mSettings);
mViewModel.resetErrorValue();
}
});
}
My Adapter code:
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, int position) {
GalleryModel galleryModel = galleryModelList.get(position);
loadMedia(viewHolder, galleryModel, viewHolder.gallerItemBinding.media, position);
}
private void loadMedia(ViewHolder viewHolder, GalleryModel galleryModel, ImageView postImage, int position) {
try {
String path = UtilHelper.getFileApi() + "/" + galleryModel.getMediaName().trim();
File file = UtilHelper.createExternalFileForDownloaded(context, path.substring(path.lastIndexOf('/') + 1));
boolean isVideoFile = UtilHelper.isVideo(Uri.parse(galleryModel.getMediaName()), context);
try {
String localeName = galleryModel.getMdOriginalType();
File localeFile = UtilHelper.createExternalFileForDownloaded(activity, localeName.substring(localeName.lastIndexOf('/') + 1));
if (localeFile.exists() && !file.exists()) {
boolean renamed = localeFile.renameTo(file);
if (renamed) {
LOG.d(TAG, "Image File renamed...");
} else {
LOG.d(TAG, "Image not renamed...");
}
}
} catch (Exception ex) {
LOG.e(TAG, ex.getMessage());
}
postImage.setTag(path);
if (!isVideoFile) {
viewHolder.gallerItemBinding.download.setVisibility(View.GONE);
viewHolder.gallerItemBinding.play.setVisibility(View.GONE);
postImage.setOnClickListener(view -> {
if (!file.exists()) {
onItemClickListener.onImageClick(galleryModel, null, !galleryModel.isMdPrivate() ? null : path, position);
} else {
onItemClickListener.onImageClick(galleryModel, null, file.getAbsolutePath(), position);
}
});
} else {
viewHolder.gallerItemBinding.play.setVisibility(View.VISIBLE);
viewHolder.gallerItemBinding.imageDownload.setVisibility(View.GONE);
}
viewHolder.gallerItemBinding.download.setOnClickListener(view -> {
try {
if (!isDownloading) {
if (!file.exists()) {
isDownloading = true;
downloadAsyncTask = new DownloadVideoAsyncTask(UtilHelper.getDirectory(activity), pDialog, this);
downloadAsyncTask.execute(path, "1");
} else {
Toast.makeText(activity, "Already downloaded.", Toast.LENGTH_LONG).show();
}
}
} catch (Exception ex) {
LOG.e(TAG, ex.getMessage());
}
});
viewHolder.gallerItemBinding.play.setOnClickListener(view -> {
try {
try {
if (!file.exists()) {
onItemClickListener.onPlayVideo(path, true);
} else {
onItemClickListener.onPlayVideo(file.getAbsolutePath(), false);
}
} catch (Exception ex) {
LOG.e(TAG, ex.getMessage());
}
} catch (Exception ex) {
LOG.e(TAG, ex.getMessage());
}
});
if (!file.exists()) {
Glide.with(context).load(path).apply(options).into(postImage);
} else {
viewHolder.gallerItemBinding.download.setVisibility(View.GONE);
viewHolder.gallerItemBinding.imageDownload.setVisibility(View.GONE);
Glide.with(context).load(file).apply(options).into(postImage);
}
} catch (Exception e) {
LOG.e(TAG, e.getMessage());
}
}