2015-05-15

[Android] 使用RecyclerView和CardView做出一個格狀圖片瀏覽器. Use RecyclerView and CardView for a Grid Image Viewer


This is a Grid image viewer to view images from internet.
You could change it to view image resources or files yourself.

It uses Picasso to load images.
http://square.github.io/picasso/



1. add dependencies to build.gradle
dependencies {
 ...
    compile 'com.android.support:recyclerview-v7:21.0.3'
    compile 'com.android.support:cardview-v7:21.0.3'
}


2. Activity member variable
private static final int GRID_COLUMN = 3;
private RecyclerView mRecyclerView;
private GridAdapter mAdapter;





3. Activity onCreate
mAdapter = new GridAdapter(this);
// Calling the RecyclerView
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
// The number of Columns
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this, GRID_COLUMN);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);


4. Add a Grid Adapter class for the grid RecyclerView
 /** Grid Adapter for Grid View
 */
class GridAdapter extends RecyclerView.Adapter {

    private Context mContext;
    private List mItems;

    GridAdapter(Context context) {
        super();
        mItems = new ArrayList<>();
        mContext = context;
    }

    public void clear() {
        mItems.clear();
        notifyDataSetChanged();
    }

    public boolean add(String item) {
        boolean returnValue = mItems.add(item);
        notifyItemInserted(mItems.size() - 1);
        return returnValue;
    }

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

        View view = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.image_grid_item_layout, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        view.setOnClickListener(viewHolder);
        return viewHolder;
    }

    @Override public void onBindViewHolder(ViewHolder holder, int position) {
        Picasso.with(mContext)
                .load(mItems.get(position))
                .placeholder(R.drawable.ic_photo_big)
                .error(R.drawable.ic_cancel_big)
                .into(holder.mImageView);
        holder.setPosition(position);
    }

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

    /**
     * View Holder for Grid View Items
     */
    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private int mPos = -1;
        public ImageView mImageView;

        public ViewHolder(View itemView) {
            super(itemView);
            mImageView = (ImageView) itemView.findViewById(R.id.img_thumbnail);
        }

        void setPosition(int pos) {
            mPos = pos;
        }

        @Override public void onClick(View v) {
            if (mPos < 0 || mPos >= mItems.size()) {
                return;
            }
            Log.d(DEBUG_TAG, "IMG onItemClick, pos=" + mPos + ", url=" + mItems.get(mPos));
            startImageViewActivity(mPos);
        }
    }

}

5. use
mAdapter.add(url); 
to add item to Grid
    or use
mAdapter.clear();
to clear Grid items

You can add other methods to modify the list by yourself, ex, mAdapter.delete(url).


6. the layout of the activity
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#ff000000"
                tools:context="com.example.viki_hung.imageforumviewer.ImageGridActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@ id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

7. the layout of the Grid Items
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 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="match_parent"
              android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="9dp"
        card_view:cardCornerRadius="3dp"
        card_view:cardElevation="0.01dp">

        <com.example.viki_hung.imageforumviewer.SquareImageView
            android:id="@ id/img_thumbnail"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#FF444444"
            android:scaleType="centerCrop"/>

    </android.support.v7.widget.CardView>
</LinearLayout>

8. SquareImageView
public class SquareImageView extends ImageView {

    public SquareImageView(Context context) {
        super(context);
    }

    public SquareImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
    }

}