This example work on last example of "Gallery-like RecyclerView + CardView example" to show how to add a button and OnClickListener in RecyclerView + CardView. A ImageButton is add over the photo on each cell. Once user click on the ImageButton, the corresponding OnClickListener, to show the info of the corresponding photo.
Modify layout/layout_cardview.xml to add a ImageButton.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
card_view:cardCornerRadius="5sp"
card_view:cardElevation="5sp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageButton
android:id="@+id/buttonInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_menu_info_details"
android:background="#00ffffff"/>
</FrameLayout>
</android.support.v7.widget.CardView>
Modify MyRecyclerViewAdapter.java:
- get the reference to the Button in the constructor of RecyclerView.ViewHolder.
- implement the OnClickListener in onBindViewHolder() of MyRecyclerViewAdapter.
package com.blogspot.android_er.androidgallery;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ItemHolder>{
private List<Uri> itemsUri;
private LayoutInflater layoutInflater;
private Context context;
private OnItemClickListener onItemClickListener;
MainActivity mainActivity;
public MyRecyclerViewAdapter(Context context, MainActivity mainActivity){
this.context = context;
layoutInflater = LayoutInflater.from(context);
itemsUri = new ArrayList<Uri>();
this.mainActivity = mainActivity;
}
@Override
public MyRecyclerViewAdapter.ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardView itemCardView = (CardView)layoutInflater.inflate(R.layout.layout_cardview, parent, false);
return new ItemHolder(itemCardView, this);
}
@Override
public void onBindViewHolder(MyRecyclerViewAdapter.ItemHolder holder, final int position) {
final Uri targetUri = itemsUri.get(position);
holder.setItemUri(targetUri.getPath());
if (targetUri != null){
try {
//! CAUTION !
//I'm not sure is it properly to load bitmap here!
holder.setImageView(loadScaledBitmap(targetUri));
holder.btnInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,
"btnInfo clicked:\n"
+ "position:" + position + "\n"
+ targetUri.getLastPathSegment(),
Toast.LENGTH_LONG).show();
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
/*
reference:
Load scaled bitmap
http://android-er.blogspot.com/2013/08/load-scaled-bitmap.html
*/
private Bitmap loadScaledBitmap(Uri src) throws FileNotFoundException {
//display the file to be loadScaledBitmap(),
//such that you can know how much work on it.
mainActivity.textInfo.append(src.getLastPathSegment() + "\n");
// required max width/height
final int REQ_WIDTH = 150;
final int REQ_HEIGHT = 150;
Bitmap bm = null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(context.getContentResolver().openInputStream(src),
null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, REQ_WIDTH,
REQ_HEIGHT);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeStream(
context.getContentResolver().openInputStream(src), null, options);
return bm;
}
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
@Override
public int getItemCount() {
return itemsUri.size();
}
public void setOnItemClickListener(OnItemClickListener listener){
onItemClickListener = listener;
}
public OnItemClickListener getOnItemClickListener(){
return onItemClickListener;
}
public interface OnItemClickListener{
public void onItemClick(ItemHolder item, int position);
}
public void add(int location, Uri iUri){
itemsUri.add(location, iUri);
notifyItemInserted(location);
}
public void clearAll(){
int itemCount = itemsUri.size();
if(itemCount>0){
itemsUri.clear();
notifyItemRangeRemoved(0, itemCount);
}
}
public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private MyRecyclerViewAdapter parent;
private CardView cardView;
ImageView imageView;
String itemUri;
ImageButton btnInfo;
public ItemHolder(CardView cardView, MyRecyclerViewAdapter parent) {
super(cardView);
itemView.setOnClickListener(this);
this.cardView = cardView;
this.parent = parent;
imageView = (ImageView) cardView.findViewById(R.id.item_image);
btnInfo = (ImageButton) cardView.findViewById(R.id.buttonInfo);
}
public void setItemUri(String itemUri){
this.itemUri = itemUri;
}
public String getItemUri(){
return itemUri;
}
public void setImageView(Bitmap bitmap){
imageView.setImageBitmap(bitmap);
}
@Override
public void onClick(View v) {
final OnItemClickListener listener = parent.getOnItemClickListener();
if(listener != null){
listener.onItemClick(this, getLayoutPosition());
//or use
//listener.onItemClick(this, getAdapterPosition());
}
}
}
}
~ More example of RecyclerView + CardView.
3 comments:
Hi
------------------------
I want to do app read the text from the WebView or convert WebView page Content to text
using C# Xamarin.Android code
-------------------------
https://drive.google.com/file/d/0B57zljJtEWstVERPOGYyX2Z3d1U/view?usp=sharing
Thanks for sharing your knowledge with everyone, I wanted to ask how I can place a spinner in a recyclcerview, you have some tutorial or link about this, you appreciate too.
Thank you.
I had some problem and i couldn't find any clues to solve it.
finally, i got clue in your posting.
-the problem was i forgot adding "final"-
Thank you again from Korea! :)
Post a Comment