如果不先滚动,RecyclerView 项目中的图像不会显示

Images in RecyclerView items are not shown without scrolling first

我从 WordPress 页面 API 发出一些请求以获取一些内容,并且对于每个内容,我都会得到一张照片。我将它们显示在 RecyclerView 上。但是如果不先滚动 RecyclerView 就不会显示,然后他们开始一个一个地显示。

这是NewsActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_news);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        Window w = getWindow();
        w.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        w.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }

    back_button = findViewById(R.id.toolbar_back_button);
    back_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onBackPressed();
        }
    });

    toolbarTxt = findViewById(R.id.tolbar_text_view);
    toolbarTxt.setText("News");

    recyclerView = findViewById(R.id.news_recyclerview);

    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(mAdapter);
    recyclerView.setHasFixedSize(true);

    ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

    if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ||
            connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) {
            merrLajmet();
    } else {
        Toast.makeText(this, "You do not have internet connection", Toast.LENGTH_SHORT).show();
    }

}

这是我获取内容的方式。

public void merrLajmet(){

    Uri baseUri = Uri.parse(NEWS_REQUEST_URL);
    Uri.Builder uriBuilder = baseUri.buildUpon();

    JsonArrayRequest jsonObjectRequest = new JsonArrayRequest(
            Request.Method.GET, uriBuilder.toString(), null, new Response.Listener<JSONArray>() {

        @Override
        public void onResponse(JSONArray response) {
            listLajmet = Query.shfaqLajmet(response);

            for (Lajmi lajmi : listLajmet) {
                merrFoton(lajmi);
            }
            mAdapter.setLajmi(listLajmet);
        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            // Error
        }
    });

    if (listLajmet.isEmpty()) {
        MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
    }
}

并从特定内容中获取照片。

public void merrFoton(final Lajmi lajmi) {

    Uri baseUri = Uri.parse(IMAGE_REQUEST_URL);
    Uri.Builder uriBuilder = baseUri.buildUpon();
    uriBuilder.appendPath(String.valueOf(lajmi.getFeatureMedia()));

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
            Request.Method.GET, uriBuilder.toString(), null, new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {
            String imageUrl = Query.shfaqFoton(response);
            if (imageUrl == ""){
                imageUrl = String.valueOf(R.drawable.news_photo1);
            }

            lajmi.setImage(imageUrl);
            //mAdapter.setLajmi(listLajmet);
        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            //Toast.makeText(NewsActivity.this, "Nuk ka te image " +
                    //error.networkResponse.toString(), Toast.LENGTH_SHORT).show();
        }
    });

    MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
}

最后,这是我的适配器 class。

public class LajmiAdapter extends RecyclerView.Adapter<LajmiAdapter.MyViewHolder>{

    private List<Lajmi> mLajmiList = new ArrayList<>();
    private Context ctx;

    public LajmiAdapter(Context ctx) {
        this.ctx = ctx;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        TextView mTitle, mCategory;
        ImageView mImage,mColor;

        public MyViewHolder(View itemView) {
            super(itemView);

            itemView.setOnClickListener(this);

            mTitle = itemView.findViewById(R.id.news_text_view_titulli);
            mCategory = itemView.findViewById(R.id.news_text_view_kategoria);

            mImage = itemView.findViewById(R.id.news_image_main);
            mColor = itemView.findViewById(R.id.news_image_small);
        }

        @Override
        public void onClick(View v) {

            int position = getAdapterPosition();

            Lajmi lajmi = mLajmiList.get(position);

            Intent intent = new Intent(ctx, SinglenewsActivity.class);

            intent.putExtra("title", lajmi.getTitle());
            intent.putExtra("category", lajmi.getCategory());
            intent.putExtra("image", lajmi.getImage());
            intent.putExtra("color",lajmi.getColor());
            intent.putExtra("description",lajmi.getDescription());

            ctx.startActivity(intent);
        }
    }

    @Override
    public LajmiAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View itemView;
        itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);
        return new LajmiAdapter.MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(LajmiAdapter.MyViewHolder holder, int position) {

        Lajmi lajmi = mLajmiList.get(position);
        holder.mTitle.setText(lajmi.getTitle());

        Picasso.get()
                .load(lajmi.getImage())
                .resize(400, 300)
                .onlyScaleDown()
                .into(holder.mImage);
    }

    public void setLajmi(List<Lajmi> lajmiList) {
        mLajmiList = lajmiList;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        if(mLajmiList == null)
            return 0;
        else
            return mLajmiList.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }
}

当我打开 NewsActivity 时,我希望所有图像都显示在 RecyclerView 的项目上,而无需先滚动。

当您滚动列表时,它会获取更新的项目,从而获取您从服务器获取的图像的更新列表。我认为您在这里错过了 notifyDataSetChanged 电话。

@Override
public void onResponse(JSONObject response) {
    String imageUrl = Query.shfaqFoton(response);
    if (imageUrl == ""){
        imageUrl = String.valueOf(R.drawable.news_photo1);
    }

    lajmi.setImage(imageUrl);
    // Add the notifyDataSetChanged here
    mAdapter.notifyDataSetChanged();
}

但是,在这种情况下,当您一张一张地获取图像时,每次获取图像时,都会通知适配器,因此 RecyclerView 将相应地重新加载。当您滚动浏览项目时,每次调用 notifyDataSetChanged() 时每次从服务器获取新图像时列表都会到达顶部,这有点烦人。

我想建议以不同的方式实现整个图像提取。首先获取要下载的图像的数量。然后获取所有图像 URL 并将它们保存在您的列表中。然后在下载完所有图片 URL 后调用 notifyDataSetChanged

希望对您有所帮助!

notifyDataSetChanged():通知附加的观察者底层数据已更改,任何反映数据集的视图都应自行刷新。(https://developer.android.com/reference/android/widget/BaseAdapter)

如果您要一张一张地获取图像,刷新视图可能不是最佳解决方案。如果您不希望它在下载新图片时滚动到页面顶部,您可以使用 notifyItemRangeInserted(int positionStart, int itemCount)

也请看看这个