aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsteckbrief <steckbrief@chefmail.de>2016-05-16 01:35:46 +0200
committersteckbrief <steckbrief@chefmail.de>2016-05-16 01:35:46 +0200
commitfe78f858bacf54f8285db31b7d6aa65ff3628f15 (patch)
tree93b81f8069c24ab3ad07a4f389a752914b791513
parent351db27a77c200e526b86c318213b72cd65d1b7b (diff)
avatar displayed as a circle, positioning adjusted, colors changed back to correct ones, positioning moved to own class file
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java26
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java96
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/AvatarLogoPositioningListener.java57
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ImageUtil.java32
-rw-r--r--src/main/res/drawable/actionbar_space_between_icon_and_title.xml8
-rw-r--r--src/main/res/layout/title.xml15
-rw-r--r--src/main/res/values-land/dimens.xml4
-rw-r--r--src/main/res/values/dimens.xml1
-rw-r--r--src/main/res/values/themes.xml11
9 files changed, 182 insertions, 68 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java
index ed9c259f..1ab1dfd6 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/AvatarService.java
@@ -156,8 +156,32 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
}
}
+ public Bitmap getCircled(Conversation conversation, int size) {
+ return getCircled(conversation, size, false);
+ }
+
+ private Bitmap getCircled(Conversation conversation, int size, boolean cachedOnly) {
+ Bitmap squareAvatar = get(conversation, size, cachedOnly);
+ String key = "";
+ if (conversation.getMode() == Conversation.MODE_SINGLE) {
+ key = key(conversation.getContact(), size);
+ } else {
+ key = key(conversation.getMucOptions(), size);
+ }
+ key += "_circle";
+
+ Bitmap circleAvatar = ImageUtil.getBitmapFromCache(key);
+ if (null != circleAvatar || cachedOnly) {
+ return circleAvatar;
+ }
+ circleAvatar = ImageUtil.getCircleBitmap(squareAvatar);
+ ImageUtil.addBitmapToCache(key, circleAvatar);
+
+ return circleAvatar;
+ }
+
public Bitmap get(Conversation conversation, int size) {
- return get(conversation,size,false);
+ return get(conversation, size, false);
}
public Bitmap get(Conversation conversation, int size, boolean cachedOnly) {
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
index 7138f8e3..71db3e3a 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
@@ -28,7 +28,6 @@ import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
@@ -36,6 +35,7 @@ import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
+import android.widget.TextView;
import android.widget.Toast;
import net.java.otr4j.session.SessionStatus;
@@ -51,6 +51,7 @@ import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.services.AvatarService;
import de.thedevstack.conversationsplus.ui.dialogs.UserDecisionDialog;
+import de.thedevstack.conversationsplus.ui.listeners.AvatarLogoPositioningListener;
import de.thedevstack.conversationsplus.ui.listeners.ResizePictureUserDecisionListener;
import de.thedevstack.conversationsplus.utils.ConversationUtil;
import de.timroes.android.listview.EnhancedListView;
@@ -118,6 +119,7 @@ public class ConversationActivity extends XmppActivity
private View mContentView;
private View avatarLogoView;
+ private View titleView;
private List<Conversation> conversationList = new ArrayList<>();
private Conversation swipedConversation = null;
@@ -131,7 +133,7 @@ public class ConversationActivity extends XmppActivity
private AtomicBoolean mRedirected = new AtomicBoolean(false);
private Pair<Integer, Intent> mPostponedActivityResult;
- public Conversation getSelectedConversation() {
+ public Conversation getSelectedConversation() {
return this.mSelectedConversation;
}
@@ -354,81 +356,73 @@ public class ConversationActivity extends XmppActivity
private void updateActionBarTitle(boolean titleShouldBeName) {
final ActionBar ab = getActionBar();
- final Conversation conversation = getSelectedConversation();
if (ab != null) {
+ if (null == this.titleView || null == this.avatarLogoView) {
+ this.initializeCustomActionBarViews(ab);
+ }
+ TextView title = (TextView) this.titleView.findViewById(R.id.conversationsTitle);
+ final Conversation conversation = getSelectedConversation();
if (titleShouldBeName && conversation != null) {
- this.updateLogoAvatar(true);
+ this.toggleShowCustomActionBarView(ab, true);
+ this.showLogoAvatar();
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true);
+
if (conversation.getMode() == Conversation.MODE_SINGLE || ConversationsPlusPreferences.useSubject()) {
- ab.setTitle(conversation.getName());
+ title.setText(conversation.getName());
} else {
- ab.setTitle(conversation.getJid().toBareJid().toString());
+ title.setText(conversation.getJid().toBareJid().toString());
}
} else {
+ this.toggleShowCustomActionBarView(ab, false);
ab.setDisplayHomeAsUpEnabled(false);
ab.setHomeButtonEnabled(false);
- ab.setTitle(R.string.app_name);
- this.updateLogoAvatar(false);
+ title.setText(R.string.app_name);
+ this.hideLogoAvatar();
}
}
}
- private void updateLogoAvatar(boolean show) {
+ private void toggleShowCustomActionBarView(ActionBar ab, boolean show) {
+ if (show) {
+ ab.setDisplayShowTitleEnabled(false);
+ ab.setDisplayShowCustomEnabled(true);
+ } else {
+ ab.setDisplayShowTitleEnabled(true);
+ ab.setDisplayShowCustomEnabled(false);
+ }
+ }
+
+ private void initializeCustomActionBarViews(ActionBar ab) {
+ if (null == this.titleView) {
+ this.titleView = LayoutInflater.from(this).inflate(R.layout.title, null);
+ ab.setCustomView(this.titleView);
+ }
if (null == this.avatarLogoView) {
this.avatarLogoView = LayoutInflater.from(this).inflate(R.layout.logo_view, null, false);
ViewGroup decorViewGroup = (ViewGroup) getWindow().getDecorView();
decorViewGroup.addView(avatarLogoView);
int resId = getResources().getIdentifier("action_bar_container", "id", "android");
final View actionBarView = decorViewGroup.findViewById(resId);
- final View iconPlaceholderView = decorViewGroup.findViewById(R.id.icon_placeholder);
if (actionBarView != null) {
- actionBarView.getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- public void onGlobalLayout() {
- // Remove the listener
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- actionBarView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
- } else {
- actionBarView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
- }
-
- // Measure views
- int[] location = new int[2];
- actionBarView.getLocationOnScreen(location);
-
- int[] logoLocation = new int[2];
- avatarLogoView.getLocationOnScreen(logoLocation);
-
- int[] iconPlaceHolderLocation = new int[2];
- if (null != iconPlaceholderView) {
- iconPlaceholderView.getLocationOnScreen(iconPlaceHolderLocation);
- }else {
- iconPlaceHolderLocation[0] = 0;
- }
-
- // Add top padding if necessary
- if (location[1] > logoLocation[1]) {
- avatarLogoView.setPadding(iconPlaceHolderLocation[0], actionBarView.getMeasuredHeight() / 4 + location[1] - logoLocation[1], 0, 0);
- }
- /*if (iconPlaceHolderLocation[0] > logoLocation[0]) {
- avatarLogoView.setPadding
- }*/
- }
- }
- );
+ actionBarView.getViewTreeObserver().addOnGlobalLayoutListener(new AvatarLogoPositioningListener(actionBarView, avatarLogoView));
}
}
- if (show) {
- ImageView avatarView = (ImageView) this.avatarLogoView.findViewById(R.id.logoViewAvatar);
- avatarView.setImageBitmap(AvatarService.getInstance().get(getSelectedConversation(), getPixel(56)));
- //avatarView.setAlpha(0.5f);
- avatarLogoView.setVisibility(View.VISIBLE);
- } else {
- avatarLogoView.setVisibility(View.GONE);
+ }
+
+ private void hideLogoAvatar() {
+ if (null != this.avatarLogoView) {
+ this.avatarLogoView.setVisibility(View.GONE);
}
}
+ private void showLogoAvatar() {
+ ImageView avatarView = (ImageView) this.avatarLogoView.findViewById(R.id.logoViewAvatar);
+ avatarView.setImageBitmap(AvatarService.getInstance().getCircled(getSelectedConversation(), getPixel(56)));
+ //avatarView.setAlpha(0.5f);
+ avatarLogoView.setVisibility(View.VISIBLE);
+ }
+
private void openConversation() {
this.updateActionBarTitle();
this.invalidateOptionsMenu();
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/AvatarLogoPositioningListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/AvatarLogoPositioningListener.java
new file mode 100644
index 00000000..e6846d9b
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/AvatarLogoPositioningListener.java
@@ -0,0 +1,57 @@
+package de.thedevstack.conversationsplus.ui.listeners;
+
+import android.os.Build;
+import android.view.View;
+import android.view.ViewTreeObserver;
+
+import de.thedevstack.conversationsplus.R;
+
+/**
+ * This listener aims to position the avatar logo.
+ */
+public class AvatarLogoPositioningListener implements ViewTreeObserver.OnGlobalLayoutListener {
+ private View actionBarView;
+ private View avatarLogoView;
+
+ public AvatarLogoPositioningListener(View actionBarView, View avatarLogoView) {
+ this.actionBarView = actionBarView;
+ this.avatarLogoView = avatarLogoView;
+ }
+
+ @Override
+ public void onGlobalLayout() {
+ // Measure views
+ int[] location = new int[2];
+ this.actionBarView.getLocationOnScreen(location);
+
+ int[] logoLocation = new int[2];
+ this.avatarLogoView.getLocationOnScreen(logoLocation);
+
+ int[] titleViewLocation = new int[2];
+ View titleView = this.actionBarView.findViewById(R.id.conversationsTitle);
+ int oldTitleViewLeftPadding = 0;
+ if (null != titleView) {
+ // Remove the listener only if all necessary view elements are there
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ this.actionBarView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ } else {
+ this.actionBarView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+ }
+
+ titleView.getLocationOnScreen(titleViewLocation);
+ int avatarWidth = (int) (58 * titleView.getResources().getDisplayMetrics().density);
+ int newTitleViewLeftPadding = titleViewLocation[0] + avatarWidth;
+ titleView.setPadding(newTitleViewLeftPadding, titleView.getPaddingTop(), 0, 0);
+ oldTitleViewLeftPadding = titleViewLocation[0];
+ }
+
+ // Add top padding if necessary
+ if (location[1] > logoLocation[1]) {
+ int actionBarViewHeight = this.actionBarView.getMeasuredHeight();
+ int newAvatarLogoTopPadding = location[1]; // Move to the top padding of the action bar (below the notification bar)
+ newAvatarLogoTopPadding += actionBarViewHeight;
+ newAvatarLogoTopPadding -= 58 * avatarLogoView.getResources().getDisplayMetrics().density * 0.6;
+ this.avatarLogoView.setPadding(oldTitleViewLeftPadding, newAvatarLogoTopPadding, 0, 0);
+ }
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ImageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ImageUtil.java
index bf79d7e0..18197e3b 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/ImageUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/ImageUtil.java
@@ -4,6 +4,10 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
@@ -365,6 +369,34 @@ public final class ImageUtil {
return inSampleSize;
}
+ /**
+ * Get a circled cut-out of a bitmap.
+ * @param bitmap the original bitmap
+ * @return the circled cut-out of the original bitmap
+ * @see <a href="http://stackoverflow.com/questions/11932805/cropping-circular-area-from-bitmap-in-android">http://stackoverflow.com/questions/11932805/cropping-circular-area-from-bitmap-in-android</a>
+ */
+ public static Bitmap getCircleBitmap(Bitmap bitmap) {
+ Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
+ bitmap.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(output);
+
+ final int color = 0xff424242;
+ final Paint paint = new Paint();
+ final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+
+ paint.setAntiAlias(true);
+ canvas.drawARGB(0, 0, 0, 0);
+ paint.setColor(color);
+ // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
+ canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
+ bitmap.getWidth() / 2, paint);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+ canvas.drawBitmap(bitmap, rect, rect, paint);
+ //Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
+ //return _bmp;
+ return output;
+ }
+
private ImageUtil() {
// Static helper class
}
diff --git a/src/main/res/drawable/actionbar_space_between_icon_and_title.xml b/src/main/res/drawable/actionbar_space_between_icon_and_title.xml
deleted file mode 100644
index 53285bc0..00000000
--- a/src/main/res/drawable/actionbar_space_between_icon_and_title.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<layer-list
- xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:drawable="@android:color/transparent"
- android:right="58dp"
- android:id="@+id/icon_placeholder"/>
-</layer-list> \ No newline at end of file
diff --git a/src/main/res/layout/title.xml b/src/main/res/layout/title.xml
new file mode 100644
index 00000000..17ff1a5b
--- /dev/null
+++ b/src/main/res/layout/title.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/transparent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text=""
+ android:id="@+id/conversationsTitle"
+ android:textSize="@dimen/action_bar_title_text_size"
+ android:textColor="@color/primaryTextOnDark"/>
+</LinearLayout> \ No newline at end of file
diff --git a/src/main/res/values-land/dimens.xml b/src/main/res/values-land/dimens.xml
new file mode 100644
index 00000000..411fd575
--- /dev/null
+++ b/src/main/res/values-land/dimens.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="action_bar_title_text_size">16dp</dimen> <!-- redefinition here, because no access to original from android -->
+</resources> \ No newline at end of file
diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml
index d5d4aad4..99a292fd 100644
--- a/src/main/res/values/dimens.xml
+++ b/src/main/res/values/dimens.xml
@@ -9,4 +9,5 @@
<dimen name="ambilwarna_hsvWidth">240dp</dimen>
<dimen name="ambilwarna_hueWidth">30dp</dimen>
<dimen name="ambilwarna_spacer">8dp</dimen>
+ <dimen name="action_bar_title_text_size">18dp</dimen> <!-- redefinition here, because no access to original from android -->
</resources>
diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml
index a157084f..0deb3a6e 100644
--- a/src/main/res/values/themes.xml
+++ b/src/main/res/values/themes.xml
@@ -44,16 +44,11 @@
</style>
<style name="ConversationsActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
- <item name="android:background">@android:color/transparent</item>
- <!--item name="android:backgroundStacked">@color/primary_dark</item-->
+ <item name="android:background">@color/primary</item>
+ <item name="android:backgroundStacked">@color/primary_dark</item>
<item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
- <item name="android:icon">@drawable/actionbar_space_between_icon_and_title</item>
+ <item name="android:icon">@android:color/transparent</item>
<item name="android:windowActionBarOverlay">true</item>
- <item name="android:titleTextStyle">@style/ConversationsPlusTitleTextStyle</item>
- </style>
-
- <style name="ConversationsPlusTitleTextStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse">
- <item name="android:textSize">12sp</item>
</style>
<style name="ConversationsActionBarWidget" parent="android:Theme.Holo.Light">