Skip to content

Commit fbb5b62

Browse files
committed
Added ViewHolders for simple click/longClick and menu functionalities
1 parent 45ebed3 commit fbb5b62

File tree

4 files changed

+188
-2
lines changed

4 files changed

+188
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ The latest AAR (Android Archive) files can be downloaded from JCenter [RecyclerE
2323
Or included in your gradle dependencies
2424

2525
```groovy
26-
compile 'com.devbrackets.android:recyclerext:0.12.2'
26+
compile 'com.devbrackets.android:recyclerext:0.12.3'
2727
```
2828

2929

library/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ apply plugin: 'bintray-release'
44

55
def versionMajor = 0
66
def versionMinor = 12
7-
def versionPatch = 2
7+
def versionPatch = 3
88

99
// Maven GAV
1010
def libraryGroupId = 'com.devbrackets.android'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.devbrackets.android.recyclerext.adapter.viewholder;
2+
3+
import android.support.annotation.Nullable;
4+
import android.support.v7.widget.RecyclerView;
5+
import android.view.HapticFeedbackConstants;
6+
import android.view.View;
7+
8+
/**
9+
* A Simple ViewHolder that adds the ability to specify
10+
* listeners that have access to the ViewHolder instead
11+
* of a position when clicked
12+
*/
13+
public abstract class ClickableViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
14+
15+
public interface OnClickListener {
16+
void onClick(ClickableViewHolder viewHolder);
17+
}
18+
19+
public interface OnLongClickListener {
20+
boolean onLongClick(ClickableViewHolder viewHolder);
21+
}
22+
23+
@Nullable
24+
private OnClickListener onClickListener;
25+
@Nullable
26+
private OnLongClickListener onLongClickListener;
27+
28+
protected boolean performLongClickHapticFeedback = true;
29+
30+
public ClickableViewHolder(View itemView) {
31+
super(itemView);
32+
initializeClickListener();
33+
}
34+
35+
/**
36+
* Sets the click and long click listeners on the root
37+
* view (see {@link #itemView})
38+
*/
39+
protected void initializeClickListener() {
40+
itemView.setOnClickListener(this);
41+
itemView.setOnLongClickListener(this);
42+
}
43+
44+
/**
45+
* Enables or Disables haptic feedback on long clicks. If a
46+
* long click listener has not been set with {@link #setOnLongClickListener(OnLongClickListener)}
47+
* then no haptic feedback will be performed.
48+
*
49+
* @param enabled True if the long click should perform a haptic feedback [default: true]
50+
*/
51+
public void setHapticFeedbackEnabled(boolean enabled) {
52+
performLongClickHapticFeedback = enabled;
53+
}
54+
55+
public void setOnClickListener(@Nullable OnClickListener onClickListener) {
56+
this.onClickListener = onClickListener;
57+
}
58+
59+
public void setOnLongClickListener(@Nullable OnLongClickListener onLongClickListener) {
60+
this.onLongClickListener = onLongClickListener;
61+
}
62+
63+
@Override
64+
public void onClick(View view) {
65+
if (onClickListener != null) {
66+
onClickListener.onClick(this);
67+
}
68+
}
69+
70+
@Override
71+
public boolean onLongClick(View v) {
72+
if (onLongClickListener != null) {
73+
if (performLongClickHapticFeedback) {
74+
itemView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
75+
}
76+
77+
return onLongClickListener.onLongClick(this);
78+
}
79+
80+
return false;
81+
}
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.devbrackets.android.recyclerext.adapter.viewholder;
2+
3+
import android.support.annotation.IdRes;
4+
import android.support.annotation.MenuRes;
5+
import android.support.annotation.Nullable;
6+
import android.support.v7.widget.PopupMenu;
7+
import android.view.Menu;
8+
import android.view.MenuInflater;
9+
import android.view.MenuItem;
10+
import android.view.View;
11+
12+
/**
13+
* A simple ViewHolder that extends {@link ClickableViewHolder} to provide the
14+
* functionality for providing and registering for popup menu selection events
15+
*/
16+
public abstract class MenuViewHolder extends ClickableViewHolder implements PopupMenu.OnMenuItemClickListener {
17+
18+
public interface OnMenuItemSelectedListener {
19+
boolean onMenuItemSelected(MenuViewHolder viewHolder, MenuItem menuItem);
20+
}
21+
22+
@Nullable
23+
private OnMenuItemSelectedListener onMenuItemSelectedListener;
24+
25+
/**
26+
* Retrieves the id for the view that will be used to show the
27+
* popup menu when clicked.
28+
*
29+
* @return The resource id for the menu view
30+
*/
31+
@IdRes
32+
protected abstract int getMenuViewId();
33+
34+
/**
35+
* Retrieves the id for the xml menu resource that specifies
36+
* the options for the popup menu.
37+
*
38+
* @return The resource id for the xml menu
39+
*/
40+
@MenuRes
41+
protected abstract int getMenuResourceId();
42+
43+
public MenuViewHolder(View itemView) {
44+
super(itemView);
45+
initializeMenuClickListener();
46+
}
47+
48+
public void setOnMenuItemSelectedListener(@Nullable OnMenuItemSelectedListener listener) {
49+
this.onMenuItemSelectedListener = listener;
50+
}
51+
52+
@Override
53+
public boolean onMenuItemClick(MenuItem item) {
54+
return onMenuItemSelectedListener != null && onMenuItemSelectedListener.onMenuItemSelected(this, item);
55+
}
56+
57+
/**
58+
* Registers the view specified with {@link #getMenuViewId()} to
59+
* show the popup menu specified with {@link #getMenuResourceId()}
60+
*/
61+
protected void initializeMenuClickListener() {
62+
View menuView = itemView.findViewById(getMenuViewId());
63+
if (menuView != null) {
64+
menuView.setOnClickListener(new MenuClickListener());
65+
}
66+
}
67+
68+
/**
69+
* Shows the menu specified with the <code>menuResourceId</code> starting
70+
* at the <code>anchor</code>
71+
*
72+
* @param anchor The view to show the popup menu from
73+
* @param menuResourceId The resource id for the menu to show
74+
*/
75+
protected void showMenu(View anchor, @MenuRes int menuResourceId) {
76+
PopupMenu menu = new PopupMenu(anchor.getContext(), anchor);
77+
MenuInflater inflater = menu.getMenuInflater();
78+
inflater.inflate(menuResourceId, menu.getMenu());
79+
80+
onPreparePopupMenu(menu.getMenu());
81+
menu.setOnMenuItemClickListener(this);
82+
menu.show();
83+
}
84+
85+
/**
86+
* Allows the user to customize the popup menu specified with {@link #getMenuResourceId()}
87+
* before it is shown
88+
*
89+
* @param menu The menu to customize
90+
*/
91+
protected void onPreparePopupMenu(Menu menu) {
92+
//Purposefully left blank
93+
}
94+
95+
/**
96+
* A simple click listener class to handle menu view clicks
97+
*/
98+
protected class MenuClickListener implements View.OnClickListener {
99+
@Override
100+
public void onClick(View view) {
101+
showMenu(view, getMenuResourceId());
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)