Issue
I am showing images from server in RecylerView. When i use fix size of ImageView or layout, it works fine.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_margin="5dp"
android:clipToPadding="false">
<ImageView
android:id="@+id/thumb_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />
</android.support.v7.widget.CardView>
</LinearLayout>
But when I set android:layout_height="wrap_content"
, all image blinking.I cant set fix size cause my all images are different.
I'm loading image to imageview with glide.
Here is my BindViewHolder code-
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
Photos image = imagesList.get(position);
Glide.with(mContext)
.load(image.getThumb())
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
((MyViewHolder) holder).progressBar.setVisibility(View.GONE);
return false;
}
})
.fitCenter()
.into(((MyViewHolder) holder).imageView);
((MyViewHolder) holder).itemView.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onClick(holder.getAdapterPosition());
}
});
}
Below image is taken from somewhere. My problem is something like this. Image blink like this but it doesn't get mix. One image flicker on it's imageview. Adapter Class
public class RecycleViewAdapter extends RecyclerView.Adapter {
private Context mContext;
private ClickListener mListener;
private final ArrayList<Photos> imagesList;
public static class MyViewHolder extends RecyclerView.ViewHolder {
private ClickListener mListener;
TextView image_date, image_weight, imageHit;
ImageView imageView, sudoImage;
ProgressBar progressBar;
public MyViewHolder(View view, ClickListener listener) {
super(view);
mListener = listener;
image_date = (TextView) itemView.findViewById(R.id.image_date);
image_weight = (TextView) itemView.findViewById(R.id.image_weight);
imageHit = (TextView) itemView.findViewById(R.id.hit);
imageView = (ImageView) itemView.findViewById(R.id.thumb_image);
progressBar = itemView.findViewById(R.id.progressBarThumb);
}
}
public static class ViewHolderAdMob extends RecyclerView.ViewHolder {
public AdView mAdView;
public ViewHolderAdMob(View view) {
super(view);
MainActivity.loadAd(view);
}
}
public RecycleViewAdapter(Context context, ArrayList<Photos> images, ClickListener listener) {
mContext = context;
this.imagesList = images;
mListener = listener;
}
@Override
public int getItemViewType(int position) {
if (position % 8 == 0)
return 1;
return 0;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch (viewType) {
case 1:
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.util_list_item_admob, parent, false);
return new ViewHolderAdMob(v);
default:
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.util_image_thumb, parent, false);
return new MyViewHolder(itemView, mListener);
}
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case 1:
break;
default:
final Photos image = imagesList.get(holder.getAdapterPosition());
new Handler().post(new Runnable() {
@Override
public void run() {
Glide.with(mContext)
.load(image.getThumb())
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
((MyViewHolder) holder).progressBar.setVisibility(View.GONE);
return false;
}
})
.fitCenter()
.into(((MyViewHolder) holder).imageView);
((MyViewHolder) holder).image_date.setText(image.getTitle());
((MyViewHolder) holder).imageHit.setText(image.getHit());
((MyViewHolder) holder).itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onClick(holder.getAdapterPosition());
}
});
if (!image.getWeight().isEmpty()) {
((MyViewHolder) holder).image_weight.setText(image.getWeight() + " gm");
}
}
});
}
}
@Override
public int getItemCount() {
return imagesList.size();
}
public interface ClickListener {
void onClick(int position);
}
}
Activity class-
public class DJPhotos extends AppCompatActivity {
private static final String url = "http://192.168.43.238/";
// private static final String url = "https://desijewel.in/";
private static final String script = url + "android/android_script.php";
static final String REQ_TAG = "VACTIVITY";
public ArrayList<Photos> imagelist;
// Variable for pagination
private int pageNumber = 1;
private boolean isLoading = true;
private int pastVisibleItems, visibleItemCount, totalItemCount, previousTotal = 0;
private int viewThesold = 0;
RecycleViewAdapter adapter;
String table, type, weightFrom, weightTo;
Button filterButton;
RecyclerView recyclerView;
ProgressBar progressBar, progressBarBottom;
RecyclerView.LayoutManager mLayoutManager;
boolean isFirstTime = true;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_djphotos);
progressBar = findViewById(R.id.progressBar);
progressBarBottom = findViewById(R.id.progressBarBottom);
Intent intent = getIntent();
table = intent.getStringExtra("table");
type = intent.getStringExtra("type");
weightFrom = intent.getStringExtra("weightFrom");
weightTo = intent.getStringExtra("weightTo");
imagelist = new ArrayList<>();
TextView desc = (TextView) findViewById(R.id.desc);
filterButton = findViewById(R.id.filterButton);
filterButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(v);
}
});
recyclerView = findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
RecycleViewAdapter.ClickListener listener = new RecycleViewAdapter.ClickListener() {
@Override
public void onClick(int position) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
bundle.putSerializable("url", imagelist);//And here i'm always getting the latest image list . u
FragmentTransaction ft = getFragmentManager().beginTransaction();
Full_Image newFragment = Full_Image.newInstance();
newFragment.setArguments(bundle);
newFragment.show(ft, "slideshow");
}
};
adapter = new RecycleViewAdapter(DJPhotos.this, imagelist, listener);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisibleItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
if (dy > 0) {
if (isLoading) {
if (totalItemCount > previousTotal) {
isLoading = false;
previousTotal = totalItemCount;
}
}
if (!isLoading && (totalItemCount - visibleItemCount - 10) <= (pastVisibleItems + viewThesold)) {
performPagination();
isLoading = true;
}
}
}
});
getJsonResponsePost();
}
public void getJsonResponsePost() {
progressBar.setVisibility(View.VISIBLE);
Map<String, String> params = new HashMap();
params.put("table", table);
params.put("weightFrom", weightFrom);
params.put("weightTo", weightTo);
params.put("type", type);
HashMap hash = new HashMap();
hash.put("page", pageNumber);
params.putAll(hash);
JSONObject json = new JSONObject(params);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, script, json,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
pageNumber++;
progressBar.setVisibility(View.GONE);
imagelist.clear();
JSONArray heroArray = null;
try {
heroArray = response.getJSONArray("images");
for (int i = 0; i < heroArray.length(); i++) {
JSONObject jsonObject = heroArray.getJSONObject(i);
Photos photos = new Photos();
photos.setUrl(jsonObject.getString("image"));
photos.setThumb(jsonObject.getString("thumb"));
photos.setWeight(jsonObject.getString("weight"));
photos.setTitle(jsonObject.getString("image_title"));
photos.setDate(jsonObject.getString("date"));
photos.setHit(jsonObject.getString("hit"));
imagelist.add(photos);
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
}
});
jsonObjectRequest.setTag(REQ_TAG);
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getInstance().addToRequestQueue(jsonObjectRequest);
}
public String getTableValue() {
return table;
}
public void showDialog(View v) {
FragmentManager manager = getFragmentManager();
CustomDialog customDialog = new CustomDialog();
customDialog.show(manager, "Custom");
}
public void performPagination() {
Map<String, String> params = new HashMap();
params.put("table", table);
params.put("weightFrom", weightFrom);
params.put("weightTo", weightTo);
params.put("type", type);
HashMap hash = new HashMap();
hash.put("page", pageNumber);
params.putAll(hash);
JSONObject json = new JSONObject(params);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, script, json,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
pageNumber++;
progressBarBottom.setVisibility(View.GONE);
if(imagelist == null)
imagelist = new ArrayList<>();
JSONArray heroArray = null;
try {
heroArray = response.getJSONArray("images");
for (int i = 0; i < heroArray.length(); i++) {
JSONObject jsonObject = heroArray.getJSONObject(i);
Photos photos = new Photos();
photos.setUrl(jsonObject.getString("image"));
photos.setThumb(jsonObject.getString("thumb"));
photos.setWeight(jsonObject.getString("weight"));
photos.setTitle(jsonObject.getString("image_title"));
photos.setDate(jsonObject.getString("date"));
photos.setHit(jsonObject.getString("hit"));
imagelist.add(photos);
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
jsonObjectRequest.setTag(REQ_TAG);
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getInstance().addToRequestQueue(jsonObjectRequest);
}
Solution
Try this
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
Photos image = imagesList.get(holder.getAdapterPosition());
new Handler().post(new Runnable() {
@Override
public void run() {
Glide.with(mContext)
.load(image.getThumb())
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
((MyViewHolder) holder).progressBar.setVisibility(View.GONE);
return false;
}
})
.fitCenter()
.into(((MyViewHolder) holder).imageView);
}
});
((MyViewHolder) holder).itemView.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onClick(holder.getAdapterPosition());
}
});
}
Answered By - Brijesh Joshi
Answer Checked By - Mary Flores (JavaFixing Volunteer)