简体   繁体   English

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

[英]Images in RecyclerView items are not shown without scrolling first

I do some request from a WordPress page API to get some content and for every content, I get a picture. 我从WordPress页面API发出一些请求以获取一些内容,对于每种内容,我都会得到一张图片。 And I display them on RecyclerView . 然后在RecyclerView上显示它们。 But they do not show without doing first a scroll of RecyclerView then they start to show one by one. 但是,如果不先滚动RecyclerView然后开始逐个显示,就不会显示它们。

Here is the NewsActivity 这是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();
    }

}

Here's how I get the contents. 这是我获取内容的方式。

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

And the get the photo of from specific content. 并从特定内容获取照片。

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

And finally, here's my adapter 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;
    }
}

When I open NewsActivity , I expect all the images to show on the item of RecyclerView without doing a scroll first. 当我打开NewsActivity ,我希望所有图像都显示在RecyclerView项上,而无需先进行滚动。

When you are scrolling the list, it gets the updated items and hence gets the updated list of images which you fetched from your server. 当您滚动列表时,它会获取更新的项目,因此会获取您从服务器获取的图像的更新列表。 I think you are missing a notifyDataSetChanged call here. 我认为您在这里错过了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();
}

However, in this case, as you are fetching your images one by one, each time you are fetching an image, the adapter will be notified and hence the RecyclerView will be reloaded accordingly. 但是,在这种情况下,当您一张一张地获取图像时,每次获取图像时,都会通知适配器,因此将相应地重新加载RecyclerView Its kind of annoying in the case when you are scrolling through items and the list gets to the top each time a new image is fetched from the server as you are calling notifyDataSetChanged() each time. 当您每次滚动浏览项目并且每次每次从服务器获取新图像时列表都到达顶部时,这种情况notifyDataSetChanged()因为您每次都调用notifyDataSetChanged()

I would like to suggest implementing the whole image fetching a bit differently. 我想建议以不同的方式实现整个图像的获取。 Get the count of the images to be downloaded first. 获取要首先下载的图像数。 Then get all the images URLs and save them in your list. 然后获取所有图像URL,并将其保存在列表中。 Then call notifyDataSetChanged once you are finished downloading all the image URLs. 完成所有图像URL的下载后,请调用notifyDataSetChanged

Hope that helps! 希望有帮助!

notifyDataSetChanged(): Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.( https://developer.android.com/reference/android/widget/BaseAdapter ) notifyDataSetChanged():通知附加的观察者基础数据已更改,任何反映该数据集的View都应刷新自身。( https://developer.android.com/reference/android/widget/BaseAdapter

If you are fetching images one by one, refreshing the view might not be the best solution. 如果要一张一张地获取图像,则刷新视图可能不是最佳解决方案。 If you don't want it to scroll to top of the page whenever a new image downloaded, you can use notifyItemRangeInserted(int positionStart, int itemCount) 如果您不希望每次下载新图像时都将其滚动到页面顶部,则可以使用notifyItemRangeInserted(int positionStart, int itemCount)

Also please have a look at this question 还请看看这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM