Skip to content

Commit 53faea1

Browse files
committed
Add: ObjectAdapter add filtering function
1 parent 392ae7b commit 53faea1

File tree

9 files changed

+237
-11
lines changed

9 files changed

+237
-11
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
</activity>
2828
<activity android:name=".activity.SwipeLayoutActivity">
2929
</activity>
30+
<activity android:name=".activity.DataFilterActivity">
31+
</activity>
3032
</application>
3133

3234
</manifest>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.cncoderx.test.recyclerviewhelper.activity;
2+
3+
import android.app.AlertDialog;
4+
import android.content.DialogInterface;
5+
import android.support.v7.widget.RecyclerView;
6+
import android.text.TextUtils;
7+
import android.view.Menu;
8+
import android.view.MenuItem;
9+
import android.widget.EditText;
10+
11+
import com.cncoderx.recyclerviewhelper.RecyclerViewHelper;
12+
import com.cncoderx.test.recyclerviewhelper.R;
13+
import com.cncoderx.test.recyclerviewhelper.adapter.AlbumAdapter;
14+
import com.cncoderx.test.recyclerviewhelper.data.AlbumManager;
15+
import com.cncoderx.test.recyclerviewhelper.utils.Layout;
16+
17+
public class DataFilterActivity extends RecyclerViewActivity {
18+
private String mSearchKey;
19+
20+
@Override
21+
protected void onLayoutManagerChanged(Layout layout) {
22+
super.onLayoutManagerChanged(layout);
23+
24+
RecyclerView.Adapter adapter = null;
25+
switch (layout) {
26+
case linear:
27+
adapter = new AlbumAdapter(R.layout.item_album_linear_layout, AlbumManager.obtainAlbumList());
28+
break;
29+
case grid:
30+
adapter = new AlbumAdapter(R.layout.item_album_grid_layout, AlbumManager.obtainAlbumList());
31+
break;
32+
case staggered:
33+
adapter = new AlbumAdapter(R.layout.item_album_staggered_layout, AlbumManager.obtainAlbumList());
34+
break;
35+
}
36+
37+
RecyclerViewHelper.setAdapter(mRecyclerView, adapter);
38+
if (!TextUtils.isEmpty(mSearchKey)) {
39+
RecyclerViewHelper.setFilterText(mRecyclerView, mSearchKey);
40+
}
41+
}
42+
43+
@Override
44+
public boolean onCreateOptionsMenu(Menu menu) {
45+
super.onCreateOptionsMenu(menu);
46+
menu.findItem(R.id.action_search).setVisible(true);
47+
return true;
48+
}
49+
50+
@Override
51+
public boolean onMenuItemSelected(int featureId, MenuItem item) {
52+
super.onMenuItemSelected(featureId, item);
53+
if (item.getItemId() == R.id.action_search) {
54+
final EditText editText = new EditText(this);
55+
editText.setSingleLine();
56+
new AlertDialog.Builder(this)
57+
.setCancelable(false)
58+
.setTitle(android.R.string.search_go)
59+
.setView(editText)
60+
.setNegativeButton(android.R.string.cancel, null)
61+
.setPositiveButton(android.R.string.search_go, new DialogInterface.OnClickListener() {
62+
@Override
63+
public void onClick(DialogInterface dialog, int which) {
64+
mSearchKey = editText.getText().toString();
65+
RecyclerViewHelper.setFilterText(mRecyclerView, mSearchKey);
66+
}
67+
}).show();
68+
}
69+
return true;
70+
}
71+
}

app/src/main/java/com/cncoderx/test/recyclerviewhelper/activity/MainActivity.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ protected void onCreate(Bundle savedInstanceState) {
2020
"Header/Footer View",
2121
"Load More Data",
2222
"Expandable Item",
23-
"Swipe Layout"
23+
"Swipe Layout",
24+
"Data Filter"
2425
}));
2526
}
2627

@@ -42,6 +43,11 @@ protected void onListItemClick(ListView l, View v, int position, long id) {
4243
case 4:
4344
startActivity(new Intent(this, SwipeLayoutActivity.class));
4445
break;
46+
case 5:
47+
startActivity(new Intent(this, DataFilterActivity.class));
48+
break;
49+
default:
50+
break;
4551
}
4652
}
4753
}

