From e87991ecac70c793f983c1f0716299d704ee7947 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 4 May 2016 13:04:00 -0300 Subject: [PATCH] Forum Avatars using the first letter of the forum and color from group Also prevents the snackbar from hiding the bottom of the list. Closes #337 --- .../res/layout/fragment_forum_list.xml | 16 +++++- briar-android/res/layout/list_item_forum.xml | 24 ++++++-- briar-android/res/layout/text_avatar_view.xml | 32 +++++++++++ briar-android/res/values/color.xml | 2 +- briar-android/res/values/dimens.xml | 1 + .../android/forum/ForumListAdapter.java | 5 ++ .../android/forum/ForumListFragment.java | 2 +- .../util/BriarRecyclerViewBehavior.java | 44 ++++++++++++++ .../android/util/TextAvatarView.java | 57 +++++++++++++++++++ 9 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 briar-android/res/layout/text_avatar_view.xml create mode 100644 briar-android/src/org/briarproject/android/util/BriarRecyclerViewBehavior.java create mode 100644 briar-android/src/org/briarproject/android/util/TextAvatarView.java diff --git a/briar-android/res/layout/fragment_forum_list.xml b/briar-android/res/layout/fragment_forum_list.xml index c823c26c1..31d90c085 100644 --- a/briar-android/res/layout/fragment_forum_list.xml +++ b/briar-android/res/layout/fragment_forum_list.xml @@ -1,6 +1,16 @@ - + android:layout_height="match_parent"> + + + + diff --git a/briar-android/res/layout/list_item_forum.xml b/briar-android/res/layout/list_item_forum.xml index 8462c1cd6..b513972e1 100644 --- a/briar-android/res/layout/list_item_forum.xml +++ b/briar-android/res/layout/list_item_forum.xml @@ -1,6 +1,7 @@ + + + tools:text="This is a name of a forum" + android:layout_alignParentTop="true" + android:layout_toRightOf="@+id/avatarView" + android:layout_toEndOf="@+id/avatarView"/> + android:text="@string/no_unread_posts" + android:layout_below="@+id/forumNameView" + android:layout_toRightOf="@+id/avatarView" + android:layout_toEndOf="@+id/avatarView"/> + + + + + + + + diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml index 9113861d7..7fa718ebd 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -18,7 +18,7 @@ #CCCCCC @color/briar_gold #AAAAAA - #AAAAAA + #b3b3b3 @color/briar_blue @color/briar_blue_dark diff --git a/briar-android/res/values/dimens.xml b/briar-android/res/values/dimens.xml index 7e3b8d807..a1e8fcf35 100644 --- a/briar-android/res/values/dimens.xml +++ b/briar-android/res/values/dimens.xml @@ -28,6 +28,7 @@ 48dp 40dp 32dp + 48dp 1dp 14dp diff --git a/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java b/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java index 9054bed9b..d6bb18454 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListAdapter.java @@ -13,6 +13,7 @@ import android.view.ViewGroup; import android.widget.TextView; import org.briarproject.R; +import org.briarproject.android.util.TextAvatarView; import org.briarproject.api.forum.Forum; import org.briarproject.api.sync.GroupId; @@ -91,6 +92,8 @@ public class ForumListAdapter extends final ForumListItem item = getItem(position); // TODO add avatar. See #337 + ui.avatar.setText(item.getForum().getName().substring(0, 1)); + ui.avatar.setBackgroundBytes(item.getForum().getId().getBytes()); // Forum Name ui.name.setText(item.getForum().getName()); @@ -176,6 +179,7 @@ public class ForumListAdapter extends protected static class ForumViewHolder extends RecyclerView.ViewHolder { private final ViewGroup layout; + private final TextAvatarView avatar; private final TextView name; private final TextView unread; private final TextView date; @@ -184,6 +188,7 @@ public class ForumListAdapter extends super(v); layout = (ViewGroup) v; + avatar = (TextAvatarView) v.findViewById(R.id.avatarView); name = (TextView) v.findViewById(R.id.forumNameView); unread = (TextView) v.findViewById(R.id.unreadView); date = (TextView) v.findViewById(R.id.dateView); diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java index 1f35e55f0..e6f0f6a26 100644 --- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java +++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java @@ -83,7 +83,7 @@ public class ForumListFragment extends BaseEventFragment implements list.setAdapter(adapter); list.setEmptyText(getString(R.string.no_forums)); - snackbar = Snackbar.make(contentView, "", LENGTH_INDEFINITE); + snackbar = Snackbar.make(list, "", LENGTH_INDEFINITE); snackbar.getView().setBackgroundResource(R.color.briar_primary); snackbar.setAction(R.string.show_forums, this); snackbar.setActionTextColor(ContextCompat diff --git a/briar-android/src/org/briarproject/android/util/BriarRecyclerViewBehavior.java b/briar-android/src/org/briarproject/android/util/BriarRecyclerViewBehavior.java new file mode 100644 index 000000000..fc57a27f0 --- /dev/null +++ b/briar-android/src/org/briarproject/android/util/BriarRecyclerViewBehavior.java @@ -0,0 +1,44 @@ +package org.briarproject.android.util; + +import android.content.Context; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.Snackbar; +import android.util.AttributeSet; +import android.view.View; + +public class BriarRecyclerViewBehavior + extends CoordinatorLayout.Behavior { + + public BriarRecyclerViewBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onDependentViewChanged(CoordinatorLayout parent, + BriarRecyclerView child, View dependency) { + + // FIXME the below code works, but does not reset margin when snackbar is dismissed +/* + int margin = 0; + if (dependency.isShown()) margin = dependency.getHeight(); + + // set snackbar height as bottom margin if it is shown + CoordinatorLayout.LayoutParams params = + (CoordinatorLayout.LayoutParams) child.getLayoutParams(); + params.setMargins(0, 0, 0, margin); + child.setLayoutParams(params); + + child.scrollToPosition(0); +*/ + return true; + } + + @Override + public boolean layoutDependsOn(CoordinatorLayout parent, + BriarRecyclerView child, View dependency) { + // we only want to trigger the change + // only when the changes is from a snackbar + return dependency instanceof Snackbar.SnackbarLayout; + } + +} diff --git a/briar-android/src/org/briarproject/android/util/TextAvatarView.java b/briar-android/src/org/briarproject/android/util/TextAvatarView.java new file mode 100644 index 000000000..721fc5e91 --- /dev/null +++ b/briar-android/src/org/briarproject/android/util/TextAvatarView.java @@ -0,0 +1,57 @@ +package org.briarproject.android.util; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.support.v7.widget.AppCompatTextView; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.FrameLayout; + +import org.briarproject.R; + +import de.hdodenhof.circleimageview.CircleImageView; + +public class TextAvatarView extends FrameLayout { + + final private AppCompatTextView textView; + final private CircleImageView backgroundView; + + public TextAvatarView(Context context, AttributeSet attrs) { + super(context, attrs); + + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater + .inflate(R.layout.text_avatar_view, this, true); + textView = (AppCompatTextView) findViewById(R.id.textAvatarView); + backgroundView = (CircleImageView) findViewById(R.id.avatarBackground); + } + + public TextAvatarView(Context context) { + this(context, null); + } + + public void setText(String text) { + textView.setText(text); + } + + public void setBackgroundBytes(byte[] bytes) { + int r = getByte(bytes, 0) * 3 / 4 + 96; + int g = getByte(bytes, 1) * 3 / 4 + 96; + int b = getByte(bytes, 2) * 3 / 4 + 96; + int color = Color.rgb(r, g, b); + + backgroundView.setFillColor(color); + } + + private byte getByte(byte[] bytes, int index) { + if (bytes == null) { + return -128; + } else { + return bytes[index % bytes.length]; + } + } + +}