【问题标题】:RecyclerView only loads the image on scrollingRecyclerView 仅在滚动时加载图像
【发布时间】:2023-03-09 22:30:02
【问题描述】:

这是我的活动:

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private List<GalleryItem> mGalleryItems;
    GalleryAdapter adapter;
    private boolean loading = true;
    int pastVisiblesItems, visibleItemCount, totalItemCount;
    LinearLayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = (RecyclerView) findViewById(R.id.grid_view);
        mGalleryItems = new ArrayList<>();
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        getItems("http://www.reddit.com/r/aww.json");
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {
                    visibleItemCount = mLayoutManager.getChildCount();
                    totalItemCount = mLayoutManager.getItemCount();
                    pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
                    if (loading) {
                        if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
                            loading = false;
                            Log.v("...", "Last Item Wow !");
                            getItems("https://www.reddit.com/r/aww.json?after=t3_40x6ke");
                        }
                    }
                }
            }
        });

        adapter = new GalleryAdapter(mGalleryItems, this);
        mRecyclerView.setAdapter(adapter);

    }


    @Override
    public void onDestroy(){
        super.onDestroy();

    }
    public void getItems(String url){
        OkHttpClient client = new OkHttpClient();
        File cacheDirectory = new File(MainActivity.this.getCacheDir(), "http");
        int cacheSize = 10 * 1024 * 1024;
        Cache cache = new Cache(cacheDirectory, cacheSize);
        client.setCache(cache);
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {

            }

            @Override
            public void onResponse(Response response) throws IOException {
                final String json = response.body().string();
                if (response.isSuccessful()) {
                        try {
                            mGalleryItems.addAll(parseItems(json));
                        } catch (JSONException e) {
                            e.printStackTrace();
                            Log.i("BEHS", e.getMessage());
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                adapter.notifyDataSetChanged();

                            }
                        });
                }
            }
        });

    }

    private List<GalleryItem> parseItems(String json) throws JSONException {
        JSONObject jsonMovie = new JSONObject(json);
        JSONObject firstData = jsonMovie.getJSONObject("data");
        JSONArray children = firstData.getJSONArray("children");

        List<GalleryItem> items = new ArrayList();

        for(int i = 0; i < children.length(); i++ ){
            JSONObject jsonObject = children.getJSONObject(i);
            JSONObject childrenObject = jsonObject.getJSONObject("data");
            GalleryItem item = new GalleryItem();
            item.setTitle(childrenObject.getString("title"));
            item.setUrl(childrenObject.getString("url"));
            item.setThumbnail(childrenObject.getString("thumbnail"));
            //if(!childrenObject.getString("url").endsWith(".jpg")){
         //       continue;
       //     }else{
                items.add(item);
     //       }
        }


        return items;
    }



    private class GalleryHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        private ImageView mImageView;
        private TextView mTextView;
        private String mUrl;

        public GalleryHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            mImageView = (ImageView) itemView.findViewById(R.id.country_photo);
            mTextView = (TextView) itemView.findViewById(R.id.country_name);
        }


        public void bindImage(GalleryItem item ){
            Picasso.with(MainActivity.this).load(item.getThumbnail()).tag(MainActivity.this).into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    Palette pallete = Palette.from(bitmap).generate();
                    int color = pallete.getMutedColor(MainActivity.this.getResources().getColor(android.R.color.black));
                    mTextView.setBackgroundColor(color);
                    mImageView.setImageBitmap(bitmap);
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {

                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {

                }
            });
        }

        public void bindUrl(String url){
            mUrl = url;
        }

        @Override
        public void onClick(View view) {
            Intent i = new Intent(MainActivity.this, ItemActivity.class);
            i.putExtra("url", mUrl);
            Log.i(mUrl, mUrl);
            startActivity(i);

        }
    }

    private class GalleryAdapter extends RecyclerView.Adapter<GalleryHolder>{
        private List<GalleryItem> mImages;
        private Context mContext;

        public GalleryAdapter(List<GalleryItem> images, Context context){
            mContext = context;
            mImages = images;
        }

        @Override
        public GalleryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
            View view = inflater.inflate(R.layout.list_item, parent, false);
            return new GalleryHolder(view);

        }

        @Override
        public void onBindViewHolder(GalleryHolder holder, int position) {
            holder.mTextView.setText(mImages.get(position).getTitle());
            holder.mImageView.setImageBitmap(null);
            holder.bindImage(mImages.get(position));
            holder.bindUrl(mImages.get(position).getUrl());

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

        @Override
        public int getItemCount() {
            return mImages.size();
        }
    }
}

我只有一个 recyclerview 从基于 REST json 的 api 加载图像和文本,列表只有一个 CardView 和一个 TextView,文本加载正常但图像仅在我将卡片滚动到屏幕外时显示,这也仅发生在列表的前 2 个位置,这里有一个视频可以更好地解释:

I dont know how to embbed videos here

如您所见,前两张图片只有在我将它们滚动出屏幕时才会加载

【问题讨论】:

    标签: java android view android-recyclerview picasso


    【解决方案1】:

    您的问题在于 TargetPicasso 仅保留对 Target 对象的弱引用)

    你可以做什么:

    • Target 对象进行强引用(例如,将其保留为ViewHolder 的字段):

       private class GalleryHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
              private ImageView mImageView;
              private TextView mTextView;
              ....
              com.squareup.picasso.Target target = new com.squareup.picasso.Target() {
                  @Override
                  public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                      mTextView.setBackgroundColor(Color.RED);
                      mImageView.setImageBitmap(bitmap);
                  }
      
                  @Override
                  public void onBitmapFailed(Drawable errorDrawable) {}
      
                  @Override
                  public void onPrepareLoad(Drawable placeHolderDrawable) {}
              };
              ....
              public void bindImage(GalleryItem item ){
                  Picasso.with(MainActivity.this).load(item.getThumbnail()).tag(MainActivity.this).into(target);
              }
          }
      
    • 避免使用Target,而是使用.into(mImageView)

    另外,查看这个帖子:https://stackoverflow.com/a/26918731/1658267(在这里你可以找到解释,为什么会这样)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      相关资源
      最近更新 更多