I have search the forum and found this
How to replace gridView to RecyclerView
I am not sastisfy with the answer given above.
Is there a simpler way that i can slot in the gridview instead of recreating a new adapter.
I had been trying to follow this Simple Android grid example using RecyclerView with GridLayoutManager (like the old GridView), but get an error like this
Multiple dex files define Landroid/support/design/widget/CoordinatorLayout$ViewElevationComparator;
Below are my code.
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;
}
}
}
Questions:
1. How to make this work?
2. What is the error about?