app/src/main/java/com/cncoderx/test/recyclerviewhelper/activity/RecyclerViewActivity.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ public boolean onCreateOptionsMenu(Menu menu) {
4747
@Override
4848
public boolean onMenuItemSelected(int featureId, MenuItem item) {
4949
switch (item.getItemId()) {
50-
case R.id.linear_layout:
50+
case R.id.action_linear:
5151
setLinearLayoutManager();
5252
break;
53-
case R.id.grid_layout:
53+
case R.id.action_grid:
5454
setGridLayoutManager();
5555
break;
56-
case R.id.staggered_grid_layout:
56+
case R.id.action_staggered_grid:
5757
setStaggeredGridLayoutManager();
5858
break;
5959
}

app/src/main/java/com/cncoderx/test/recyclerviewhelper/activity/SwipeLayoutActivity.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package com.cncoderx.test.recyclerviewhelper.activity;
22

3+
import android.app.AlertDialog;
4+
import android.content.DialogInterface;
5+
import android.view.Menu;
6+
import android.view.MenuItem;
7+
import android.widget.EditText;
8+
39
import com.cncoderx.recyclerviewhelper.RecyclerViewHelper;
410
import com.cncoderx.test.recyclerviewhelper.R;
511
import com.cncoderx.test.recyclerviewhelper.adapter.AlbumSwipeAdapter;
@@ -30,4 +36,33 @@ protected void onLayoutManagerChanged(Layout layout) {
3036
adapter.setMode(Attributes.Mode.Multiple);
3137
RecyclerViewHelper.setAdapter(mRecyclerView, adapter);
3238
}
39+
40+
@Override
41+
public boolean onCreateOptionsMenu(Menu menu) {
42+
super.onCreateOptionsMenu(menu);
43+
menu.findItem(R.id.action_search).setVisible(true);
44+
return true;
45+
}
46+
47+
@Override
48+
public boolean onMenuItemSelected(int featureId, MenuItem item) {
49+
super.onMenuItemSelected(featureId, item);
50+
if (item.getItemId() == R.id.action_search) {
51+
final EditText editText = new EditText(this);
52+
editText.setSingleLine();
53+
new AlertDialog.Builder(this)
54+
.setCancelable(false)
55+
.setTitle(android.R.string.search_go)
56+
.setView(editText)
57+
.setNegativeButton(android.R.string.cancel, null)
58+
.setPositiveButton(android.R.string.search_go, new DialogInterface.OnClickListener() {
59+
@Override
60+
public void onClick(DialogInterface dialog, int which) {
61+
String mSearchKey = editText.getText().toString();
62+
RecyclerViewHelper.setFilterText(mRecyclerView, mSearchKey);
63+
}
64+
}).show();
65+
}
66+
return true;
67+
}
3368
}

app/src/main/java/com/cncoderx/test/recyclerviewhelper/data/Album.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.cncoderx.test.recyclerviewhelper.data;
22

3+
import android.support.annotation.NonNull;
4+
35
/**
46
* @author cncoderx
57
*/
@@ -40,4 +42,10 @@ public String getCategory() {
4042
public void setCategory(String category) {
4143
this.category = category;
4244
}
45+
46+
@NonNull
47+
@Override
48+
public String toString() {
49+
return name;
50+
}
4351
}
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<menu xmlns:android="http://schemas.android.com/apk/res/android">
2+
<menu xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto">
4+
5+
<item
6+
android:id="@+id/action_search"
7+
android:title="@android:string/search_go"
8+
android:icon="@android:drawable/ic_menu_search"
9+
android:showAsAction="ifRoom"
10+
android:visible="false"/>
11+
312
<item
4-
android:id="@+id/linear_layout"
13+
android:id="@+id/action_linear"
514
android:title="Linear Layout"
615
android:showAsAction="collapseActionView"/>
716

817
<item
9-
android:id="@+id/grid_layout"
18+
android:id="@+id/action_grid"
1019
android:title="Grid Layout"
1120
android:showAsAction="collapseActionView"/>
1221

1322
<item
14-
android:id="@+id/staggered_grid_layout"
23+
android:id="@+id/action_staggered_grid"
1524
android:title="Staggered Grid Layout"
1625
android:showAsAction="collapseActionView"/>
1726
</menu>

library/src/main/java/com/cncoderx/recyclerviewhelper/adapter/ObjectAdapter.java

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,26 @@
55
import android.view.LayoutInflater;
66
import android.view.View;
77
import android.view.ViewGroup;
8+
import android.widget.Filter;
9+
import android.widget.Filterable;
810

911
import com.cncoderx.recyclerviewhelper.utils.Array;
1012
import com.cncoderx.recyclerviewhelper.utils.IArray;
1113

14+
import java.util.ArrayList;
1215
import java.util.Arrays;
1316
import java.util.Collection;
1417
import java.util.Comparator;
1518

1619
/**
1720
* @author cncoderx
1821
*/
19-
public abstract class ObjectAdapter<T> extends BaseAdapter implements IArray<T>, IArray.Callback {
22+
public abstract class ObjectAdapter<T> extends BaseAdapter implements IArray<T>, IArray.Callback, Filterable {
2023
private @LayoutRes int mResource;
21-
private final Array<T> mArray = new Array<>();
24+
private Array<T> mArray = new Array<>();
25+
private Array<T> mOriginalArray;
26+
private ArrayFilter mFilter;
27+
private final Object mLock = new Object();
2228

2329
private boolean mNotifyOnChange = true;
2430
private int mPositionOffset = 0;
@@ -230,4 +236,77 @@ public int getPositionOffset() {
230236
public void setPositionOffset(int positionOffset) {
231237
mPositionOffset = positionOffset;
232238
}
239+
240+
@Override
241+
public Filter getFilter() {
242+
if (mFilter == null) {
243+
mFilter = new ArrayFilter();
244+
}
245+
return mFilter;
246+
}
247+
248+
private class ArrayFilter extends Filter {
249+
250+
@Override
251+
protected FilterResults performFiltering(CharSequence prefix) {
252+
final FilterResults results = new FilterResults();
253+
254+
if (mOriginalArray == null) {
255+
synchronized (mLock) {
256+
mOriginalArray = new Array<>(mArray);
257+
}
258+
}
259+
260+
if (prefix == null || prefix.length() == 0) {
261+
final Array<T> array;
262+
synchronized (mLock) {
263+
array = new Array<>(mOriginalArray);
264+
}
265+
results.values = array;
266+
results.count = array.size();
267+
} else {
268+
final String prefixString = prefix.toString().toLowerCase();
269+
270+
final Array<T> array;
271+
synchronized (mLock) {
272+
array = new Array<>(mOriginalArray);
273+
}
274+
275+
final int count = array.size();
276+
final Array<T> newArray = new Array<>();
277+
278+
for (int i = 0; i < count; i++) {
279+
final T value = array.get(i);
280+
final String valueText = value.toString().toLowerCase();
281+
282+
// First match against the whole, non-splitted value
283+
if (valueText.startsWith(prefixString)) {
284+
newArray.add(value);
285+
} else {
286+
final String[] words = valueText.split(" ");
287+
for (String word : words) {
288+
if (word.startsWith(prefixString)) {
289+
newArray.add(value);
290+
break;
291+
}
292+
}
293+
}
294+
}
295+
296+
results.values = newArray;
297+
results.count = newArray.size();
298+
}
299+
300+
return results;
301+
}
302+
303+
@Override
304+
protected void publishResults(CharSequence constraint, FilterResults results) {
305+
mArray.setCallback(null);
306+
//noinspection unchecked
307+
mArray = (Array<T>) results.values;
308+
mArray.setCallback(ObjectAdapter.this);
309+
notifyDataSetChanged();
310+
}
311+
}
233312
}

library/src/main/java/com/cncoderx/recyclerviewhelper/utils/Array.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
public class Array<T> implements IArray<T> {
1414

15-
private ArrayList<T> mArray = new ArrayList<>();
15+
private final ArrayList<T> mArray;
1616

1717
private Callback mCallback;
1818

@@ -24,6 +24,22 @@ public void setCallback(Callback callback) {
2424
mCallback = callback;
2525
}
2626

27+
public Array() {
28+
this.mArray = new ArrayList<>();
29+
}
30+
31+
public Array(int capacity) {
32+
this.mArray = new ArrayList<>(capacity);
33+
}
34+
35+
public Array(Array<T> array) {
36+
this(array.mArray);
37+
}
38+
39+
public Array(Collection<? extends T> c) {
40+
this.mArray = new ArrayList<>(c);
41+
}
42+
2743
@Override
2844
public boolean isEmpty() {
2945
return mArray.isEmpty();

0 commit comments

Comments
 (0)