123
123

Reputation: 51

RecyclerView and CardView Click listener implementation

I just moved into the android RecyclerView and CardViewand ... and realized recyclerview don't have an option for Onclick listner, but after implement this feature, i just don't see any result.

hear is my code and layouts:

MainActivity:

public class MainActivity extends AppCompatActivity {

    //private usefulSites_RecyclerView_Adapter mAdapter;
    final Context context = this;
    private RecyclerView mRecyclerView;
    private StaggeredGridLayoutManager mGridLayoutManager;
    private RecyclerViewAdapter mAdapter;
    private String[] mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
        CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
        mCollapsingToolbarLayout.setTitle("test");
        //通过CollapsingToolbarLayout修改字体颜色
        mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
        mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);


        //mList = getResources().getStringArray(R.array.numbers);

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.setLayoutManager(mGridLayoutManager);
        mAdapter = new RecyclerViewAdapter(getApplicationContext());
        mRecyclerView.setAdapter(mAdapter);


    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

RecyclerViewAdapter

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

    private Context mContext;
    private String [] mSiteTitle,mSiteLink;
    private int [] mThumbnail;

    public RecyclerViewAdapter(Context contexts, String[] list) {
        this.mContext = contexts;
        this.mSiteTitle = list;
    }
    public RecyclerViewAdapter(Context contexts) {
        this.mContext = contexts;
        initList();
    }
    private void initList(){

        UsfulSite_init mInit=new UsfulSite_init();
        mSiteTitle= mInit.initSiteTitle();
        mSiteLink=mInit.initSiteLink();
        mThumbnail=mInit.initThumbnail();


    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.usful_sites_card_view, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.sTitle.setText(mSiteTitle[position]);
        holder.sLink.setText(mSiteTitle[position]);
        holder.sImage.setImageResource(mThumbnail[position]);


        holder.setClickListener(new ItemClickListener() {
            @Override
            public void onClick(View view, int position, boolean isLongClick) {
                if (isLongClick) {
                    Toast.makeText(mContext, "#" + position + " - " + mSiteTitle[position] + " (Long click)", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(mContext, "#" + position + " - " + mSiteTitle[position], Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return mSiteTitle.length;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder
            implements View.OnClickListener, View.OnLongClickListener{
        private TextView sTitle,sLink;
        private ImageView sImage;
        private ItemClickListener clickListener;

        public ViewHolder(View itemView) {
            super(itemView);
            sTitle = (TextView)itemView.findViewById(R.id.useful_sites_Title);
            sLink=(TextView)itemView.findViewById(R.id.useful_sites_Link);
            sImage=(ImageView)itemView.findViewById(R.id.useful_sites_thumbnail);
            itemView.setTag(itemView);
            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);


        }

        public void setClickListener(ItemClickListener itemClickListener) {
            this.clickListener = itemClickListener;
        }

        @Override
        public void onClick(View view) {
            clickListener.onClick(view, getPosition(), false);
        }

        @Override
        public boolean onLongClick(View view) {
            clickListener.onClick(view, getPosition(), true);
            return true;
        }
    }
}

Activity_main.xml:

<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout

    android:layout_width="match_parent"
    android:layout_height="256dp"
    android:fitsSystemWindows="true">
    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        app:contentScrim="#30469b"
        app:expandedTitleMarginStart="48dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">
        <ImageView

            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/a"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.7"  />
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin" />
    </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none" />
</LinearLayout>

CardView Layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="5dp"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="4dp"
android:layout_height="match_parent">

<RelativeLayout

    android:id="@+id/mainHolder"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/useful_sites_thumbnail"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:tint="@color/photo_tint"
        android:layout_centerInParent="true"
        />

    <TextView
        android:id="@+id/useful_sites_Title"
        android:gravity="center"
        android:background="?android:selectableItemBackground"
        android:focusable="true"
        android:clickable="true"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:textSize="24sp"
        android:layout_centerInParent="true"
        android:textColor="@android:color/white"
        />
    <TextView
        android:id="@+id/useful_sites_Link"
        android:gravity="center"
        android:background="?android:selectableItemBackground"
        android:focusable="true"
        android:clickable="true"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:textSize="24sp"
        android:layout_centerInParent="true"
        android:textColor="@android:color/white"
        android:visibility="gone"
        />
</RelativeLayout>

I tested another ways for clickListner in RV butT, i just stuck in this. can some one look at my code and guide me, Little about this.

Upvotes: 3

Views: 25938

Answers (4)

Davidgh
Davidgh

Reputation: 9

You Can Add your listener into constructor of View Holder.

public ViewHolder(View v) {
    super(v);
    title = (TextView) v.findViewById(R.id.album_list_title);
    count = (TextView) v.findViewById(R.id.album_list_count);
    picture = (ImageView) v.findViewById(R.id.album_list_picture);

    v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Handel yout event here
            }
        });
}

Upvotes: 0

Victor Dumont
Victor Dumont

Reputation: 13

The answer from VLeong works great for me! But a little clarification. This : holder.cardView.setOnClickListener(new View.OnClickListener() { need to be changed to :

holder.itemView.setOnClickListener(new View.OnClickListener(){

Upvotes: 1

Norutan
Norutan

Reputation: 1520

If you want to implement onClick for each cardview, you can do like this: in your XML:

<android.support.v7.widget.CardView
    android:id="@+id/card_view">

    ...

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

Then, in your adapter code:

public static class ViewHolder extends RecyclerView.ViewHolder {
        private CardView cardView;

        public ViewHolder(View itemView) {
            super(itemView);
            cardView = (CardView) itemView.findViewById(R.id.card_view);
        }
}

...

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //implement onClick
                System.out.println("Clicked");
            }
        });
    }
}

Upvotes: 8

Dmitrijs
Dmitrijs

Reputation: 1393

You can pass listener from Adapter to ViewHolder, and listen events there, and you also can pass event from Adapter to your Activity or where you create this Adapter

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

private List<Album> albums;
private Context context;
public AlbumAdapterClickListener recListener;

public AlbumAdapter(List<Album> albums, Context context, AlbumAdapterClickListener recListener) {
    this.albums = albums;
    this.context = context;
    this.recListener = recListener;
}

public interface AlbumAdapterClickListener {
    void recyclerViewClick(String albumID);
}


public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView title;
    public TextView count;
    public ImageView picture;
    public String albumID;
    public AlbumClickListener listener;

    //listener passed to viewHolder
    public interface AlbumClickListener {
        void albumOnClick(String albumID);
    }

    public ViewHolder(View v, AlbumClickListener listener) {
        super(v);
        title = (TextView) v.findViewById(R.id.album_list_title);
        count = (TextView) v.findViewById(R.id.album_list_count);
        picture = (ImageView) v.findViewById(R.id.album_list_picture);

        this.listener = listener;
        v.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        listener.albumOnClick(this.albumID);
    }
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.album_list_item, viewGroup, false),
            new ViewHolder.AlbumClickListener() {
                @Override
                public void albumOnClick(String albumID) {
                    //TODO show gridView with current albumID
                    Log.e("fdf", albumID);
                    // albumID going to Fragment
                    recListener.recyclerViewClick(albumID);
                }

            });
}


@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    Album album = albums.get(i);
    viewHolder.albumID = album.getId();
    viewHolder.count.setText(album.getPhotoCount());
    viewHolder.title.setText(album.getName());
    Picasso.with(context).load(albums.get(i).getCoverURL()).placeholder(R.mipmap.fb_place_holder).resize(140, 140)
            .centerCrop().into(viewHolder.picture);
}

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

}

Upvotes: 3

Related Questions