mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-17 19:29:02 +00:00
Merge pull request #539 from nivl4/feat/avatar-gif-support
feat: add GIF supported AvatarView
This commit is contained in:
commit
c8a44f28a9
21 changed files with 656 additions and 117 deletions
|
|
@ -9,7 +9,7 @@ android:
|
|||
# Uncomment the lines below if you want to
|
||||
# use the latest revision of Android SDK Tools
|
||||
# - platform-tools
|
||||
# - tools
|
||||
- tools
|
||||
|
||||
# The BuildTools version used by your project
|
||||
- build-tools-23.0.3
|
||||
|
|
|
|||
|
|
@ -117,6 +117,13 @@ dependencies {
|
|||
//Analytics
|
||||
compile 'com.amplitude:android-sdk:2.7.1'
|
||||
|
||||
// Fresco Image Management Library
|
||||
compile('com.facebook.fresco:fresco:0.10.0') {
|
||||
exclude module: 'bolts-android'
|
||||
}
|
||||
compile('com.facebook.fresco:animated-gif:0.10.0') {
|
||||
exclude module: 'bolts-android'
|
||||
}
|
||||
//Tests
|
||||
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
|
||||
testCompile 'org.robolectric:robolectric:3.0'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp">
|
||||
|
|
@ -10,13 +11,14 @@
|
|||
android:layout_margin="5dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_marginRight="5dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/avatarView"
|
||||
android:layout_width="140dp"
|
||||
android:layout_height="147dp" />
|
||||
android:layout_height="147dp"
|
||||
android:layout_marginRight="5dp"
|
||||
app:showBackground="true"
|
||||
app:showMount="true"
|
||||
app:showPet="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
|
|
@ -17,10 +18,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
style="@style/CardContent"
|
||||
android:background="@drawable/selection_highlight">
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/healerAvatarView"
|
||||
android:layout_width="@dimen/avatar_header_width"
|
||||
android:layout_height="@dimen/avatar_header_height"
|
||||
android:id="@+id/healerImageView" />
|
||||
android:layout_height="@dimen/avatar_header_height" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -49,10 +50,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
style="@style/CardContent"
|
||||
android:background="@drawable/selection_highlight">
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/mageAvatarView"
|
||||
android:layout_width="@dimen/avatar_header_width"
|
||||
android:layout_height="@dimen/avatar_header_height"
|
||||
android:id="@+id/mageImageView" />
|
||||
android:layout_height="@dimen/avatar_header_height" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -81,10 +82,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
style="@style/CardContent"
|
||||
android:background="@drawable/selection_highlight">
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/rogueAvatarView"
|
||||
android:layout_width="@dimen/avatar_header_width"
|
||||
android:layout_height="@dimen/avatar_header_height"
|
||||
android:id="@+id/rogueImageView" />
|
||||
android:layout_height="@dimen/avatar_header_height" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -113,10 +114,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
style="@style/CardContent"
|
||||
android:background="@drawable/selection_highlight">
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/warriorAvatarView"
|
||||
android:layout_width="@dimen/avatar_header_width"
|
||||
android:layout_height="@dimen/avatar_header_height"
|
||||
android:id="@+id/warriorImageView" />
|
||||
android:layout_height="@dimen/avatar_header_height" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?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"
|
||||
android:id="@+id/avatar_with_bars_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -18,16 +19,16 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<ImageView
|
||||
android:id="@+id/IMG_ProfilePicture"
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/avatarView"
|
||||
android:layout_width="@dimen/avatar_header_width"
|
||||
android:layout_height="@dimen/avatar_header_height"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:scaleType="fitStart"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
android:contentDescription="@string/profile_image" />
|
||||
android:layout_marginRight="16dp"
|
||||
app:showBackground="true"
|
||||
app:showMount="true"
|
||||
app:showPet="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/LL_header"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?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"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="24dip"
|
||||
|
|
@ -15,11 +16,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp" />
|
||||
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:layout_width="@dimen/avatar_small_width"
|
||||
android:layout_height="@dimen/avatar_small_height"
|
||||
android:id="@+id/avatarView"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
android:layout_gravity="center_horizontal"
|
||||
app:showBackground="false"
|
||||
app:showMount="false"
|
||||
app:showPet="false" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
<?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"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="24dip"
|
||||
android:paddingEnd="24dip"
|
||||
android:paddingStart="24dip"
|
||||
android:paddingRight="24dip">
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:layout_width="@dimen/avatar_small_width"
|
||||
android:layout_height="@dimen/avatar_small_height"
|
||||
android:id="@+id/avatarView"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
android:layout_gravity="center_horizontal"
|
||||
app:showBackground="false"
|
||||
app:showMount="false"
|
||||
app:showPet="false" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?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"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
|
@ -8,10 +9,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/avatarView"
|
||||
android:layout_width="@dimen/avatar_width"
|
||||
android:layout_height="@dimen/avatar_height"
|
||||
android:id="@+id/avatarView" />
|
||||
app:showBackground="true"
|
||||
app:showMount="true"
|
||||
app:showPet="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/CardView.Default">
|
||||
|
|
@ -10,13 +11,14 @@
|
|||
style="@style/CardContent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_marginRight="5dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
<com.habitrpg.android.habitica.ui.AvatarView
|
||||
android:id="@+id/avatarView"
|
||||
android:layout_width="103dp"
|
||||
android:layout_height="90dp" />
|
||||
android:layout_height="90dp"
|
||||
android:layout_marginRight="5dp"
|
||||
app:showBackground="false"
|
||||
app:showMount="false"
|
||||
app:showPet="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
|
|
|||
7
Habitica/res/values/attrs_avatar_view.xml
Normal file
7
Habitica/res/values/attrs_avatar_view.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<resources>
|
||||
<declare-styleable name="AvatarView">
|
||||
<attr name="showBackground" format="boolean" />
|
||||
<attr name="showMount" format="boolean" />
|
||||
<attr name="showPet" format="boolean" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
|
@ -4,6 +4,7 @@ import com.amplitude.api.Amplitude;
|
|||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.core.CrashlyticsCore;
|
||||
import com.facebook.FacebookSdk;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.habitrpg.android.habitica.ui.activities.IntroActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.LoginActivity;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
|
|
@ -58,6 +59,8 @@ public class HabiticaApplication extends MultiDexApplication {
|
|||
createBillingAndCheckout();
|
||||
registerActivityLifecycleCallbacks();
|
||||
Amplitude.getInstance().initialize(this, getString(R.string.amplitude_app_id)).enableForegroundTracking(this);
|
||||
|
||||
Fresco.initialize(this);
|
||||
}
|
||||
|
||||
private void setupLeakCanary() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,454 @@
|
|||
package com.habitrpg.android.habitica.ui;
|
||||
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.drawee.controller.BaseControllerListener;
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
||||
import com.facebook.drawee.interfaces.DraweeController;
|
||||
import com.facebook.drawee.view.DraweeHolder;
|
||||
import com.facebook.drawee.view.MultiDraweeHolder;
|
||||
import com.facebook.imagepipeline.image.ImageInfo;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class AvatarView extends View {
|
||||
public static final String IMAGE_URI_ROOT = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/";
|
||||
private static final String TAG = "AvatarView";
|
||||
private static final Map<String, String> FILENAME_MAP;
|
||||
private static final Rect FULL_HERO_RECT = new Rect(0, 0, 140, 147);
|
||||
private static final Rect COMPACT_HERO_RECT = new Rect(0, 0, 114, 114);
|
||||
private static final Rect HERO_ONLY_RECT = new Rect(0, 0, 90, 90);
|
||||
|
||||
static {
|
||||
Map<String, String> tempMap = new HashMap<>();
|
||||
tempMap.put("head_special_1", "ContributorOnly-Equip-CrystalHelmet.gif");
|
||||
tempMap.put("armor_special_1", "ContributorOnly-Equip-CrystalArmor.gif");
|
||||
tempMap.put("weapon_special_critical", "weapon_special_critical.gif");
|
||||
tempMap.put("Pet-Wolf-Cerberus", "Pet-Wolf-Cerberus.gif");
|
||||
FILENAME_MAP = Collections.unmodifiableMap(tempMap);
|
||||
}
|
||||
|
||||
private boolean showBackground = true;
|
||||
private boolean showMount = true;
|
||||
private boolean showPet = true;
|
||||
private boolean hasBackground;
|
||||
private boolean hasMount;
|
||||
private boolean hasPet;
|
||||
private boolean isOrphan;
|
||||
private MultiDraweeHolder<GenericDraweeHierarchy> multiDraweeHolder = new MultiDraweeHolder<>();
|
||||
private HabitRPGUser user;
|
||||
private RectF avatarRectF;
|
||||
private Matrix matrix = new Matrix();
|
||||
private AtomicInteger numberLayersInProcess = new AtomicInteger(0);
|
||||
private Consumer<Bitmap> avatarImageConsumer;
|
||||
private Bitmap avatarBitmap;
|
||||
private Canvas avatarCanvas;
|
||||
|
||||
public AvatarView(Context context) {
|
||||
super(context);
|
||||
init(null, 0);
|
||||
}
|
||||
|
||||
public AvatarView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs, 0);
|
||||
}
|
||||
|
||||
public AvatarView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(attrs, defStyle);
|
||||
}
|
||||
|
||||
public AvatarView(Context context, boolean showBackground, boolean showMount, boolean showPet) {
|
||||
super(context);
|
||||
|
||||
this.showBackground = showBackground;
|
||||
this.showMount = showMount;
|
||||
this.showPet = showPet;
|
||||
isOrphan = true;
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs, int defStyle) {
|
||||
// Load attributes
|
||||
final TypedArray a = getContext().obtainStyledAttributes(
|
||||
attrs, R.styleable.AvatarView, defStyle, 0);
|
||||
|
||||
try {
|
||||
showBackground = a.getBoolean(R.styleable.AvatarView_showBackground, true);
|
||||
showMount = a.getBoolean(R.styleable.AvatarView_showMount, true);
|
||||
showPet = a.getBoolean(R.styleable.AvatarView_showPet, true);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private void showLayers(@NonNull Map<LayerType, String> layerMap) {
|
||||
if (multiDraweeHolder.size() > 0) return;
|
||||
int i = 0;
|
||||
|
||||
numberLayersInProcess.set(layerMap.size());
|
||||
|
||||
for (Map.Entry<LayerType, String> entry : layerMap.entrySet()) {
|
||||
final LayerType layerKey = entry.getKey();
|
||||
final String layerName = entry.getValue();
|
||||
final int layerNumber = i++;
|
||||
|
||||
GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
|
||||
.setFadeDuration(0)
|
||||
.build();
|
||||
|
||||
DraweeHolder<GenericDraweeHierarchy> draweeHolder = DraweeHolder.create(hierarchy, getContext());
|
||||
draweeHolder.getTopLevelDrawable().setCallback(this);
|
||||
multiDraweeHolder.add(draweeHolder);
|
||||
|
||||
DraweeController controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(IMAGE_URI_ROOT + getFileName(layerName))
|
||||
.setControllerListener(new BaseControllerListener<ImageInfo>() {
|
||||
@Override
|
||||
public void onFinalImageSet(
|
||||
String id,
|
||||
ImageInfo imageInfo,
|
||||
Animatable anim) {
|
||||
if (imageInfo != null) {
|
||||
multiDraweeHolder.get(layerNumber).getTopLevelDrawable().setBounds(getLayerBounds(layerKey, layerName, imageInfo));
|
||||
onLayerComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String id, Throwable throwable) {
|
||||
Log.e(TAG, "Error loading layer: " + layerName, throwable);
|
||||
onLayerComplete();
|
||||
}
|
||||
})
|
||||
.setAutoPlayAnimations(!isOrphan)
|
||||
.build();
|
||||
draweeHolder.setController(controller);
|
||||
}
|
||||
|
||||
if (isOrphan) multiDraweeHolder.onAttach();
|
||||
}
|
||||
|
||||
private Map<LayerType, String> getLayerMap() {
|
||||
assert user != null;
|
||||
return getLayerMap(user, true);
|
||||
}
|
||||
|
||||
private Map<LayerType, String> getLayerMap(@NonNull HabitRPGUser user, boolean resetHasAttributes) {
|
||||
EnumMap<LayerType, String> layerMap = user.getAvatarLayerMap();
|
||||
|
||||
if (resetHasAttributes) hasBackground = hasMount = hasPet = false;
|
||||
|
||||
String mountName = user.getItems().getCurrentMount();
|
||||
if (showMount && !TextUtils.isEmpty(mountName)) {
|
||||
layerMap.put(LayerType.MOUNT_BODY, "Mount_Body_" + mountName);
|
||||
layerMap.put(LayerType.MOUNT_HEAD, "Mount_Head_" + mountName);
|
||||
if (resetHasAttributes) hasMount = true;
|
||||
}
|
||||
|
||||
String petName = user.getItems().getCurrentPet();
|
||||
if (showPet && !TextUtils.isEmpty(petName)) {
|
||||
layerMap.put(LayerType.PET, "Pet-" + petName);
|
||||
if (resetHasAttributes) hasPet = true;
|
||||
}
|
||||
|
||||
String backgroundName = user.getPreferences().getBackground();
|
||||
if (showBackground && !TextUtils.isEmpty(backgroundName)) {
|
||||
layerMap.put(LayerType.BACKGROUND, "background_" + backgroundName);
|
||||
if (resetHasAttributes) hasBackground = true;
|
||||
}
|
||||
return layerMap;
|
||||
}
|
||||
|
||||
private Rect getLayerBounds(@NonNull LayerType layerType, @NonNull String layerName, @NonNull ImageInfo layerImageInfo) {
|
||||
PointF offset = null;
|
||||
Rect bounds = new Rect(0, 0, layerImageInfo.getWidth(), layerImageInfo.getHeight());
|
||||
RectF boundsF = new RectF(bounds);
|
||||
|
||||
// lookup layer specific offset
|
||||
switch (layerName) {
|
||||
case "weapon_special_critical":
|
||||
if (showMount || showPet) {
|
||||
// full hero box
|
||||
if (hasMount) {
|
||||
offset = new PointF(13.0f, 12.0f);
|
||||
} else if (hasPet) {
|
||||
offset = new PointF(13.0f, 24.5f + 12.0f);
|
||||
} else {
|
||||
offset = new PointF(13.0f, 28.0f + 12.0f);
|
||||
}
|
||||
} else if (showBackground) {
|
||||
// compact hero box
|
||||
offset = new PointF(-12.0f, 18.0f + 12.0f);
|
||||
} else {
|
||||
// hero only box
|
||||
offset = new PointF(-12.0f, 12.0f);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// otherwise lookup default layer type based offset
|
||||
if (offset == null) {
|
||||
switch (layerType) {
|
||||
case BACKGROUND:
|
||||
if (!(showMount || showPet)) {
|
||||
offset = new PointF(-25.0f, 0.0f); // compact hero box
|
||||
}
|
||||
break;
|
||||
case MOUNT_BODY:
|
||||
case MOUNT_HEAD:
|
||||
offset = new PointF(25.0f, 18.0f); // full hero box
|
||||
break;
|
||||
case CHAIR:
|
||||
case BACK:
|
||||
case SKIN:
|
||||
case SHIRT:
|
||||
case ARMOR:
|
||||
case BODY:
|
||||
case HEAD_0:
|
||||
case HAIR_BASE:
|
||||
case HAIR_BANGS:
|
||||
case HAIR_MUSTACHE:
|
||||
case HAIR_BEARD:
|
||||
case EYEWEAR:
|
||||
case HEAD:
|
||||
case HEAD_ACCESSORY:
|
||||
case HAIR_FLOWER:
|
||||
case SHIELD:
|
||||
case WEAPON:
|
||||
case ZZZ:
|
||||
if (showMount || showPet) {
|
||||
// full hero box
|
||||
if (hasMount) {
|
||||
offset = new PointF(25.0f, 0);
|
||||
} else if (hasPet) {
|
||||
offset = new PointF(25.0f, 24.5f);
|
||||
} else {
|
||||
offset = new PointF(25.0f, 28.0f);
|
||||
}
|
||||
} else if (showBackground) {
|
||||
// compact hero box
|
||||
offset = new PointF(0.0f, 18.0f);
|
||||
}
|
||||
break;
|
||||
case PET:
|
||||
offset = new PointF(0, FULL_HERO_RECT.height() - layerImageInfo.getHeight());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset != null) {
|
||||
Matrix translateMatrix = new Matrix();
|
||||
translateMatrix.setTranslate(offset.x, offset.y);
|
||||
translateMatrix.mapRect(boundsF);
|
||||
}
|
||||
|
||||
// resize bounds to fit and keep original aspect ratio
|
||||
matrix.mapRect(boundsF);
|
||||
boundsF.round(bounds);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private String getFileName(@NonNull String imageName) {
|
||||
if (FILENAME_MAP.containsKey(imageName)) {
|
||||
return FILENAME_MAP.get(imageName);
|
||||
}
|
||||
|
||||
return imageName + ".png";
|
||||
}
|
||||
|
||||
private void onLayerComplete() {
|
||||
if (numberLayersInProcess.decrementAndGet() == 0) {
|
||||
if (avatarImageConsumer != null) {
|
||||
avatarImageConsumer.accept(getAvatarImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onAvatarImageReady(@NonNull Consumer<Bitmap> consumer) {
|
||||
avatarImageConsumer = consumer;
|
||||
if (multiDraweeHolder.size() > 0 && numberLayersInProcess.get() == 0) {
|
||||
avatarImageConsumer.accept(getAvatarImage());
|
||||
} else {
|
||||
initAvatarRectMatrix();
|
||||
showLayers(getLayerMap());
|
||||
}
|
||||
}
|
||||
|
||||
public void setUser(@NonNull HabitRPGUser user) {
|
||||
HabitRPGUser oldUser = this.user;
|
||||
this.user = user;
|
||||
|
||||
if (oldUser != null) {
|
||||
Map<LayerType, String> currentLayerMap = getLayerMap(oldUser, false);
|
||||
Map<LayerType, String> newLayerMap = getLayerMap(user, false);
|
||||
if (!currentLayerMap.equals(newLayerMap)) {
|
||||
multiDraweeHolder.clear();
|
||||
numberLayersInProcess.set(0);
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private Rect getOriginalRect() {
|
||||
return (showMount || showPet) ? FULL_HERO_RECT : ((showBackground) ? COMPACT_HERO_RECT : HERO_ONLY_RECT);
|
||||
}
|
||||
|
||||
private Bitmap getAvatarImage() {
|
||||
assert user != null;
|
||||
assert avatarRectF != null;
|
||||
Rect canvasRect = new Rect();
|
||||
avatarRectF.round(canvasRect);
|
||||
avatarBitmap = Bitmap.createBitmap(canvasRect.width(), canvasRect.height(), Bitmap.Config.ARGB_8888);
|
||||
avatarCanvas = new Canvas(avatarBitmap);
|
||||
draw(avatarCanvas);
|
||||
|
||||
return avatarBitmap;
|
||||
}
|
||||
|
||||
private void initAvatarRectMatrix() {
|
||||
if (avatarRectF == null) {
|
||||
Rect srcRect = getOriginalRect();
|
||||
|
||||
if (isOrphan) {
|
||||
avatarRectF = new RectF(srcRect);
|
||||
|
||||
// change scale to not be 1:1
|
||||
// a quick fix as fresco AnimatedDrawable/ScaleTypeDrawable
|
||||
// will not translate matrix properly
|
||||
matrix.setScale(1.2f, 1.2f);
|
||||
matrix.mapRect(avatarRectF);
|
||||
} else {
|
||||
// full hero box when showMount and showPet is enabled (140w * 147h)
|
||||
// compact hero box when only showBackground is enabled (114w * 114h)
|
||||
// hero only box when all show settings disabled (90w * 90h)
|
||||
avatarRectF = new RectF(0, 0, getWidth(), getHeight());
|
||||
matrix.setRectToRect(new RectF(srcRect), avatarRectF, Matrix.ScaleToFit.START); // TODO support other ScaleToFit
|
||||
avatarRectF = new RectF(srcRect);
|
||||
matrix.mapRect(avatarRectF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
initAvatarRectMatrix();
|
||||
|
||||
// draw only when user is set
|
||||
if (user == null) return;
|
||||
|
||||
// request image layers if not yet processed
|
||||
if (multiDraweeHolder.size() == 0) {
|
||||
showLayers(getLayerMap());
|
||||
}
|
||||
|
||||
// manually call onAttach/onDetach if view is without parent as they will never be called otherwise
|
||||
if (isOrphan) multiDraweeHolder.onAttach();
|
||||
multiDraweeHolder.draw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
multiDraweeHolder.onDetach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTemporaryDetach() {
|
||||
super.onStartTemporaryDetach();
|
||||
multiDraweeHolder.onDetach();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
multiDraweeHolder.onAttach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishTemporaryDetach() {
|
||||
super.onFinishTemporaryDetach();
|
||||
multiDraweeHolder.onAttach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
return multiDraweeHolder.onTouchEvent(event) || super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verifyDrawable(Drawable who) {
|
||||
return multiDraweeHolder.verifyDrawable(who) || super.verifyDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateDrawable(@NonNull Drawable drawable) {
|
||||
invalidate();
|
||||
if (avatarCanvas != null) draw(avatarCanvas);
|
||||
}
|
||||
|
||||
public enum LayerType {
|
||||
BACKGROUND(0),
|
||||
MOUNT_BODY(1),
|
||||
CHAIR(2),
|
||||
BACK(3),
|
||||
SKIN(4),
|
||||
SHIRT(5),
|
||||
ARMOR(6),
|
||||
BODY(7),
|
||||
HEAD_0(8),
|
||||
HAIR_BASE(9),
|
||||
HAIR_BANGS(10),
|
||||
HAIR_MUSTACHE(11),
|
||||
HAIR_BEARD(12),
|
||||
EYEWEAR(13),
|
||||
HEAD(14),
|
||||
HEAD_ACCESSORY(15),
|
||||
HAIR_FLOWER(16),
|
||||
SHIELD(17),
|
||||
WEAPON(18),
|
||||
MOUNT_HEAD(19),
|
||||
ZZZ(20),
|
||||
PET(21);
|
||||
|
||||
final int order;
|
||||
|
||||
LayerType(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Consumer<T> {
|
||||
void accept(T t);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import com.habitrpg.android.habitica.R;
|
|||
import com.habitrpg.android.habitica.databinding.ValueBarBinding;
|
||||
import com.habitrpg.android.habitica.events.BoughtGemsEvent;
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand;
|
||||
import com.habitrpg.android.habitica.userpicture.UserPicture;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Stats;
|
||||
|
||||
|
|
@ -20,7 +19,6 @@ import android.support.v4.content.ContextCompat;
|
|||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
|
|
@ -31,7 +29,7 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
private ValueBarBinding xpBar;
|
||||
private ValueBarBinding mpBar;
|
||||
|
||||
private ImageView image;
|
||||
private AvatarView avatarView;
|
||||
|
||||
private android.content.res.Resources res;
|
||||
|
||||
|
|
@ -39,7 +37,6 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
|
||||
private TextView lvlText, goldText, silverText, gemsText;
|
||||
private HabitRPGUser userObject;
|
||||
private UserPicture userPicture;
|
||||
|
||||
private int cachedMaxHealth, cachedMaxExp, cachedMaxMana;
|
||||
|
||||
|
|
@ -59,7 +56,7 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
gemsText = (TextView) v.findViewById(R.id.gems_tv);
|
||||
View hpBarView = v.findViewById(R.id.hpBar);
|
||||
|
||||
image = (ImageView) v.findViewById(R.id.IMG_ProfilePicture);
|
||||
avatarView = (AvatarView) v.findViewById(R.id.avatarView);
|
||||
hpBar = DataBindingUtil.bind(hpBarView);
|
||||
xpBar = DataBindingUtil.bind(v.findViewById(R.id.xpBar));
|
||||
mpBar = DataBindingUtil.bind(v.findViewById(R.id.mpBar));
|
||||
|
|
@ -70,7 +67,6 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
|
||||
gemsText.setClickable(true);
|
||||
gemsText.setOnClickListener(this);
|
||||
this.userPicture = new UserPicture(this.context);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
|
|
@ -83,8 +79,7 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
|
|||
int gp = (stats.getGp().intValue());
|
||||
int sp = (int) ((stats.getGp() - gp) * 100);
|
||||
|
||||
userPicture.setUser(user);
|
||||
userPicture.setPictureOn(image);
|
||||
avatarView.setUser(user);
|
||||
|
||||
if (stats.get_class() != null) {
|
||||
userClass += stats.getCleanedClassName();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.ui.activities;
|
|||
import com.habitrpg.android.habitica.APIHelper;
|
||||
import com.habitrpg.android.habitica.HabiticaApplication;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.userpicture.UserPicture;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Gear;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Hair;
|
||||
|
|
@ -15,7 +15,6 @@ import android.app.ProgressDialog;
|
|||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -30,14 +29,14 @@ public class ClassSelectionActivity extends BaseActivity implements Action1<Habi
|
|||
Boolean classWasUnset = false;
|
||||
Boolean shouldFinish = false;
|
||||
|
||||
@BindView(R.id.healerImageView)
|
||||
ImageView healerImageView;
|
||||
@BindView(R.id.mageImageView)
|
||||
ImageView mageImageView;
|
||||
@BindView(R.id.rogueImageView)
|
||||
ImageView rogueImageView;
|
||||
@BindView(R.id.warriorImageView)
|
||||
ImageView warriorImageView;
|
||||
@BindView(R.id.healerAvatarView)
|
||||
AvatarView healerAvatarView;
|
||||
@BindView(R.id.mageAvatarView)
|
||||
AvatarView mageAvatarView;
|
||||
@BindView(R.id.rogueAvatarView)
|
||||
AvatarView rogueAvatarView;
|
||||
@BindView(R.id.warriorAvatarView)
|
||||
AvatarView warriorAvatarView;
|
||||
|
||||
APIHelper apiHelper;
|
||||
|
||||
|
|
@ -77,18 +76,14 @@ public class ClassSelectionActivity extends BaseActivity implements Action1<Habi
|
|||
healerOutfit.setShield("shield_healer_5");
|
||||
healerOutfit.setWeapon("weapon_healer_6");
|
||||
HabitRPGUser healer = this.makeUser(preferences, healerOutfit);
|
||||
UserPicture healerUserPicture = new UserPicture(this);
|
||||
healerUserPicture.setUser(healer);
|
||||
healerUserPicture.setPictureOn(healerImageView);
|
||||
healerAvatarView.setUser(healer);
|
||||
|
||||
Outfit mageOutfit = new Outfit();
|
||||
mageOutfit.setArmor("armor_wizard_5");
|
||||
mageOutfit.setHead("head_wizard_5");
|
||||
mageOutfit.setWeapon("weapon_wizard_6");
|
||||
HabitRPGUser mage = this.makeUser(preferences, mageOutfit);
|
||||
UserPicture mageUserPicture = new UserPicture(this);
|
||||
mageUserPicture.setUser(mage);
|
||||
mageUserPicture.setPictureOn(mageImageView);
|
||||
mageAvatarView.setUser(mage);
|
||||
|
||||
Outfit rogueOutfit = new Outfit();
|
||||
rogueOutfit.setArmor("armor_rogue_5");
|
||||
|
|
@ -96,9 +91,7 @@ public class ClassSelectionActivity extends BaseActivity implements Action1<Habi
|
|||
rogueOutfit.setShield("shield_rogue_6");
|
||||
rogueOutfit.setWeapon("weapon_rogue_6");
|
||||
HabitRPGUser rogue = this.makeUser(preferences, rogueOutfit);
|
||||
UserPicture rogueUserPicture = new UserPicture(this);
|
||||
rogueUserPicture.setUser(rogue);
|
||||
rogueUserPicture.setPictureOn(rogueImageView);
|
||||
rogueAvatarView.setUser(rogue);
|
||||
|
||||
Outfit warriorOutfit = new Outfit();
|
||||
warriorOutfit.setArmor("armor_warrior_5");
|
||||
|
|
@ -106,9 +99,7 @@ public class ClassSelectionActivity extends BaseActivity implements Action1<Habi
|
|||
warriorOutfit.setShield("shield_warrior_5");
|
||||
warriorOutfit.setWeapon("weapon_warrior_6");
|
||||
HabitRPGUser warrior = this.makeUser(preferences, warriorOutfit);
|
||||
UserPicture warriorUserPicture = new UserPicture(this);
|
||||
warriorUserPicture.setUser(warrior);
|
||||
warriorUserPicture.setPictureOn(warriorImageView);
|
||||
warriorAvatarView.setUser(warrior);
|
||||
|
||||
if (!isInitialSelection) {
|
||||
apiHelper.apiService.changeClass()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand;
|
|||
import com.habitrpg.android.habitica.events.commands.SellItemCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.UnlockPathCommand;
|
||||
import com.habitrpg.android.habitica.events.commands.UpdateUserCommand;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
|
||||
import com.habitrpg.android.habitica.ui.menu.MainDrawerBuilder;
|
||||
import com.habitrpg.android.habitica.ui.TutorialView;
|
||||
|
|
@ -38,7 +39,6 @@ import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
|||
import com.habitrpg.android.habitica.ui.fragments.GemsPurchaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils;
|
||||
import com.habitrpg.android.habitica.userpicture.BitmapUtils;
|
||||
import com.habitrpg.android.habitica.userpicture.UserPicture;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.SuppressedModals;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Tag;
|
||||
|
|
@ -164,8 +164,8 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
private APIHelper apiHelper;
|
||||
private AlertDialog faintDialog;
|
||||
|
||||
private UserPicture sideUserPicture;
|
||||
private UserPicture dialogUserPicture;
|
||||
private AvatarView sideAvatarView;
|
||||
private AvatarView dialogAvatarView;
|
||||
|
||||
private Date lastSync;
|
||||
|
||||
|
|
@ -199,8 +199,7 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
drawer = MainDrawerBuilder.CreateDefaultBuilderSettings(this, toolbar, accountHeader)
|
||||
.build();
|
||||
drawer.setSelectionAtPosition(1, false);
|
||||
this.sideUserPicture = new UserPicture(this, true, false);
|
||||
this.dialogUserPicture = new UserPicture(this, false, false);
|
||||
sideAvatarView = new AvatarView(this, true, false, false);
|
||||
|
||||
if (this.filterDrawer == null) {
|
||||
filterDrawer = new DrawerBuilder()
|
||||
|
|
@ -588,9 +587,9 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
}
|
||||
}
|
||||
profile.withName(user.getProfile().getName());
|
||||
sideUserPicture.setUser(this.user);
|
||||
sideUserPicture.setPictureWithRunnable(avatar -> {
|
||||
profile.withIcon(avatar);
|
||||
sideAvatarView.setUser(user);
|
||||
sideAvatarView.onAvatarImageReady(avatarImage -> {
|
||||
profile.withIcon(avatarImage);
|
||||
accountHeader.updateProfile(profile);
|
||||
});
|
||||
accountHeader.updateProfile(profile);
|
||||
|
|
@ -1002,9 +1001,8 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
hpBar.setPartyMembers(true);
|
||||
AvatarWithBarsViewModel.setHpBarData(hpBar, user.getStats(), this);
|
||||
|
||||
ImageView avatarView = (ImageView) customView.findViewById(R.id.avatarView);
|
||||
this.dialogUserPicture.setUser(this.user);
|
||||
this.dialogUserPicture.setPictureOn(avatarView);
|
||||
dialogAvatarView = (AvatarView) customView.findViewById(R.id.avatarView);
|
||||
dialogAvatarView.setUser(user);
|
||||
}
|
||||
|
||||
this.faintDialog = new AlertDialog.Builder(this)
|
||||
|
|
@ -1036,11 +1034,16 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
if (customView != null) {
|
||||
TextView detailView = (TextView) customView.findViewById(R.id.levelupDetail);
|
||||
detailView.setText(this.getString(R.string.levelup_detail, level));
|
||||
ImageView avatarView = (ImageView) customView.findViewById(R.id.avatarView);
|
||||
this.dialogUserPicture.setUser(this.user);
|
||||
this.dialogUserPicture.setPictureOn(avatarView);
|
||||
dialogAvatarView = (AvatarView) customView.findViewById(R.id.avatarView);
|
||||
dialogAvatarView.setUser(user);
|
||||
}
|
||||
|
||||
final ShareEvent event = new ShareEvent();
|
||||
event.sharedMessage = getString(R.string.share_levelup, level) + " https://habitica.com/social/level-up";
|
||||
AvatarView avatarView = new AvatarView(this, true, true, true);
|
||||
avatarView.setUser(user);
|
||||
avatarView.onAvatarImageReady(avatarImage -> event.shareImage = avatarImage);
|
||||
|
||||
AlertDialog alert = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.levelup_header)
|
||||
.setView(customView)
|
||||
|
|
@ -1048,15 +1051,8 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
checkClassSelection();
|
||||
})
|
||||
.setNeutralButton(R.string.share, (dialog, which) -> {
|
||||
ShareEvent event = new ShareEvent();
|
||||
event.sharedMessage = getString(R.string.share_levelup, level) + " https://habitica.com/social/level-up";
|
||||
UserPicture picture = new UserPicture(this, true, true);
|
||||
picture.setUser(this.user);
|
||||
picture.setPictureWithRunnable(avatarBitmap -> {
|
||||
event.shareImage = avatarBitmap;
|
||||
EventBus.getDefault().post(event);
|
||||
dialog.dismiss();
|
||||
});
|
||||
EventBus.getDefault().post(event);
|
||||
dialog.dismiss();
|
||||
})
|
||||
.create();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.habitrpg.android.habitica.R;
|
|||
import com.habitrpg.android.habitica.databinding.ValueBarBinding;
|
||||
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
|
||||
import com.habitrpg.android.habitica.ui.helpers.ViewHelper;
|
||||
import com.habitrpg.android.habitica.userpicture.UserPicture;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
|
||||
import android.content.Context;
|
||||
|
|
@ -12,11 +12,9 @@ import android.content.res.Resources;
|
|||
import android.databinding.DataBindingUtil;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -56,8 +54,8 @@ public class PartyMemberRecyclerViewAdapter extends RecyclerView.Adapter<PartyMe
|
|||
|
||||
class MemberViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@BindView(R.id.avatar)
|
||||
ImageView imageView;
|
||||
@BindView(R.id.avatarView)
|
||||
AvatarView avatarView;
|
||||
|
||||
@BindView(R.id.username)
|
||||
TextView userName;
|
||||
|
|
@ -74,7 +72,6 @@ public class PartyMemberRecyclerViewAdapter extends RecyclerView.Adapter<PartyMe
|
|||
ValueBarBinding hpBar;
|
||||
|
||||
Resources resources;
|
||||
UserPicture userPicture;
|
||||
|
||||
public MemberViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
|
@ -87,20 +84,12 @@ public class PartyMemberRecyclerViewAdapter extends RecyclerView.Adapter<PartyMe
|
|||
hpBar.setPartyMembers(true);
|
||||
|
||||
resources = itemView.getResources();
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
|
||||
if (dpWidth >= 320) {
|
||||
userPicture = new UserPicture(itemView.getContext(), true, true);
|
||||
} else {
|
||||
userPicture = new UserPicture(itemView.getContext(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(HabitRPGUser user) {
|
||||
android.content.Context ctx = itemView.getContext();
|
||||
|
||||
userPicture.setUser(user);
|
||||
userPicture.setPictureOn(imageView);
|
||||
avatarView.setUser(user);
|
||||
|
||||
AvatarWithBarsViewModel.setHpBarData(hpBar, user.getStats(), ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.habitrpg.android.habitica.ui.activities.SetupActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.setup.CustomizationSetupAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration;
|
||||
import com.habitrpg.android.habitica.userpicture.UserPicture;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Customization;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
import com.raizlabs.android.dbflow.sql.builder.Condition;
|
||||
|
|
@ -19,7 +19,6 @@ import android.support.v7.widget.RecyclerView;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -38,11 +37,10 @@ public class AvatarSetupFragment extends BaseFragment {
|
|||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.avatarView)
|
||||
ImageView avatarView;
|
||||
AvatarView avatarView;
|
||||
|
||||
CustomizationSetupAdapter adapter;
|
||||
GridLayoutManager layoutManager;
|
||||
UserPicture userPicture;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
@ -77,7 +75,6 @@ public class AvatarSetupFragment extends BaseFragment {
|
|||
this.recyclerView.setAdapter(this.adapter);
|
||||
this.loadCustomizations();
|
||||
|
||||
userPicture = new UserPicture(this.activity, true, true);
|
||||
if (this.user != null) {
|
||||
this.updateAvatar();
|
||||
}
|
||||
|
|
@ -115,8 +112,8 @@ public class AvatarSetupFragment extends BaseFragment {
|
|||
|
||||
public void setUser(HabitRPGUser user) {
|
||||
this.user = user;
|
||||
if (this.userPicture != null) {
|
||||
this.updateAvatar();
|
||||
if (avatarView != null) {
|
||||
updateAvatar();
|
||||
}
|
||||
if (this.adapter != null) {
|
||||
this.adapter.user = user;
|
||||
|
|
@ -125,8 +122,7 @@ public class AvatarSetupFragment extends BaseFragment {
|
|||
}
|
||||
|
||||
private void updateAvatar() {
|
||||
this.userPicture.setUser(this.user);
|
||||
this.userPicture.setPictureOn(this.avatarView);
|
||||
avatarView.setUser(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.magicmicky.habitrpgwrapper.lib.models;
|
|||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import com.habitrpg.android.habitica.HabitDatabase;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.TasksOrder;
|
||||
import com.raizlabs.android.dbflow.annotation.Column;
|
||||
|
|
@ -15,8 +16,12 @@ import com.raizlabs.android.dbflow.sql.builder.Condition;
|
|||
import com.raizlabs.android.dbflow.sql.language.Select;
|
||||
import com.raizlabs.android.dbflow.structure.BaseModel;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Table(databaseName = HabitDatabase.NAME)
|
||||
public class HabitRPGUser extends BaseModel {
|
||||
|
|
@ -365,4 +370,73 @@ public class HabitRPGUser extends BaseModel {
|
|||
|
||||
return layerNames;
|
||||
}
|
||||
|
||||
public EnumMap<AvatarView.LayerType, String> getAvatarLayerMap() {
|
||||
EnumMap<AvatarView.LayerType, String> layerMap = new EnumMap<>(AvatarView.LayerType.class);
|
||||
|
||||
Preferences prefs = getPreferences();
|
||||
Outfit outfit = (prefs.getCostume()) ? getItems().getGear().getCostume() : getItems().getGear().getEquipped();
|
||||
|
||||
if (!TextUtils.isEmpty(prefs.getChair())) {
|
||||
layerMap.put(AvatarView.LayerType.CHAIR, prefs.getChair());
|
||||
}
|
||||
|
||||
if (outfit != null) {
|
||||
if (!TextUtils.isEmpty(outfit.getBack())) {
|
||||
layerMap.put(AvatarView.LayerType.BACK, outfit.getBack());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getArmor())) {
|
||||
layerMap.put(AvatarView.LayerType.ARMOR, prefs.getSize() + "_" + outfit.getArmor());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getBody())) {
|
||||
layerMap.put(AvatarView.LayerType.BODY, outfit.getBody());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getEyeWear())) {
|
||||
layerMap.put(AvatarView.LayerType.EYEWEAR, outfit.getEyeWear());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getHead())) {
|
||||
layerMap.put(AvatarView.LayerType.HEAD, outfit.getHead());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getHeadAccessory())) {
|
||||
layerMap.put(AvatarView.LayerType.HEAD_ACCESSORY, outfit.getHeadAccessory());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getShield())) {
|
||||
layerMap.put(AvatarView.LayerType.SHIELD, outfit.getShield());
|
||||
}
|
||||
if (outfit.isAvailable(outfit.getWeapon())) {
|
||||
layerMap.put(AvatarView.LayerType.WEAPON, outfit.getWeapon());
|
||||
}
|
||||
}
|
||||
|
||||
layerMap.put(AvatarView.LayerType.SKIN, "skin_" + prefs.getSkin() + ((prefs.getSleep()) ? "_sleep" : ""));
|
||||
layerMap.put(AvatarView.LayerType.SHIRT, prefs.getSize() + "_shirt_" + prefs.getShirt());
|
||||
layerMap.put(AvatarView.LayerType.HEAD_0, "head_0");
|
||||
|
||||
Hair hair = prefs.getHair();
|
||||
if (hair != null) {
|
||||
String hairColor = hair.getColor();
|
||||
|
||||
if (hair.isAvailable(hair.getBase())) {
|
||||
layerMap.put(AvatarView.LayerType.HAIR_BASE, "hair_base_" + hair.getBase() + "_" + hairColor);
|
||||
}
|
||||
if (hair.isAvailable(hair.getBangs())) {
|
||||
layerMap.put(AvatarView.LayerType.HAIR_BANGS, "hair_bangs_" + hair.getBangs() + "_" + hairColor);
|
||||
}
|
||||
if (hair.isAvailable(hair.getMustache())) {
|
||||
layerMap.put(AvatarView.LayerType.HAIR_MUSTACHE, "hair_mustache_" + hair.getMustache() + "_" + hairColor);
|
||||
}
|
||||
if (hair.isAvailable(hair.getBeard())) {
|
||||
layerMap.put(AvatarView.LayerType.HAIR_BEARD, "hair_beard_" + hair.getBeard() + "_" + hairColor);
|
||||
}
|
||||
if (hair.isAvailable(hair.getFlower())) {
|
||||
layerMap.put(AvatarView.LayerType.HAIR_FLOWER, "hair_flower_" + hair.getFlower());
|
||||
}
|
||||
}
|
||||
|
||||
if (prefs.getSleep()) {
|
||||
layerMap.put(AvatarView.LayerType.ZZZ, "zzz");
|
||||
}
|
||||
|
||||
return layerMap;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,4 +75,8 @@ public class Hair extends BaseModel {
|
|||
public int getFlower() { return flower; }
|
||||
|
||||
public void setFlower(int flower) { this.flower = flower; }
|
||||
|
||||
public boolean isAvailable(int hairId) {
|
||||
return hairId > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey;
|
|||
import com.raizlabs.android.dbflow.annotation.Table;
|
||||
import com.raizlabs.android.dbflow.structure.BaseModel;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**
|
||||
* Created by viirus on 20/07/15.
|
||||
*/
|
||||
|
|
@ -54,4 +56,7 @@ public class Outfit extends BaseModel {
|
|||
public String getWeapon() {return weapon;}
|
||||
public void setWeapon(String weapon) {this.weapon = weapon;}
|
||||
|
||||
public boolean isAvailable(String outfit) {
|
||||
return !TextUtils.isEmpty(outfit) && !outfit.endsWith("base_0");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,10 +190,10 @@ public class Preferences extends BaseModel {
|
|||
}
|
||||
|
||||
public String getChair() {
|
||||
if (chair != null) {
|
||||
if (chair != null && !chair.equals("none")) {
|
||||
return "chair_"+chair;
|
||||
}
|
||||
return chair;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setChair(String chair) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue