当滚动时,Recyclerview 闪烁

3

我正在使用 RecylerView 在页面上展示来自服务器的图片。当我使用固定大小的 ImageViewlayout 时,图片可以成功显示。

<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>

但是当我设置android:layout_height="wrap_content"时,所有的图片都会闪烁。我不能设置固定大小,因为我的所有图片都是不同的。 我正在使用Glide将图片加载到ImageView中。 这是我的BindViewHolder代码-
 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());
                }
            });

以下图片来自某处。我的问题类似于这样。图像闪烁,但它们并没有混合在一起。一个图像闪烁在其ImageView上。 适配器类

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);
}

}

活动类 -

公共类DJPhotos扩展自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);
}

enter image description here


尝试使用以下代码块:<ImageView android:layout_width="wrap_content" android:adjustViewBounds="true" android:layout_height="wrap_content" /> - AskNilesh
请问您能否添加 GIF 或其他内容以便更好地理解您的问题? - Brijesh Joshi
3个回答

1

您可以尝试使用通用图像加载器

UIL旨在为图像加载、缓存和显示提供强大、灵活和高度可定制的工具。它提供了许多配置选项,并对图像加载和缓存过程有很好的控制。

它提供了许多功能,例如:

  1. 多线程图像加载(异步或同步)
  2. 广泛的ImageLoader配置自定义(线程执行器、下载器、解码器、内存和磁盘缓存、显示图像选项等)
  3. 每个显示图像调用的许多自定义选项(存根图像、缓存开关、解码选项、位图处理和显示等)
  4. 在内存和/或磁盘上缓存图像(设备文件系统或SD卡)
  5. 监听加载过程(包括下载进度)

希望它能解决您的问题。


问题不在于Glide,而是当layout_height固定时它可以正常工作。 - mukeshsoni

1

Try this code..

            <ImageView
                android:id="@+id/thumb_image"
                android:layout_width="wrap_parent"
                android:layout_height="wrap_content"
                android:scaleType="centerCrop" />

Glide需要一些时间来加载图像,但是您可以将图像存储为Glide缓存,然后再次加载图像时就不需要花费时间了。

将此代码定义到适配器中。

  Glide.with(context).load(CommonUtils.checkForNullValue(userData.getUserVo().getPhoto())).apply(RequestOptions.circleCropTransform())
                .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL))
                .apply(RequestOptions.placeholderOf(R.drawable.big_user))
                .into(holder.ivUserImage);

而且图像质量取决于。


我添加了 Glide 代码,但是 Glide 加载图像需要一些时间,但是您可以使用以下代码将图像存储到缓存中: .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)) 之后,它不会再次加载图像,而是从缓存中获取。 - user4571931
请提供您的完整适配器和活动类代码。 - user4571931

0

试试这个

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());
                }
            });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接