From a51726f14707cb812bc6e822fe57d5069cdb81ee Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Tue, 29 Dec 2015 11:24:02 -0200 Subject: [PATCH] This introduces a floating action button (FAB) in the contact list. The button hides itself when you scroll down the list of contacts and shows again when you scroll up. To properly color the button, the accent color has been defined. It uses the same color as the action bar (primary color). I leave it to a UX designer to adapt the color scheme. Please note that the design support library was used. It includes the app-compat library, so this has been removed from the `build.gradle` file. Closes #199 --- briar-android/build.gradle | 2 +- briar-android/res/drawable/ic_add_white.xml | 5 ++ .../res/drawable/social_add_person.xml | 5 -- .../res/layout/activity_contact_list.xml | 31 ++++++++++-- .../res/menu/contact_list_actions.xml | 12 ----- briar-android/res/values/styles.xml | 1 + .../android/contact/ContactListActivity.java | 47 +++++++------------ .../android/util/HideFabOnScrollBehavior.java | 42 +++++++++++++++++ 8 files changed, 91 insertions(+), 54 deletions(-) create mode 100644 briar-android/res/drawable/ic_add_white.xml delete mode 100644 briar-android/res/drawable/social_add_person.xml delete mode 100644 briar-android/res/menu/contact_list_actions.xml create mode 100644 briar-android/src/org/briarproject/android/util/HideFabOnScrollBehavior.java diff --git a/briar-android/build.gradle b/briar-android/build.gradle index f06ca62b13..8e043ff7f8 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -6,7 +6,7 @@ dependencies { compile fileTree(dir: '../briar-core/libs', include: '*.jar') compile project(':briar-core') compile fileTree(dir: 'libs', include: '*.jar') - compile "com.android.support:appcompat-v7:23.1.1" + compile 'com.android.support:design:23.1.1' compile 'com.android.support:recyclerview-v7:23.1.1' } diff --git a/briar-android/res/drawable/ic_add_white.xml b/briar-android/res/drawable/ic_add_white.xml new file mode 100644 index 0000000000..3052692a03 --- /dev/null +++ b/briar-android/res/drawable/ic_add_white.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> +</vector> diff --git a/briar-android/res/drawable/social_add_person.xml b/briar-android/res/drawable/social_add_person.xml deleted file mode 100644 index 982183dea2..0000000000 --- a/briar-android/res/drawable/social_add_person.xml +++ /dev/null @@ -1,5 +0,0 @@ -<vector android:alpha="0.56" android:height="24dp" - android:viewportHeight="24.0" android:viewportWidth="24.0" - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#FF000000" android:pathData="M15,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zm-9,-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9,4c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/> -</vector> diff --git a/briar-android/res/layout/activity_contact_list.xml b/briar-android/res/layout/activity_contact_list.xml index acde6fdc93..02faeff9bc 100644 --- a/briar-android/res/layout/activity_contact_list.xml +++ b/briar-android/res/layout/activity_contact_list.xml @@ -1,18 +1,39 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> - <android.support.v7.widget.RecyclerView - android:id="@+id/contactList" - android:scrollbars="vertical" + <android.support.design.widget.CoordinatorLayout + android:id="@+id/coordinatorLayout" android:layout_width="match_parent" - android:layout_height="match_parent" - tools:listitem="@layout/list_item_contact"/> + android:layout_height="match_parent"> + + <android.support.v7.widget.RecyclerView + android:id="@+id/contactList" + android:scrollbars="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:listitem="@layout/list_item_contact"/> + + <android.support.design.widget.FloatingActionButton + android:id="@+id/addContactFAB" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="@dimen/margin_activity_horizontal" + android:src="@drawable/ic_add_white" + app:fabSize="normal" + app:elevation="4dp" + app:layout_anchor="@id/contactList" + app:layout_anchorGravity="bottom|right|end" + app:layout_behavior="org.briarproject.android.util.HideFabOnScrollBehavior"/> + + </android.support.design.widget.CoordinatorLayout> <ProgressBar android:id="@+id/progressBar" diff --git a/briar-android/res/menu/contact_list_actions.xml b/briar-android/res/menu/contact_list_actions.xml deleted file mode 100644 index 718200a659..0000000000 --- a/briar-android/res/menu/contact_list_actions.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> - - <item - android:id="@+id/action_social_add_person" - android:icon="@drawable/social_add_person" - app:showAsAction="always" - android:title="@string/add_contact_title"/> - -</menu> \ No newline at end of file diff --git a/briar-android/res/values/styles.xml b/briar-android/res/values/styles.xml index 0e0c2c0b94..8a706c0a22 100644 --- a/briar-android/res/values/styles.xml +++ b/briar-android/res/values/styles.xml @@ -5,6 +5,7 @@ <item name="actionBarStyle">@style/BriarActionBar</item> <item name="colorPrimary">@color/briar_primary</item> <item name="colorPrimaryDark">@color/briar_primary_dark</item> + <item name="colorAccent">@color/briar_primary</item> <item name="android:textColorPrimary">@color/briar_text_primary</item> <item name="android:textColorPrimaryInverse">@color/briar_text_primary_inverse</item> <item name="android:textColorSecondary">@color/briar_text_primary</item> diff --git a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java index 7f9298089c..b3fec8962a 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java @@ -1,13 +1,11 @@ package org.briarproject.android.contact; import android.content.Intent; -import android.graphics.PorterDuff; import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; +import android.view.View; import android.view.View.OnCreateContextMenuListener; import android.widget.ProgressBar; import android.widget.TextView; @@ -81,6 +79,19 @@ public class ContactListActivity extends BriarActivity // Show a progress bar while the list is loading loading = (ProgressBar) findViewById(R.id.progressBar); loading.setVisibility(VISIBLE); + + // Show a floating action button + FloatingActionButton fab = (FloatingActionButton) findViewById( + R.id.addContactFAB); + + // handle FAB click + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(ContactListActivity.this, + AddContactActivity.class)); + } + }); } @Override @@ -96,32 +107,6 @@ public class ContactListActivity extends BriarActivity loadContacts(); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu items for use in the action bar - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.contact_list_actions, menu); - - // adapt icon color to dark action bar - menu.findItem(R.id.action_social_add_person).getIcon().setColorFilter( - getResources().getColor(R.color.action_bar_text), - PorterDuff.Mode.SRC_IN); - - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(final MenuItem item) { - // Handle presses on the action bar items - switch (item.getItemId()) { - case R.id.action_social_add_person: - startActivity(new Intent(this, AddContactActivity.class)); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - private void loadContacts() { runOnUiThread(new Runnable() { @@ -169,7 +154,7 @@ public class ContactListActivity extends BriarActivity private void displayContacts(final List<ContactListItem> contacts) { runOnUiThread(new Runnable() { public void run() { - if(contacts.size() > 0) { + if (contacts.size() > 0) { list.setVisibility(VISIBLE); empty.setVisibility(GONE); } else { diff --git a/briar-android/src/org/briarproject/android/util/HideFabOnScrollBehavior.java b/briar-android/src/org/briarproject/android/util/HideFabOnScrollBehavior.java new file mode 100644 index 0000000000..9d847b9c2b --- /dev/null +++ b/briar-android/src/org/briarproject/android/util/HideFabOnScrollBehavior.java @@ -0,0 +1,42 @@ +package org.briarproject.android.util; + +import android.content.Context; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.view.ViewCompat; +import android.util.AttributeSet; +import android.view.View; + +public class HideFabOnScrollBehavior extends FloatingActionButton.Behavior { + + public HideFabOnScrollBehavior(Context context, AttributeSet attrs) { + super(); + } + + @Override + public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, + FloatingActionButton child, View directTargetChild, View target, + int nestedScrollAxes) { + return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || + super.onStartNestedScroll(coordinatorLayout, child, + directTargetChild, target, + nestedScrollAxes); + } + + @Override + public void onNestedScroll(CoordinatorLayout coordinatorLayout, + FloatingActionButton child, + View target, int dxConsumed, int dyConsumed, int dxUnconsumed, + int dyUnconsumed) { + super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, + dyConsumed, dxUnconsumed, + dyUnconsumed); + + if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { + child.hide(); + } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { + child.show(); + } + } + +} \ No newline at end of file -- GitLab