aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Monk <jmonk@google.com>2016-08-11 11:16:36 -0400
committerJason Monk <jmonk@google.com>2016-08-11 11:16:36 -0400
commit8752b6579fa2cc0659ed20b8e9e0ac606cdce2ed (patch)
tree4a5f0fd803a3aff510b66efd3e35e131567d0bb1
parent002df26c21a78353d33705bb076ac61a09400095 (diff)
downloadexperimental-8752b6579fa2cc0659ed20b8e9e0ac606cdce2ed.tar.gz
Fix build and switch to RecyclerView
- Fix build - Switch to recyclerView - Add swipe to dismiss - Don't try to cache views, causing proboblems and likely not needed anymore - Make views look more like notification panel. Change-Id: I6620c247405c077fa90942693c884cf5b1e5b811
-rw-r--r--NotificationListenerSample/Android.mk11
-rw-r--r--NotificationListenerSample/res/layout/item.xml19
-rw-r--r--NotificationListenerSample/res/layout/main.xml70
-rw-r--r--NotificationListenerSample/src/com/android/example/notificationlistener/Listener.java4
-rw-r--r--NotificationListenerSample/src/com/android/example/notificationlistener/NotificationListenerActivity.java117
5 files changed, 128 insertions, 93 deletions
diff --git a/NotificationListenerSample/Android.mk b/NotificationListenerSample/Android.mk
index 5075a96..9ab4b62 100644
--- a/NotificationListenerSample/Android.mk
+++ b/NotificationListenerSample/Android.mk
@@ -18,13 +18,22 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
+ frameworks/support/v7/appcompat/res \
+ frameworks/support/v7/recyclerview/res
+
+LOCAL_AAPT_FLAGS := --auto-add-overlay \
+ --extra-packages android.support.v7.appcompat:android.support.v7.recyclerview
+
LOCAL_MODULE_TAGS := optional
LOCAL_AAPT_FLAGS += -c mdpi,hdpi,xhdpi
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
+ android-support-v7-recyclerview \
+ android-support-v7-appcompat
LOCAL_PACKAGE_NAME := NotificationListenerSample
LOCAL_CERTIFICATE := platform
diff --git a/NotificationListenerSample/res/layout/item.xml b/NotificationListenerSample/res/layout/item.xml
index 2d9a5ed..3c505ac 100644
--- a/NotificationListenerSample/res/layout/item.xml
+++ b/NotificationListenerSample/res/layout/item.xml
@@ -14,19 +14,12 @@
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:padding="4dp">
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="@android:color/white">
<FrameLayout android:id="@+id/remote_view"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:onClick="launch"
- />
- <ImageButton android:id="@+id/dismiss"
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="top|end"
- android:src="@drawable/dialog_ic_dismiss"
- android:onClick="dismiss"
+ android:layout_width="match_parent"
+ android:onClick="launch"
/>
-</FrameLayout> \ No newline at end of file
+</FrameLayout>
diff --git a/NotificationListenerSample/res/layout/main.xml b/NotificationListenerSample/res/layout/main.xml
index 9cc681c..12b230f 100644
--- a/NotificationListenerSample/res/layout/main.xml
+++ b/NotificationListenerSample/res/layout/main.xml
@@ -14,45 +14,51 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="12dp"
- >
- <ListView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="12dp"
+ >
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:paddingBottom="12dp"
+ android:layout_weight="1">
+ <android.support.v7.widget.RecyclerView
android:id="@android:id/list"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:padding="4dp"
+ android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
- android:text="@string/working_as_intended"
- android:layout_weight="1"
- android:choiceMode="singleChoice"
+ android:background="#eeeeee"
+ android:elevation="4dp"
/>
+ </FrameLayout>
<TextView android:id="@android:id/empty"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:padding="4dp"
- android:layout_marginBottom="16dp"
- android:text="@string/working_as_intended"
- android:layout_weight="1"
- />
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:padding="16dp"
+ android:layout_marginBottom="16dp"
+ android:text="@string/working_as_intended"
+ android:layout_weight="1"
+ />
+
<Button
- android:id="@+id/launch_settings"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/launch_to_disable"
- android:onClick="launchSettings"
- android:layout_weight="0"
- />
+ android:id="@+id/launch_settings"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/launch_to_disable"
+ android:onClick="launchSettings"
+ android:layout_gravity="bottom"
+ />
<Button
- android:id="@+id/snooze"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/snooze"
- android:onClick="snooze"
- android:layout_weight="0"
- />
+ android:id="@+id/snooze"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/snooze"
+ android:onClick="snooze"
+ android:layout_gravity="bottom"
+ />
</LinearLayout>
diff --git a/NotificationListenerSample/src/com/android/example/notificationlistener/Listener.java b/NotificationListenerSample/src/com/android/example/notificationlistener/Listener.java
index 4a65e6a..43979d0 100644
--- a/NotificationListenerSample/src/com/android/example/notificationlistener/Listener.java
+++ b/NotificationListenerSample/src/com/android/example/notificationlistener/Listener.java
@@ -80,7 +80,7 @@ public class Listener extends NotificationListenerService {
NotificationListenerService.requestRebind(
ComponentName.createRelative(context.getPackageName(),
Listener.class.getCanonicalName()));
- } catch (RemoteException e) {
+ } catch (Exception e) {
Log.e(TAG, "failed to rebind service", e);
}
}
@@ -238,7 +238,7 @@ public class Listener extends NotificationListenerService {
Log.d(TAG, "trying to snooze");
try {
requestUnbind();
- } catch (RemoteException e) {
+ } catch (Exception e) {
Log.e(TAG, "failed to unbind service", e);
}
break;
diff --git a/NotificationListenerSample/src/com/android/example/notificationlistener/NotificationListenerActivity.java b/NotificationListenerSample/src/com/android/example/notificationlistener/NotificationListenerActivity.java
index c5016af..b171811 100644
--- a/NotificationListenerSample/src/com/android/example/notificationlistener/NotificationListenerActivity.java
+++ b/NotificationListenerSample/src/com/android/example/notificationlistener/NotificationListenerActivity.java
@@ -15,6 +15,7 @@
*/
package com.android.example.notificationlistener;
+import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.Notification;
@@ -27,7 +28,13 @@ import android.os.Bundle;
import android.provider.Settings.Secure;
import android.service.notification.StatusBarNotification;
import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.support.v7.widget.helper.ItemTouchHelper.SimpleCallback;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
@@ -39,7 +46,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-public class NotificationListenerActivity extends ListActivity {
+public class NotificationListenerActivity extends Activity {
private static final String LISTENER_PATH = "com.android.example.notificationlistener/" +
"com.android.example.notificationlistener.Listener";
private static final String TAG = "NotificationListenerActivity";
@@ -72,7 +79,36 @@ public class NotificationListenerActivity extends ListActivity {
mSnoozeButton = (Button) findViewById(R.id.snooze);
mEmptyText = (TextView) findViewById(android.R.id.empty);
mStatusAdaptor = new StatusAdaptor(this);
- setListAdapter(mStatusAdaptor);
+ RecyclerView list = (RecyclerView) findViewById(android.R.id.list);
+ list.setLayoutManager(new LinearLayoutManager(this));
+ list.setAdapter(mStatusAdaptor);
+
+ ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SimpleCallback(0,
+ ItemTouchHelper.RIGHT) {
+ @Override
+ public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
+ List<StatusBarNotification> notifications = mStatusAdaptor.mNotifications;
+ int position = viewHolder.getAdapterPosition();
+ if (notifications == null || position >= notifications.size()) {
+ return 0;
+ }
+ StatusBarNotification notification = notifications.get(position);
+ return notification.isClearable() ? super.getMovementFlags(recyclerView, viewHolder)
+ : 0;
+ }
+
+ @Override
+ public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder,
+ ViewHolder target) {
+ return false;
+ }
+
+ @Override
+ public void onSwiped(ViewHolder viewHolder, int direction) {
+ dismiss(viewHolder.itemView);
+ }
+ });
+ itemTouchHelper.attachToRecyclerView(list);
}
@Override
@@ -171,17 +207,20 @@ public class NotificationListenerActivity extends ListActivity {
final List<StatusBarNotification> notifications = Listener.getNotifications();
if (notifications != null) {
mStatusAdaptor.setData(notifications);
+ findViewById(android.R.id.empty).setVisibility(notifications.size() == 0
+ ? View.VISIBLE : View.GONE);
+ } else {
+ findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
}
mStatusAdaptor.update(key);
}
- private class StatusAdaptor extends BaseAdapter {
+ private class StatusAdaptor extends RecyclerView.Adapter<Holder> {
private final Context mContext;
private List<StatusBarNotification> mNotifications;
private HashMap<String, Long> mKeyToId;
private HashSet<String> mKeys;
private long mNextId;
- private HashMap<String, View> mRecycledViews;
private String mUpdateKey;
public StatusAdaptor(Context context) {
@@ -189,44 +228,35 @@ public class NotificationListenerActivity extends ListActivity {
mKeyToId = new HashMap<String, Long>();
mKeys = new HashSet<String>();
mNextId = 0;
- mRecycledViews = new HashMap<String, View>();
+ setHasStableIds(true);
}
@Override
- public int getCount() {
+ public int getItemCount() {
return mNotifications == null ? 0 : mNotifications.size();
}
@Override
- public Object getItem(int position) {
- return mNotifications.get(position);
- }
-
- @Override
- public boolean hasStableIds() {
- return true;
- }
-
- @Override
public long getItemId(int position) {
final StatusBarNotification sbn = mNotifications.get(position);
final String key = sbn.getKey();
if (!mKeyToId.containsKey(key)) {
mKeyToId.put(key, mNextId);
- mNextId ++;
+ mNextId++;
}
return mKeyToId.get(key);
}
@Override
- public View getView(int position, View view, ViewGroup list) {
- if (view == null) {
- view = View.inflate(mContext, R.layout.item, null);
- }
- FrameLayout container = (FrameLayout) view.findViewById(R.id.remote_view);
- View dismiss = view.findViewById(R.id.dismiss);
+ public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item,
+ parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(Holder holder, int position) {
+ FrameLayout container = holder.container;
StatusBarNotification sbn = mNotifications.get(position);
- View child;
if (container.getTag() instanceof StatusBarNotification &&
container.getChildCount() > 0) {
// recycle the view
@@ -237,40 +267,27 @@ public class NotificationListenerActivity extends ListActivity {
} else {
View content = container.getChildAt(0);
container.removeView(content);
- mRecycledViews.put(old.getKey(), content);
}
}
- child = mRecycledViews.get(sbn.getKey());
- if (child == null) {
- Notification.Builder builder =
- Notification.Builder.recoverBuilder(mContext, sbn.getNotification());
- child = builder.createContentView().apply(mContext, null);
- }
+ Notification.Builder builder =
+ Notification.Builder.recoverBuilder(mContext, sbn.getNotification());
+ View child = builder.createContentView().apply(mContext, null);
container.setTag(sbn);
+ holder.itemView.setTag(sbn);
container.removeAllViews();
container.addView(child);
- dismiss.setVisibility(sbn.isClearable() ? View.VISIBLE : View.GONE);
- dismiss.setTag(sbn);
- return view;
}
public void update(String key) {
if (mNotifications != null) {
synchronized (mNotifications) {
- mKeys.clear();
for (int i = 0; i < mNotifications.size(); i++) {
- mKeys.add(mNotifications.get(i).getKey());
+ if (mNotifications.get(i).getKey().equals(key)) {
+ Log.d(TAG, "notifyItemChanged " + i);
+ notifyItemChanged(i);
+ }
}
- mKeyToId.keySet().retainAll(mKeys);
}
- if (key == null) {
- mRecycledViews.clear();
- } else {
- mUpdateKey = key;
- mRecycledViews.remove(key);
- }
- Log.d(TAG, "notifyDataSetChanged");
- notifyDataSetChanged();
} else {
Log.d(TAG, "missed and update");
}
@@ -278,6 +295,16 @@ public class NotificationListenerActivity extends ListActivity {
public void setData(List<StatusBarNotification> notifications) {
mNotifications = notifications;
+ notifyDataSetChanged();
+ }
+ }
+
+ private static class Holder extends RecyclerView.ViewHolder {
+ private final FrameLayout container;
+
+ public Holder(View itemView) {
+ super(itemView);
+ container = (FrameLayout) itemView.findViewById(R.id.remote_view);
}
}
}