我已经搜索了论坛并找到了这个
How to replace gridView to RecyclerView
我对以上给出的答案不满意。
有没有一种更简单的方法,我可以在gridview中插入而不是重新创建新的适配器。
我一直在尝试遵循此Simple Android grid example using RecyclerView with GridLayoutManager (like the old GridView),但遇到这样的错误
多个dex文件定义了Landroid / support / design / widget / CoordinatorLayout $ ViewElevationComparator;
下面是我的代码。
MainActivity
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);
}
}
ImageAdapter
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.错误是什么?
答案 0 :(得分:1)
您的适配器如下所示:
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;
}
}
}
答案 1 :(得分:0)
我声明int column = 3
,即创建多少列。
在您的活动代码中创建如下所示:
public class MyActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
int column = 3;
mLayoutManager = reyclerView.setLayoutManager(new GridLayoutManager(context,column));
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
并创建一些适配器,如下所示:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
private Context mContext;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public ImageView mImageView;
public MyViewHolder(ImageView v) {
super(v);
mTextView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset, Context context) {
mDataset = myDataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
ImageView imageView = (ImageView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
...
MyViewHolder vh = new MyViewHolder(imageView);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
GlideApp
.with(mContext)
.load(mDataSet.getPosition(position).imageUrl)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.into(holder.mImageView);
holder.mImageView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
}