首页 > 解决方案 > 将gridview替换为recyclerview

问题描述

我搜索了论坛,发现这个
如何将 gridView 替换为 RecyclerView 我对上面给出的答案不满意。
有没有一种更简单的方法可以让我插入 gridview 而不是重新创建一个新的适配器。

我一直在尝试使用 RecyclerView 和 GridLayoutManager(如旧的 GridView)来遵循这个简单的 Android 网格示例,但是得到一个像这样的错误
Multiple dex files define Landroid/support/design/widget/CoordinatorLayout$ViewElevationComparator;

下面是我的代码。

主要活动

public class Main3Activity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

MyRecyclerViewAdapter adapter;

String[] files;

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

    //------------------------
    AssetManager am = getAssets();
    try {
        files  = am.list("img");

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rv);
        int numberOfColumns = 3;
        recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapter = new MyRecyclerViewAdapter(this);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);


    } catch (IOException e) {
        Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_SHORT);
    }

}

@Override
public void onItemClick(View view, int position) {
    Intent intent = new Intent(getApplicationContext(), PuzzleActivity.class);
    intent.putExtra("assetName", files[position % files.length]);
    startActivity(intent);
}

}

图像适配器

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

private String[] mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;

private Context mContext;
private AssetManager am;
private String[] files;

// data is passed into the constructor
MyRecyclerViewAdapter(Context context) {
    this.mInflater = LayoutInflater.from(context);
    //this.mData = data;

    mContext = context;
    am = mContext.getAssets();
    try {
        mData  = am.list("img");
    } catch (IOException e) {
        e.printStackTrace();
    }

}

// inflates the cell layout from xml when needed
@Override
@NonNull
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
    return new ViewHolder(view);
}

// binds the data to the TextView in each cell
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    holder.myTextView.setText(mData[position]);
}

// total number of cells
@Override
public int getItemCount() {
    return mData.length;
}


// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView myTextView;

    ViewHolder(View itemView) {
        super(itemView);
        myTextView = itemView.findViewById(R.id.info_text);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());

    }
}

// convenience method for getting data at click position
String getItem(int id) {
    return mData[id];
}

// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
    this.mClickListener = itemClickListener;
}

// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}


//---------------------------------------------------------------------
// create a new ImageView for each item referenced by the Adapter
public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        convertView = layoutInflater.inflate(R.layout.grid_element, null);
    }

    final ImageView imageView = convertView.findViewById(R.id.gridImageview);
    imageView.setImageBitmap(null);
    // run image related code after the view was laid out
    imageView.post(new Runnable() {
        @Override
        public void run() {
            new AsyncTask<Void, Void, Void>() {
                private Bitmap bitmap;
                @Override
                protected Void doInBackground(Void... voids) {
                    bitmap = getPicFromAsset(imageView, files[position]);
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    imageView.setImageBitmap(bitmap);
                }
            }.execute();
        }
    });

    return convertView;
}

private Bitmap getPicFromAsset(ImageView imageView, String assetName) {
    // Get the dimensions of the View
    int targetW = imageView.getWidth();
    int targetH = imageView.getHeight();

    if(targetW == 0 || targetH == 0) {
        // view has no dimensions set
        return null;
    }

    try {
        InputStream is = am.open("img/" + assetName);
        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

        is.reset();

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        return BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
    } catch (IOException e) {
        e.printStackTrace();

        return null;
    }
}

}

问题:
1.如何使这项工作?
2. 错误是什么?

标签: androidandroid-recyclerview

解决方案


您的适配器将如下所示:

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

private String[] mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;

private Context mContext;
private AssetManager am;
private String[] files;

// data is passed into the constructor
MyRecyclerViewAdapter(Context context) {
    this.mInflater = LayoutInflater.from(context);
    //this.mData = data;

    mContext = context;
    am = mContext.getAssets();
    try {
        mData = am.list("img");
    } catch (IOException e) {
        e.printStackTrace();
    }

}

// inflates the cell layout from xml when needed
@Override
@NonNull
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = mInflater.inflate(R.layout.grid_element, parent, false);
    return new ViewHolder(view);
}

// binds the data to the TextView in each cell
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    //        holder.myTextView.setText(mData[position]);
    holder.imageView.setImageBitmap(null);
    // run image related code after the view was laid out
    holder.imageView.post(new Runnable() {
        @Override
        public void run() {
            new AsyncTask<Void, Void, Void>() {
                private Bitmap bitmap;

                @Override
                protected Void doInBackground(Void... voids) {
                    bitmap = getPicFromAsset(holder.imageView, files[position]);
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    holder.imageView.setImageBitmap(bitmap);
                }
            }.execute();
        }
    });
}

// total number of cells
@Override
public int getItemCount() {
    return mData.length;
}


// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    //        TextView myTextView;
    ImageView imageView;

    ViewHolder(View itemView) {
        super(itemView);
    //            myTextView = itemView.findViewById(R.id.info_text);
        imageView = itemView.findViewById(R.id.gridImageview);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());

    }
}

// convenience method for getting data at click position
String getItem(int id) {
    return mData[id];
}

// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
    this.mClickListener = itemClickListener;
}

// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}

private Bitmap getPicFromAsset(ImageView imageView, String assetName) {
    // Get the dimensions of the View
    int targetW = imageView.getWidth();
    int targetH = imageView.getHeight();

    if (targetW == 0 || targetH == 0) {
        // view has no dimensions set
        return null;
    }

    try {
        InputStream is = am.open("img/" + assetName);
        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);

        is.reset();

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        return BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
    } catch (IOException e) {
        e.printStackTrace();

        return null;
    }
}
}

推荐阅读