RecyclerView生涩,只有小的png图标,Android

时间:2016-11-29 20:00:00

标签: android android-recyclerview

我有一个RecyclerView,带有一个简单的TextView和一个ImageView,它是一个小图标(国家的一面旗帜)。每个图标介于2kb和10kb之间,这对我来说似乎很小。图标都存储在可绘制文件夹中。

然而,滚动时,它不是很平滑。它抽搐。

我有这段代码:

    search = (EditText) findViewById( R.id.search);
    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setNestedScrollingEnabled(false);

这是我的适配器:

public class CountryAdapter extends RecyclerView.Adapter<CountryViewHolder> {

    private ArrayList<Country> countryArrayList;
    private Context context;

    public CountryAdapter(ArrayList<Country> countryArrayList, Context context) {
        this.countryArrayList = countryArrayList;
        this.context = context;
    }

    @Override
    public CountryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.country_item, parent, false);

        return new CountryViewHolder(itemView);

    }

    @Override
    public void onBindViewHolder(CountryViewHolder holder, int position) {


        final Country currentCountry = countryArrayList.get(position);

        holder.countryItemLinearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, currentCountry.getCountry().toString(), Toast.LENGTH_SHORT).show();
            }
        });

        holder.countryTextView.setText(currentCountry.getCountry());
        holder.countryFlagImageView.setImageResource(currentCountry.getFlag());


    }

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

1 个答案:

答案 0 :(得分:1)

我之前也遇到过这个问题。解决此问题的方法是异步加载资源中的位图,然后在图像加载完成后将其设置在图像上。这基本上就是我的系统。

public class LoadImage extends AsyncTask<Void, Void, Bitmap> {

    private Context context;

    private ImageView imageView;
    private int imageResource;

    public LoadImage(Context context, ImageView imageView, int imageResource) {
        this.context = context;
        this.imageView = imageView;
        this.imageResource = imageResource;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        return BitmapFactory.decodeResource(context.getResources(), imageResource);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);

        imageView.setImageBitmap(bitmap);
    }
}

然后你这样称呼它:

new LoadImage(context, holder.countryFlagImageView, currentCountry.getFlag()).execute();

这会将位图的解码移动到一个单独的线程中,这样它就不会阻止你的RecyclerView

如果你把它放在你的holder类中,当你调用它时,你将它设置为一个变量,如果该视图在任务完成之前被回收,你可以取消该过程。像这样:

持有人类

public class CountryViewHolder extends RecyclerView.ViewHolder {

    public AsyncTask imageLoadTask;

    public void setImage(Context context, ImageView imageView, int resource){
        imageLoadTask = new LoadImage(context, imageView, resource);
        imageLoadTask.execute();
    }

}

从上面调用

@Override
public void onBindViewHolder(CountryViewHolder holder, int position) {

    final Country currentCountry = countryArrayList.get(position);

    holder.setImage(holder.countryFlagImageView.getContext(), holder.countryFlagImageView, currentCountry.getFlag());

}

然后在适配器中添加此覆盖:

@Override
public void onViewRecycled(FeedHolder holder) {
    super.onViewRecycled(holder);
    holder.imageLoadTask.cancel(true);
}

这基本上导致它只解码当前屏幕上的视图的资源。

希望它有所帮助!