Skip to content

Instantly share code, notes, and snippets.

@beraldofilippo
Last active March 7, 2021 16:41
Show Gist options
  • Save beraldofilippo/d8d2404bc6f4217fd1a76166cf23e2d0 to your computer and use it in GitHub Desktop.
Save beraldofilippo/d8d2404bc6f4217fd1a76166cf23e2d0 to your computer and use it in GitHub Desktop.
RecyclerView single and double click listener on items of a RecyclerView.
/**
* Created by Hugo Visser.
* Please see http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/
*
* Modified by Filippo Beraldo:
* - Added OnDoubleClickListener in place of the standard OnClickListener.
*/
public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnDoubleClickListener mOnDoubleClickListener = new OnDoubleClickListener() {
@Override
public void onDoubleClick(View v) {
if (mOnItemClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemDoubleClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
@Override
public void onSingleClick(View v) {
if (mOnItemClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
= new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(View view) {
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnDoubleClickListener);
}
}
@Override
public void onChildViewDetachedFromWindow(View view) {
}
};
private ItemClickSupport(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mRecyclerView.setTag(R.id.item_click_support, this);
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support == null) {
support = new ItemClickSupport(view);
}
return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support != null) {
support.detach(view);
}
return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
return this;
}
private void detach(RecyclerView view) {
view.removeOnChildAttachStateChangeListener(mAttachListener);
view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
void onItemDoubleClicked(RecyclerView recyclerView, int position, View v);
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.grid, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),
2, GridLayoutManager.VERTICAL, false));
// Make sure your recyler view adapter implements getItemAt(position), which return the item from the dataset placed at position
// in this case I use getProductId() from my POJO Product class
ItemClickSupport.addTo(mRecyclerView)
.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
Log.d("ITEM CLICK", "Item single clicked " + mRecyclerViewAdapter.getItemAt(position).getProductId());
}
@Override
public void onItemDoubleClicked(RecyclerView recyclerView, int position, View v) {
Log.d("ITEM CLICK", "Item double clicked " + mRecyclerViewAdapter.getItemAt(position).getProductId());
}
});
return rootView;
}
/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Please see
* https://github.com/wireapp/wire-android/blob/master/wire-ui/src/main/java/com/waz/zclient/ui/views/OnDoubleClickListener.java
*/
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Doesn't care about which view is clicked, so should only be used for a single View.
*
* Modified by Filippo Beraldo on 02/02/17:
* - Added the ability to pass the View v when the click event occurs.
*/
public abstract class OnDoubleClickListener implements View.OnClickListener {
private final int doubleClickTimeout;
private Handler handler;
private long firstClickTime;
public OnDoubleClickListener() {
doubleClickTimeout = ViewConfiguration.getDoubleTapTimeout();
firstClickTime = 0L;
handler = new Handler(Looper.getMainLooper());
}
@Override
public void onClick(final View v) {
long now = System.currentTimeMillis();
if (now - firstClickTime < doubleClickTimeout) {
handler.removeCallbacksAndMessages(null);
firstClickTime = 0L;
onDoubleClick(v);
} else {
firstClickTime = now;
handler.postDelayed(new Runnable() {
@Override
public void run() {
onSingleClick(v);
firstClickTime = 0L;
}
}, doubleClickTimeout);
}
}
public abstract void onDoubleClick(View v);
public abstract void onSingleClick(View v);
public void reset() {
handler.removeCallbacksAndMessages(null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment