Skip to content

Instantly share code, notes, and snippets.

@MatthewDailey
Last active August 29, 2015 14:26
Show Gist options
  • Save MatthewDailey/8ac2b26fee9a23ac46f9 to your computer and use it in GitHub Desktop.
Save MatthewDailey/8ac2b26fee9a23ac46f9 to your computer and use it in GitHub Desktop.
package com.reactiverobot.filtrate.activity;
import android.animation.ObjectAnimator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.jensdriller.libs.undobar.UndoBar;
import com.reactiverobot.filtrate.R;
import com.reactiverobot.filtrate.notification.FiltrateNotification;
import com.reactiverobot.filtrate.notification.FiltratedNotificationSupplier;
import com.wdullaer.swipeactionadapter.DecoratorAdapter;
import com.wdullaer.swipeactionadapter.SwipeActionAdapter;
import com.wdullaer.swipeactionadapter.SwipeDirections;
import com.wdullaer.swipeactionadapter.SwipeViewGroup;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import roboguice.activity.RoboActionBarActivity;
import roboguice.inject.InjectView;
public class ManageFilteredNotificationsActivity extends RoboActionBarActivity {
@Inject LayoutInflater inflater;
@InjectView(R.id.notif_list_view) ListView notificationList;
@Inject FiltratedNotificationSupplier filtratedNotificationSupplier;
private ArrayAdapter<FiltrateNotification> adapter;
protected List<FiltrateNotification> getNotifications() {
return filtratedNotificationSupplier.getRecentNotifications();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_filtered);
adapter = new NotificationAdapter(this, getNotifications());
final SwipeActionAdapter swipeActionAdapter = new SwipeActionAdapter(adapter);
swipeActionAdapter.setListView(notificationList);
notificationList.setAdapter(swipeActionAdapter);
notificationList.setEmptyView(findViewById(R.id.empty_view));
swipeActionAdapter.addBackground(SwipeDirections.DIRECTION_FAR_LEFT, R.layout.swipe_left_background)
.addBackground(SwipeDirections.DIRECTION_NORMAL_LEFT,R.layout.swipe_left_background)
.addBackground(SwipeDirections.DIRECTION_FAR_RIGHT,R.layout.swipe_right_background)
.addBackground(SwipeDirections.DIRECTION_NORMAL_RIGHT, R.layout.swipe_right_background);
swipeActionAdapter.setSwipeActionListener(new SwipeActionAdapter.SwipeActionListener() {
@Override
public boolean hasActions(int position) {
// All items can be swiped
return true;
}
@Override
public boolean shouldDismiss(int position, int direction) {
return true;
}
@Override
public void onSwipe(int[] positionList, int[] directionList) {
for (int i = 0; i < positionList.length; i++) {
int direction = directionList[i];
int position = positionList[i];
FiltrateNotification notification = adapter.getItem(position);
switch (direction) {
case SwipeDirections.DIRECTION_NORMAL_LEFT:
case SwipeDirections.DIRECTION_FAR_LEFT:
clearAndHideSingleNotificationWithUndo(notification, position);
break;
case SwipeDirections.DIRECTION_NORMAL_RIGHT:
case SwipeDirections.DIRECTION_FAR_RIGHT:
clearAndShowSingleNotificationWithUndo(notification, position);
break;
default:
break;
}
}
}
});
}
private class NotificationAdapter extends ArrayAdapter<FiltrateNotification> {
private final Context context;
public NotificationAdapter(Context context, List<FiltrateNotification> notifications) {
super(context, -1, notifications);
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final FiltrateNotification notification = getItem(position);
final NotificationViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.notification_list_item, null);
viewHolder = new NotificationViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (NotificationViewHolder) convertView.getTag();
}
viewHolder.titleView.setText(notification.text().getTitle());
viewHolder.contentView.setText(notification.text().getContent());
// viewHolder.contentView.setLines(1);
viewHolder.timestampView.setText(notification.getDateString());
Optional<Integer> appIcon = getAppIcon(notification);
if (appIcon.isPresent()) {
viewHolder.iconView.setImageResource(appIcon.get());
viewHolder.iconView.setVisibility(View.VISIBLE);
} else {
viewHolder.iconView.setVisibility(View.GONE);
}
convertView.setOnClickListener(getShowTextContentListener(notification, position));
convertView.requestLayout();
return convertView;
}
@NonNull
private View.OnClickListener getShowTextContentListener(final FiltrateNotification notification, final int position) {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
String message = String.format("%s\n\n%s", notification.getDateString(),
notification.text().getContent());
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.FiltrateDialog)
.setTitle(notification.text().getTitle())
.setMessage(message)
.setPositiveButton("Wish I'd seen it", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
clearAndShowSingleNotificationWithUndo(notification, position);
}
})
.setNegativeButton("Glad I missed it", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
clearAndHideSingleNotificationWithUndo(notification, position);
}
});
Optional<Integer> appIcon = getAppIcon(notification);
if (appIcon.isPresent()) {
builder.setIcon(appIcon.get());
}
builder.create().show();
}
};
}
}
private Optional<Integer> getAppIcon(FiltrateNotification notification) {
String packageName = notification.text().getPackageName();
if (packageName.equals("com.facebook.orca")) {
return Optional.of(R.mipmap.facebook_messenger_icon);
} else if (packageName.contains("com.google.android.talk")) {
return Optional.of(R.mipmap.hangouts_icon);
} else if (packageName.equals("com.google.android.apps.inbox")) {
return Optional.of(R.mipmap.inbox_icon);
} else if (packageName.contains("whatsapp")) {
return Optional.of(R.mipmap.whatsapp_icon);
} else if (packageName.contains("groupme")) {
return Optional.of(R.mipmap.groupme_icon);
} else if (packageName.contains("hipchat")) {
return Optional.of(R.mipmap.hipchat_icon);
} else if (packageName.contains("snapchat")) {
return Optional.of(R.mipmap.snapchat_icon);
} else if (packageName.contains("com.google.android.gm")) {
return Optional.of(R.mipmap.gmail_icon);
} else if (packageName.contains("com.google.android.youtube")) {
return Optional.of(R.mipmap.youtube_icon);
} else if (packageName.contains("flipboard.app")) {
return Optional.of(R.mipmap.flipboard_icon);
} else if (packageName.contains("com.rstudioz.habits")) {
return Optional.of(R.mipmap.rewire_icon);
} else if (packageName.contains("com.android.incallui")) {
return Optional.of(R.drawable.ic_phone);
}
return Optional.absent();
}
private void clearAndShowSingleNotificationWithUndo(FiltrateNotification notification, int position) {
adapter.remove(notification);
new UndoBar.Builder(this)
.setListener(showListener(notification, position))
.setMessage("1 should be shown.")
.show();
}
private void clearAndHideSingleNotificationWithUndo(FiltrateNotification notification, int position) {
adapter.remove(notification);
new UndoBar.Builder(this)
.setListener(hideListener(notification, position))
.setMessage("1 should be hidden.")
.show();
}
private UndoBar.Listener hideListener(final FiltrateNotification notification, final int position) {
return new UndoBar.Listener() {
private AtomicBoolean hasUndone = new AtomicBoolean(false);
@Override
public void onHide() {
notification.markShouldHide();
}
@Override
public void onUndo(Parcelable parcelable) {
if (hasUndone.compareAndSet(false, true)) {
adapter.insert(notification, position);
}
}
};
}
private UndoBar.Listener showListener(final FiltrateNotification notification, final int position) {
return new UndoBar.Listener() {
private AtomicBoolean hasUndone = new AtomicBoolean(false);
@Override
public void onHide() {
notification.markShouldShow();
}
@Override
public void onUndo(Parcelable parcelable) {
if (hasUndone.compareAndSet(false, true)) {
adapter.insert(notification, position);
}
}
};
}
private class NotificationViewHolder {
final TextView titleView;
final TextView contentView;
final TextView timestampView;
final ImageView iconView;
private NotificationViewHolder(View notificationView) {
this.titleView = (TextView) notificationView.findViewById(R.id.notif_text_title);
this.contentView = (TextView) notificationView.findViewById(R.id.notif_text_content);
this.timestampView = (TextView) notificationView.findViewById(R.id.notif_text_time_stamp);
this.iconView = (ImageView) notificationView.findViewById(R.id.notif_icon_img);
}
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final FiltrateNotification notification = getItem(position);
final NotificationViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.notification_list_item, null);
viewHolder = new NotificationViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (NotificationViewHolder) convertView.getTag();
}
viewHolder.titleView.setText(notification.text().getTitle());
viewHolder.contentView.setText(notification.text().getContent());
viewHolder.timestampView.setText(notification.getDateString());
Optional<Integer> appIcon = getAppIcon(notification);
if (appIcon.isPresent()) {
viewHolder.iconView.setImageResource(appIcon.get());
viewHolder.iconView.setVisibility(View.VISIBLE);
} else {
viewHolder.iconView.setVisibility(View.GONE);
}
convertView.setOnClickListener(getShowTextContentListener(notification, position));
convertView.requestLayout();
return convertView;
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:background="@android:color/white"
android:layout_height="match_parent"
android:padding="16dp">
<ImageView
android:id="@+id/notif_icon_img"
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="2dp"
android:layout_marginRight="8dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="March 20, 1990 2:00PM"
android:textSize="10dp"
android:id="@+id/notif_text_time_stamp"
android:maxLines="1"
android:textColor="@android:color/black" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Courtney"
android:textStyle="bold"
android:id="@+id/notif_text_title"
android:maxLines="1"
android:textColor="@android:color/black"
android:paddingTop="4dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry&apos;s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book"
android:id="@+id/notif_text_content"
android:textColor="@android:color/black"
android:paddingTop="4dp"
android:ellipsize="end"/>
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="?android:listPreferredItemHeight"
android:background="@android:color/holo_red_light">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:text="Glad I missed it"
android:textStyle="bold"
android:textSize="24dp"
android:gravity="center_vertical|left"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="?android:listPreferredItemHeight"
android:background="@android:color/holo_green_light">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:text="Wish I'd seen it"
android:textStyle="bold"
android:textSize="24dp"
android:gravity="center_vertical|right"/>
</LinearLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment