1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-17 04:00:48 +01:00

improved sign in verification

improved like animation
improved status card item
bug fixes
This commit is contained in:
Mariotaku Lee 2016-02-22 15:02:41 +08:00
parent b5e76a056b
commit be05ac0775
27 changed files with 499 additions and 447 deletions

View File

@ -38,13 +38,13 @@ android {
dependencies {
apt 'com.bluelinelabs:logansquare-compiler:1.3.4'
apt 'com.hannesdorfmann.parcelableplease:processor:1.0.2'
apt 'com.github.mariotaku.ObjectCursor:processor:0.9.3'
apt 'com.github.mariotaku.ObjectCursor:processor:0.9.4'
compile 'com.android.support:support-annotations:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.bluelinelabs:logansquare:1.3.4'
compile 'org.apache.commons:commons-lang3:3.4'
compile 'com.github.mariotaku.RestFu:library:0.9.21'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.3'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.4'
compile fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -21,8 +21,8 @@ android {
applicationId "org.mariotaku.twidere"
minSdkVersion 14
targetSdkVersion 23
versionCode 150
versionName "3.0.5.2"
versionCode 151
versionName "3.0.6"
multiDexEnabled true
buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("false")'
@ -71,7 +71,7 @@ dependencies {
androidTestApt 'com.bluelinelabs:logansquare-compiler:1.3.4'
apt 'com.hannesdorfmann.parcelableplease:processor:1.0.2'
apt 'com.google.dagger:dagger-compiler:2.0.2'
apt "com.github.mariotaku.ObjectCursor:processor:0.9.3"
apt "com.github.mariotaku.ObjectCursor:processor:0.9.4"
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:support-v13:23.1.1'
@ -110,10 +110,10 @@ dependencies {
compile 'com.google.dagger:dagger:2.0.2'
compile 'org.attoparser:attoparser:1.4.0.RELEASE'
compile 'com.j256.simplemagic:simplemagic:1.6'
compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.7'
compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.7'
compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.9'
compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.9'
compile 'com.github.mariotaku:SQLiteQB:0.9.4'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.3'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.4'
compile project(':twidere.component.common')
compile project(':twidere.component.nyan')

View File

@ -24,8 +24,6 @@ import android.app.FragmentManager;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
@ -808,6 +806,8 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements
public static class ImagePageFragment extends SubsampleImageViewerFragment {
private int mMediaLoadState;
@Override
protected Object getDownloadExtra() {
final MediaExtra mediaExtra = new MediaExtra();
@ -830,6 +830,18 @@ public final class MediaViewerActivity extends AbsMediaViewerActivity implements
}
}
@Override
public boolean hasDownloadedData() {
return super.hasDownloadedData() && mMediaLoadState != State.ERROR;
}
@Override
protected void onMediaLoadStateChange(@State int state) {
mMediaLoadState = state;
if (getUserVisibleHint()) {
getActivity().supportInvalidateOptionsMenu();
}
}
}
public static class VideoPageFragment extends CacheDownloadMediaViewerFragment

View File

@ -68,6 +68,7 @@ import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.SettingsActivity;
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.TwitterOAuth;
@ -131,8 +132,6 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
private ContentResolver mResolver;
private AbstractSignInTask mTask;
private TintedStatusLayout mMainContent;
private Runnable mResumeFragmentRunnable;
private boolean mFragmentsResumed;
@Override
public void afterTextChanged(final Editable s) {
@ -482,36 +481,18 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
setSignInButton();
}
@Override
protected void onResumeFragments() {
super.onResumeFragments();
if (!mFragmentsResumed && mResumeFragmentRunnable != null) {
mResumeFragmentRunnable.run();
}
mFragmentsResumed = true;
}
@Override
protected void onPause() {
mFragmentsResumed = false;
super.onPause();
}
void dismissDialogFragment(final String tag) {
mResumeFragmentRunnable = new Runnable() {
executeAfterFragmentResumed(new Action() {
@Override
public void run() {
public void execute(IExtendedActivity activity) {
final FragmentManager fm = getSupportFragmentManager();
final Fragment f = fm.findFragmentByTag(tag);
if (f instanceof DialogFragment) {
((DialogFragment) f).dismiss();
}
mResumeFragmentRunnable = null;
}
};
if (mFragmentsResumed) {
mResumeFragmentRunnable.run();
}
});
}
void onSignInStart() {
@ -519,27 +500,19 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
}
void showSignInProgressDialog() {
postAfterFragmentResumed(new Runnable() {
executeAfterFragmentResumed(new Action() {
@Override
public void run() {
public void execute(IExtendedActivity activity) {
if (isFinishing()) return;
final FragmentManager fm = getSupportFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
final SupportProgressDialogFragment fragment = new SupportProgressDialogFragment();
fragment.setCancelable(false);
fragment.show(ft, FRAGMENT_TAG_SIGN_IN_PROGRESS);
mResumeFragmentRunnable = null;
}
});
}
void postAfterFragmentResumed(Runnable runnable) {
mResumeFragmentRunnable = runnable;
if (mFragmentsResumed) {
mResumeFragmentRunnable.run();
}
}
protected boolean isActionBarOutlineEnabled() {
return true;
}
@ -848,13 +821,16 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
public void run() {
final SignInActivity activity = activityRef.get();
if (activity == null) return;
activity.postAfterFragmentResumed(new Runnable() {
activity.executeAfterFragmentResumed(new Action() {
@Override
public void run() {
InputLoginVerificationDialogFragment df = new InputLoginVerificationDialogFragment();
public void execute(IExtendedActivity activity) {
final SignInActivity sia = (SignInActivity) activity;
final InputLoginVerificationDialogFragment df =
new InputLoginVerificationDialogFragment();
df.setCancelable(false);
df.setCallback(InputLoginVerificationCallback.this);
df.setChallengeType(challengeType);
df.show(activity.getSupportFragmentManager(), null);
df.show(sia.getSupportFragmentManager(), null);
}
});
}
@ -948,9 +924,13 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
} else if ("RetypePhoneNumber".equalsIgnoreCase(challengeType)) {
verificationHint.setText(R.string.login_challenge_retype_phone_hint);
editVerification.setVisibility(View.VISIBLE);
} else {
} else if ("Sms".equalsIgnoreCase(challengeType)) {
verificationHint.setText(R.string.login_verification_pin_hint);
editVerification.setVisibility(View.VISIBLE);
} else {
verificationHint.setText(getString(R.string.unsupported_login_verification_type_name,
challengeType));
editVerification.setVisibility(View.VISIBLE);
}
}
}

View File

@ -275,6 +275,7 @@ public abstract class CursorActivitiesFragment extends AbsActivitiesFragment<Lis
@Subscribe
public void notifyFavoriteTask(FavoriteTaskEvent event) {
}
@Subscribe

View File

@ -44,17 +44,17 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
import org.mariotaku.twidere.loader.support.ExtendedObjectCursorLoader;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatusCursorIndices;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.ErrorInfoStore;
import org.mariotaku.twidere.model.message.AccountChangedEvent;
import org.mariotaku.twidere.model.message.FavoriteTaskEvent;
import org.mariotaku.twidere.model.message.GetStatusesTaskEvent;
import org.mariotaku.twidere.model.message.StatusDestroyedEvent;
import org.mariotaku.twidere.model.message.StatusListChangedEvent;
import org.mariotaku.twidere.model.message.StatusRetweetedEvent;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.ErrorInfoStore;
import java.util.List;
@ -136,6 +136,22 @@ public abstract class CursorStatusesFragment extends AbsStatusesFragment<List<Pa
@Subscribe
public void notifyFavoriteTask(FavoriteTaskEvent event) {
if (event.isSucceeded()) {
final ParcelableStatus status = event.getStatus();
final List<ParcelableStatus> data = getAdapterData();
if (status == null || data == null || data.isEmpty()) return;
final AbsStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
final int firstVisiblePosition = getLayoutManager().findFirstVisibleItemPosition();
final int lastVisiblePosition = getLayoutManager().findLastVisibleItemPosition();
final int startIndex = adapter.getStatusStartIndex();
for (int i = firstVisiblePosition, j = lastVisiblePosition + 1; i < j; i++) {
if (adapter.getAccountId(i) == status.account_id &&
adapter.getStatusId(i) == status.id) {
data.set(i - startIndex, status);
return;
}
}
}
}

View File

@ -4,15 +4,15 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.support.annotation.IntDef;
import android.support.v4.content.ContextCompat;
import android.support.annotation.NonNull;
import android.util.Property;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
@ -20,13 +20,11 @@ import android.view.animation.DecelerateInterpolator;
import org.mariotaku.twidere.graphic.iface.DoNotWrapDrawable;
import org.mariotaku.twidere.graphic.like.layer.AnimationLayerDrawable;
import org.mariotaku.twidere.graphic.like.layer.CircleLayerDrawable;
import org.mariotaku.twidere.graphic.like.layer.IconLayerDrawable;
import org.mariotaku.twidere.graphic.like.layer.Layer;
import org.mariotaku.twidere.graphic.like.layer.ParticleLayerDrawable;
import org.mariotaku.twidere.graphic.like.layer.ScalableDrawable;
import org.mariotaku.twidere.graphic.like.layer.ShineLayerDrawable;
import org.mariotaku.twidere.graphic.like.palette.FavoritePalette;
import org.mariotaku.twidere.graphic.like.palette.LikePalette;
import org.mariotaku.twidere.graphic.like.palette.Palette;
import java.lang.ref.WeakReference;
@ -35,49 +33,17 @@ import java.lang.ref.WeakReference;
*/
public class LikeAnimationDrawable extends Drawable implements Animatable, Drawable.Callback, DoNotWrapDrawable {
private static final Property<IconLayerDrawable, Float> ICON_SCALE = new Property<IconLayerDrawable, Float>(Float.class, "icon_scale") {
@Override
public void set(IconLayerDrawable object, Float value) {
object.setScale(value);
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public Float get(IconLayerDrawable object) {
return object.getScale();
}
};
private static final Property<Layer, Float> LAYER_PROGRESS = new Property<Layer, Float>(Float.class, "layer_progress") {
@Override
public void set(Layer object, Float value) {
object.setProgress(value);
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public Float get(Layer object) {
return object.getProgress();
}
};
@NonNull
private LikeAnimationState mState;
private boolean mMutated;
public LikeAnimationDrawable(final Context context, final int likeIcon, final int defaultColor,
final int likeColor, @Style final int style) {
mState = new LikeAnimationState(context, likeIcon, defaultColor, likeColor, style, this);
public LikeAnimationDrawable(final Drawable icon, final int defaultColor, final int activatedColor,
@Style final int style) {
mState = new LikeAnimationState(icon, defaultColor, activatedColor, style, this);
}
public LikeAnimationDrawable(LikeAnimationState state) {
LikeAnimationDrawable(@NonNull LikeAnimationState state) {
mState = state;
}
@ -89,7 +55,7 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
final AnimationLayerDrawable particleLayer = mState.mParticleLayer;
final AnimationLayerDrawable circleLayer = mState.mCircleLayer;
final IconLayerDrawable iconLayer = mState.mIconLayer;
final ScalableDrawable iconLayer = mState.mIconDrawable;
switch (mState.mStyle) {
case Style.LIKE: {
@ -126,7 +92,7 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
}
private void resetState() {
iconLayer.setColorFilter(mState.mDefaultColor, PorterDuff.Mode.SRC_ATOP);
setColorFilter(mState.mDefaultColor, PorterDuff.Mode.SRC_ATOP);
particleLayer.setProgress(-1);
}
});
@ -135,12 +101,12 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
}
private void setupFavoriteAnimation(final AnimatorSet animatorSet, final Layer particleLayer,
final Layer circleLayer, final IconLayerDrawable iconLayer) {
final Layer circleLayer, final ScalableDrawable iconLayer) {
setupLikeAnimation(animatorSet, particleLayer, circleLayer, iconLayer);
}
private void setupLikeAnimation(final AnimatorSet animatorSet, final Layer particleLayer,
final Layer circleLayer, final IconLayerDrawable iconLayer) {
final Layer circleLayer, final ScalableDrawable iconLayer) {
final long duration = mState.mDuration;
final long scaleDownDuration = Math.round(1f / 24f * duration);
final long ovalExpandDuration = Math.round(4f / 24f * duration);
@ -150,42 +116,42 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
final long particleExpandDuration = Math.round(12f / 24f * duration);
final long circleExplodeDuration = Math.round(5f / 24f * duration);
final ObjectAnimator iconScaleDown = ObjectAnimator.ofFloat(iconLayer, ICON_SCALE, 1, 0);
final ObjectAnimator iconScaleDown = ObjectAnimator.ofFloat(iconLayer, IconScaleProperty.SINGLETON, 1, 0);
iconScaleDown.setDuration(scaleDownDuration);
iconScaleDown.setInterpolator(new AccelerateInterpolator(2));
iconScaleDown.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
iconLayer.setColorFilter(mState.mDefaultColor, PorterDuff.Mode.SRC_ATOP);
setColorFilter(mState.mDefaultColor, PorterDuff.Mode.SRC_ATOP);
}
});
final ObjectAnimator ovalExpand = ObjectAnimator.ofFloat(circleLayer, LAYER_PROGRESS, 0, 0.5f);
final ObjectAnimator ovalExpand = ObjectAnimator.ofFloat(circleLayer, LayerProgressProperty.SINGLETON, 0, 0.5f);
ovalExpand.setDuration(ovalExpandDuration);
final ObjectAnimator iconExpand = ObjectAnimator.ofFloat(iconLayer, ICON_SCALE, 0, 1.25f);
final ObjectAnimator iconExpand = ObjectAnimator.ofFloat(iconLayer, IconScaleProperty.SINGLETON, 0, 1.25f);
iconExpand.setDuration(iconExpandDuration);
iconExpand.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
iconLayer.setColorFilter(mState.mLikeColor, PorterDuff.Mode.SRC_ATOP);
setColorFilter(mState.mActivatedColor, PorterDuff.Mode.SRC_ATOP);
}
});
final ObjectAnimator particleExplode = ObjectAnimator.ofFloat(particleLayer, LAYER_PROGRESS, 0, 0.5f);
final ObjectAnimator particleExplode = ObjectAnimator.ofFloat(particleLayer, LayerProgressProperty.SINGLETON, 0, 0.5f);
particleExplode.setDuration(iconExpandDuration);
final ObjectAnimator iconNormal = ObjectAnimator.ofFloat(iconLayer, ICON_SCALE, 1.25f, 1);
final ObjectAnimator iconNormal = ObjectAnimator.ofFloat(iconLayer, IconScaleProperty.SINGLETON, 1.25f, 1);
iconNormal.setDuration(iconNormalDuration);
final ObjectAnimator circleExplode = ObjectAnimator.ofFloat(circleLayer, LAYER_PROGRESS, 0.5f, 0.95f, 0.95f, 1);
final ObjectAnimator circleExplode = ObjectAnimator.ofFloat(circleLayer, LayerProgressProperty.SINGLETON, 0.5f, 0.95f, 0.95f, 1);
circleExplode.setDuration(circleExplodeDuration);
circleExplode.setInterpolator(new DecelerateInterpolator());
final ObjectAnimator particleFade = ObjectAnimator.ofFloat(particleLayer, LAYER_PROGRESS, 0.5f, 1);
final ObjectAnimator particleFade = ObjectAnimator.ofFloat(particleLayer, LayerProgressProperty.SINGLETON, 0.5f, 1);
particleFade.setDuration(particleExpandDuration);
@ -224,19 +190,19 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
@Override
public int getIntrinsicWidth() {
return mState.mIconLayer.getIntrinsicWidth();
return mState.mIconDrawable.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
return mState.mIconLayer.getIntrinsicHeight();
return mState.mIconDrawable.getIntrinsicHeight();
}
@Override
public void draw(Canvas canvas) {
mState.mCircleLayer.draw(canvas);
mState.mParticleLayer.draw(canvas);
mState.mIconLayer.draw(canvas);
mState.mIconDrawable.draw(canvas);
}
@Override
@ -247,12 +213,12 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
@Override
public void setAlpha(int alpha) {
mState.mIconLayer.setAlpha(alpha);
mState.mIconDrawable.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mState.mIconLayer.setColorFilter(colorFilter);
mState.setIconColorFilter(colorFilter);
}
@Override
@ -280,6 +246,11 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
return mState;
}
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations() | mState.getChangingConfigurations();
}
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
@ -303,39 +274,41 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
// Default values
private final int mDefaultColor;
private final int mLikeColor;
private final int mActivatedColor;
@Style
private final int mStyle;
// Layers
private final AnimationLayerDrawable mCircleLayer;
private final AnimationLayerDrawable mParticleLayer;
private final IconLayerDrawable mIconLayer;
private final ScalableDrawable mIconDrawable;
private long mDuration = 500;
private AnimatorSet mCurrentAnimator;
private WeakReference<OnLikedListener> mListenerRef;
public LikeAnimationState(final Context context, final int likeIcon, final int defaultColor,
final int likeColor, @Style final int style, Callback callback) {
public LikeAnimationState(final Drawable icon, final int defaultColor, final int activatedColor,
@Style final int style, Callback callback) {
mDefaultColor = defaultColor;
mLikeColor = likeColor;
mActivatedColor = activatedColor;
mStyle = style;
mIconLayer = new IconLayerDrawable(ContextCompat.getDrawable(context, likeIcon));
mIconLayer.setColorFilter(defaultColor, PorterDuff.Mode.SRC_ATOP);
final int intrinsicWidth = icon.getIntrinsicWidth();
final int intrinsicHeight = icon.getIntrinsicHeight();
mIconDrawable = new ScalableDrawable(icon);
setIconColorFilter(new PorterDuffColorFilter(defaultColor, PorterDuff.Mode.SRC_ATOP));
final Palette palette;
switch (style) {
case Style.FAVORITE: {
palette = new FavoritePalette();
mParticleLayer = new ShineLayerDrawable(mIconLayer.getIntrinsicWidth(),
mIconLayer.getIntrinsicHeight(), palette);
mParticleLayer = new ShineLayerDrawable(intrinsicWidth, intrinsicHeight,
palette);
break;
}
case Style.LIKE: {
palette = new LikePalette();
mParticleLayer = new ParticleLayerDrawable(mIconLayer.getIntrinsicWidth(),
mIconLayer.getIntrinsicHeight(), palette);
mParticleLayer = new ParticleLayerDrawable(intrinsicWidth, intrinsicHeight,
palette);
break;
}
default: {
@ -343,24 +316,29 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
}
}
mParticleLayer.setProgress(-1);
mCircleLayer = new CircleLayerDrawable(mIconLayer.getIntrinsicWidth(), mIconLayer.getIntrinsicHeight(), palette);
mCircleLayer = new CircleLayerDrawable(intrinsicWidth, intrinsicHeight, palette);
mIconLayer.setCallback(callback);
mIconDrawable.setCallback(callback);
mParticleLayer.setCallback(callback);
mCircleLayer.setCallback(callback);
}
public LikeAnimationState(LikeAnimationState state, LikeAnimationDrawable owner) {
mDefaultColor = state.mDefaultColor;
mLikeColor = state.mLikeColor;
mActivatedColor = state.mActivatedColor;
mStyle = state.mStyle;
mCircleLayer = (AnimationLayerDrawable) clone(state.mCircleLayer, owner);
mParticleLayer = (AnimationLayerDrawable) clone(state.mParticleLayer, owner);
mIconLayer = (IconLayerDrawable) clone(state.mIconLayer, owner);
mIconDrawable = (ScalableDrawable) clone(state.mIconDrawable, owner);
}
private Drawable clone(Drawable orig, LikeAnimationDrawable owner) {
public void setIconColorFilter(ColorFilter cf) {
mIconDrawable.setColorFilter(cf);
}
private static Drawable clone(Drawable orig, LikeAnimationDrawable owner) {
final Drawable clone = orig.getConstantState().newDrawable();
clone.mutate();
clone.setCallback(owner);
clone.setBounds(orig.getBounds());
return clone;
@ -369,7 +347,7 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
public void setBounds(int left, int top, int right, int bottom) {
mCircleLayer.setBounds(left, top, right, bottom);
mParticleLayer.setBounds(left, top, right, bottom);
mIconLayer.setBounds(left, top, right, bottom);
mIconDrawable.setBounds(left, top, right, bottom);
}
@Override
@ -379,8 +357,74 @@ public class LikeAnimationDrawable extends Drawable implements Animatable, Drawa
@Override
public int getChangingConfigurations() {
return 0;
return mCircleLayer.getChangingConfigurations() |
mParticleLayer.getChangingConfigurations() |
mIconDrawable.getChangingConfigurations();
}
}
static final class IconScaleProperty extends Property<ScalableDrawable, Float> {
static final Property<ScalableDrawable, Float> SINGLETON = new IconScaleProperty();
private IconScaleProperty() {
super(Float.class, "icon_scale");
}
@Override
public void set(ScalableDrawable object, Float value) {
object.setScale(value);
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public Float get(ScalableDrawable object) {
return object.getScale();
}
}
static final class LayerProgressProperty extends Property<Layer, Float> {
static final Property<Layer, Float> SINGLETON = new LayerProgressProperty();
private LayerProgressProperty() {
super(Float.class, "layer_progress");
}
@Override
public void set(Layer object, Float value) {
object.setProgress(value);
}
@Override
public boolean isReadOnly() {
return false;
}
@Override
public Float get(Layer object) {
return object.getProgress();
}
}
/**
* Created by mariotaku on 16/2/22.
*/
public interface Layer {
float getProgress();
void setProgress(float progress);
}
/**
* Created by mariotaku on 16/2/22.
*/
public interface Palette {
int getParticleColor(int count, int index, float progress);
int getCircleColor(float progress);
}
}

View File

@ -4,22 +4,21 @@ import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
import org.mariotaku.twidere.graphic.like.state.AbsLayerState;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public abstract class AnimationLayerDrawable<S extends AbsLayerState> extends Drawable implements Layer {
public abstract class AnimationLayerDrawable extends Drawable implements LikeAnimationDrawable.Layer {
protected S mState;
protected AnimationLayerState mState;
private boolean mMutated;
public AnimationLayerDrawable(final int intrinsicWidth, final int intrinsicHeight, final Palette palette) {
public AnimationLayerDrawable(final int intrinsicWidth, final int intrinsicHeight, final LikeAnimationDrawable.Palette palette) {
mState = createConstantState(intrinsicWidth, intrinsicHeight, palette);
}
protected abstract S createConstantState(int intrinsicWidth, int intrinsicHeight, final Palette palette);
protected abstract AnimationLayerState createConstantState(int intrinsicWidth, int intrinsicHeight, final LikeAnimationDrawable.Palette palette);
@Override
public void setAlpha(final int alpha) {
@ -72,4 +71,40 @@ public abstract class AnimationLayerDrawable<S extends AbsLayerState> extends Dr
return this;
}
/**
* Created by mariotaku on 16/2/22.
*/
public abstract static class AnimationLayerState extends ConstantState {
protected final int mIntrinsicWidth;
protected final int mIntrinsicHeight;
protected final LikeAnimationDrawable.Palette mPalette;
private float mProgress;
public AnimationLayerState(int intrinsicWidth, int intrinsicHeight, LikeAnimationDrawable.Palette palette) {
this.mPalette = palette;
this.mIntrinsicHeight = intrinsicHeight;
this.mIntrinsicWidth = intrinsicWidth;
}
public final float getProgress() {
return mProgress;
}
public final void setProgress(float progress) {
mProgress = progress;
}
public final LikeAnimationDrawable.Palette getPalette() {
return mPalette;
}
public final int getIntrinsicWidth() {
return mIntrinsicWidth;
}
public final int getIntrinsicHeight() {
return mIntrinsicHeight;
}
}
}

View File

@ -3,34 +3,35 @@ package org.mariotaku.twidere.graphic.like.layer;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
import org.mariotaku.twidere.graphic.like.state.CircleState;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public class CircleLayerDrawable extends AnimationLayerDrawable<CircleState> {
public class CircleLayerDrawable extends AnimationLayerDrawable {
public CircleLayerDrawable(final int intrinsicWidth, final int intrinsicHeight,
final Palette palette) {
final LikeAnimationDrawable.Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
}
@Override
protected CircleState createConstantState(final int intrinsicWidth,
final int intrinsicHeight,
final Palette palette) {
final LikeAnimationDrawable.Palette palette) {
return new CircleState(intrinsicWidth, intrinsicHeight, palette);
}
@Override
public void draw(final Canvas canvas) {
final CircleState state = (CircleState) mState;
final float progress = getProgress();
final Rect bounds = getBounds();
final float radius;
final Paint paint = mState.getPaint();
final int fullRadius = mState.getFullRadius();
final Paint paint = state.getPaint();
final int fullRadius = state.getFullRadius();
if (progress < 0.5f) {
paint.setStyle(Paint.Style.FILL);
final float sizeProgress = Math.min(1, progress * 2);
@ -43,14 +44,49 @@ public class CircleLayerDrawable extends AnimationLayerDrawable<CircleState> {
radius = fullRadius - strokeWidth / 2;
if (strokeWidth <= 0) return;
}
paint.setColor(mState.getPalette().getCircleColor(progress));
paint.setColor(state.getPalette().getCircleColor(progress));
canvas.drawCircle(bounds.centerX(), bounds.centerY(), radius, paint);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mState.setFullRadius(Math.min(bounds.width(), bounds.height()) / 2);
final CircleState state = (CircleState) mState;
state.setFullRadius(Math.min(bounds.width(), bounds.height()) / 2);
}
/**
* Created by mariotaku on 16/2/22.
*/
static class CircleState extends AnimationLayerState {
private final Paint mPaint;
private int mFullRadius;
public CircleState(int intrinsicWidth, int intrinsicHeight, LikeAnimationDrawable.Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
@Override
public Drawable newDrawable() {
return new CircleLayerDrawable(mIntrinsicWidth, mIntrinsicHeight, mPalette);
}
@Override
public int getChangingConfigurations() {
return 0;
}
public void setFullRadius(int fullRadius) {
mFullRadius = fullRadius;
}
public Paint getPaint() {
return mPaint;
}
public int getFullRadius() {
return mFullRadius;
}
}
}

View File

@ -1,11 +0,0 @@
package org.mariotaku.twidere.graphic.like.layer;
/**
* Created by mariotaku on 16/2/22.
*/
public interface Layer {
float getProgress();
void setProgress(float progress);
}

View File

@ -3,38 +3,39 @@ package org.mariotaku.twidere.graphic.like.layer;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
import org.mariotaku.twidere.graphic.like.state.ParticleLayerState;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public class ParticleLayerDrawable extends AnimationLayerDrawable<ParticleLayerState> {
public class ParticleLayerDrawable extends AnimationLayerDrawable {
private static final int PARTICLES_PIVOTS_COUNT = 7;
public ParticleLayerDrawable(final int intrinsicWidth, final int intrinsicHeight,
final Palette palette) {
final LikeAnimationDrawable.Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
}
@Override
protected ParticleLayerState createConstantState(final int intrinsicWidth,
final int intrinsicHeight,
final Palette palette) {
final LikeAnimationDrawable.Palette palette) {
return new ParticleLayerState(intrinsicWidth, intrinsicHeight, palette);
}
@Override
public void draw(final Canvas canvas) {
final ParticleLayerState state = (ParticleLayerState) mState;
final float progress = getProgress();
if (progress < 0) return;
final Rect bounds = getBounds();
final float expandSpinProgress = Math.min(0.5f, progress);
final float fullRadius = mState.getFullRadius();
final float fullRadius = state.getFullRadius();
final float currentRadius = fullRadius + (fullRadius * expandSpinProgress);
final float particleSize = mState.getParticleSize();
final float particleSize = state.getParticleSize();
final float distance = particleSize + (particleSize * progress);
final float mainStrokeWidth, subStrokeWidth;
if (progress < 0.5) {
@ -49,14 +50,14 @@ public class ParticleLayerDrawable extends AnimationLayerDrawable<ParticleLayerS
for (int i = 0; i < PARTICLES_PIVOTS_COUNT; i++) {
final double degree = 360.0 / PARTICLES_PIVOTS_COUNT * i;
final Palette palette = mState.getPalette();
final LikeAnimationDrawable.Palette palette = state.getPalette();
final int color = palette.getParticleColor(PARTICLES_PIVOTS_COUNT, i, progress);
final double mainParticleAngle = Math.toRadians(degree - 115);
final float mainParticleX = (float) (bounds.centerX() + currentRadius * Math.cos(mainParticleAngle));
final float mainParticleY = (float) (bounds.centerY() + currentRadius * Math.sin(mainParticleAngle));
final Paint paint = mState.getPaint();
final Paint paint = state.getPaint();
paint.setColor(color);
if (mainStrokeWidth > 0) {
canvas.drawCircle(mainParticleX, mainParticleY, mainStrokeWidth / 2, paint);
@ -77,7 +78,51 @@ public class ParticleLayerDrawable extends AnimationLayerDrawable<ParticleLayerS
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mState.setFullRadius(Math.min(bounds.width(), bounds.height()) / 2);
final ParticleLayerState state = (ParticleLayerState) mState;
state.setFullRadius(Math.min(bounds.width(), bounds.height()) / 2);
}
/**
* Created by mariotaku on 16/2/22.
*/
static class ParticleLayerState extends AnimationLayerState {
private final Paint mPaint;
private float mFullRadius;
private float mParticleSize;
public ParticleLayerState(int intrinsicWidth, int intrinsicHeight, LikeAnimationDrawable.Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.FILL);
setProgress(-1);
}
@Override
public Drawable newDrawable() {
return new ParticleLayerDrawable(mIntrinsicWidth, mIntrinsicHeight, mPalette);
}
@Override
public int getChangingConfigurations() {
return 0;
}
public float getFullRadius() {
return mFullRadius;
}
public float getParticleSize() {
return mParticleSize;
}
public Paint getPaint() {
return mPaint;
}
public void setFullRadius(int fullRadius) {
mFullRadius = fullRadius;
mParticleSize = fullRadius / 4f;
}
}
}

View File

@ -4,32 +4,31 @@ import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.view.Gravity;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public class IconLayerDrawable extends Drawable implements Drawable.Callback {
private final Drawable mDrawable;
private final Rect mTmpRect = new Rect();
public class ScalableDrawable extends Drawable implements Drawable.Callback {
private boolean mMutated;
private ScaleConstantState mState;
public IconLayerDrawable(Drawable drawable) {
public ScalableDrawable(Drawable drawable) {
if (drawable == null) throw new NullPointerException();
mState = new ScaleConstantState(drawable);
mDrawable = drawable;
drawable.setCallback(this);
mState = new ScaleConstantState(drawable, this);
setScale(1);
}
ScalableDrawable(ScaleConstantState state) {
mState = state;
}
/**
* Returns the drawable scaled by this ScaleDrawable.
*/
public Drawable getDrawable() {
return mDrawable;
return mState.mDrawable;
}
// overrides from Drawable.Callback
@ -58,57 +57,55 @@ public class IconLayerDrawable extends Drawable implements Drawable.Callback {
@Override
public void draw(Canvas canvas) {
if (mState.getScale() <= 0) return;
mDrawable.draw(canvas);
mState.mDrawable.draw(canvas);
}
@Override
public int getChangingConfigurations() {
return super.getChangingConfigurations()
| mDrawable.getChangingConfigurations();
return super.getChangingConfigurations() | mState.getChangingConfigurations();
}
@Override
public boolean getPadding(Rect padding) {
public boolean getPadding(@NonNull Rect padding) {
// XXX need to adjust padding!
return mDrawable.getPadding(padding);
return mState.mDrawable.getPadding(padding);
}
@Override
public boolean setVisible(boolean visible, boolean restart) {
mDrawable.setVisible(visible, restart);
return super.setVisible(visible, restart);
return mState.mDrawable.setVisible(visible, restart);
}
@Override
public void setAlpha(int alpha) {
mDrawable.setAlpha(alpha);
mState.mDrawable.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mDrawable.setColorFilter(cf);
mState.mDrawable.setColorFilter(cf);
}
@Override
public int getOpacity() {
return mDrawable.getOpacity();
return mState.mDrawable.getOpacity();
}
@Override
public boolean isStateful() {
return mDrawable.isStateful();
return mState.mDrawable.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
boolean changed = mDrawable.setState(state);
final boolean changed = mState.mDrawable.setState(state);
onBoundsChange(getBounds());
return changed;
}
@Override
protected boolean onLevelChange(int level) {
mDrawable.setLevel(level);
mState.mDrawable.setLevel(level);
onBoundsChange(getBounds());
invalidateSelf();
return true;
@ -121,18 +118,18 @@ public class IconLayerDrawable extends Drawable implements Drawable.Callback {
@Override
public int getIntrinsicWidth() {
return mDrawable.getIntrinsicWidth();
return mState.mDrawable.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
return mDrawable.getIntrinsicHeight();
return mState.mDrawable.getIntrinsicHeight();
}
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
mDrawable.mutate();
mState = new ScaleConstantState(this);
mMutated = true;
}
return this;
@ -154,21 +151,31 @@ public class IconLayerDrawable extends Drawable implements Drawable.Callback {
static class ScaleConstantState extends ConstantState {
private final Drawable mIcon;
private final Drawable mDrawable;
private float mScale;
private final Rect mTmpRect = new Rect();
public ScaleConstantState(Drawable icon) {
mIcon = icon;
ScaleConstantState(Drawable drawable, ScalableDrawable owner) {
mDrawable = drawable;
mDrawable.setCallback(owner);
}
ScaleConstantState(ScalableDrawable owner) {
final ScaleConstantState state = owner.mState;
mDrawable = state.mDrawable.getConstantState().newDrawable();
mDrawable.mutate();
mDrawable.setCallback(owner);
mScale = state.getScale();
}
@Override
public Drawable newDrawable() {
return new IconLayerDrawable(mIcon.mutate());
return new ScalableDrawable(this);
}
@Override
public int getChangingConfigurations() {
return mIcon.getChangingConfigurations();
return mDrawable.getChangingConfigurations();
}
public void setScale(float scale) {
@ -181,13 +188,13 @@ public class IconLayerDrawable extends Drawable implements Drawable.Callback {
}
private void updateBounds(Rect bounds) {
final Rect r = mTmpRect;
final int w = Math.round(mDrawable.getIntrinsicWidth() * mState.getScale());
final int h = Math.round(mDrawable.getIntrinsicHeight() * mState.getScale());
final Rect r = mState.mTmpRect;
final int w = Math.round(mState.mDrawable.getIntrinsicWidth() * mState.getScale());
final int h = Math.round(mState.mDrawable.getIntrinsicHeight() * mState.getScale());
Gravity.apply(Gravity.CENTER, w, h, bounds, r);
if (w > 0 && h > 0) {
mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
mState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
}
invalidateSelf();
}

View File

@ -3,38 +3,32 @@ package org.mariotaku.twidere.graphic.like.layer;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
import org.mariotaku.twidere.graphic.like.state.ShineLayerState;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public class ShineLayerDrawable extends AnimationLayerDrawable<ShineLayerState> {
public class ShineLayerDrawable extends AnimationLayerDrawable {
private static final int PARTICLES_PIVOTS_COUNT = 5;
public ShineLayerDrawable(final int intrinsicWidth, final int intrinsicHeight, final Palette palette) {
public ShineLayerDrawable(final int intrinsicWidth, final int intrinsicHeight, final LikeAnimationDrawable.Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
}
@Override
protected ShineLayerState createConstantState(final int intrinsicWidth,
final int intrinsicHeight,
final Palette palette) {
return new ShineLayerState(intrinsicWidth, intrinsicHeight, palette);
}
@Override
public void draw(Canvas canvas) {
final ShineLayerState state = (ShineLayerState) mState;
final float progress = getProgress();
if (progress < 0) return;
final Palette palette = mState.getPalette();
final LikeAnimationDrawable.Palette palette = state.getPalette();
final int particleColor = palette.getParticleColor(0, 0, progress);
final Rect bounds = getBounds();
final Paint paint = mState.getPaint();
final Paint paint = state.getPaint();
paint.setColor(particleColor);
paint.setStrokeWidth(mState.getLineWidth());
paint.setStrokeWidth(state.getLineWidth());
final float[] startEnd = new float[2];
paint.setAlpha(0xFF);
if (progress < 0.25f) {
@ -63,6 +57,20 @@ public class ShineLayerDrawable extends AnimationLayerDrawable<ShineLayerState>
}
}
@Override
protected ShineLayerState createConstantState(final int intrinsicWidth, final int intrinsicHeight,
final LikeAnimationDrawable.Palette palette) {
return new ShineLayerState(intrinsicWidth, intrinsicHeight, palette);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
final int fullRadius = Math.min(bounds.width(), bounds.height()) / 2;
final ShineLayerState state = (ShineLayerState) mState;
state.setFullRadius(fullRadius);
}
private void calcPhase4(float[] startEnd, float progress) {
calcPhase3(startEnd, 0.75f);
}
@ -74,25 +82,64 @@ public class ShineLayerDrawable extends AnimationLayerDrawable<ShineLayerState>
}
private void calcPhase2(float[] startEnd, float progress) {
final ShineLayerState state = (ShineLayerState) mState;
calcPhase1(startEnd, 0.25f);
final float length = startEnd[1] - startEnd[0];
final float initialStart = startEnd[0];
startEnd[0] = initialStart + mState.getFullRadius() / 3 * (progress - 0.25f) * 4;
startEnd[0] = initialStart + state.getFullRadius() / 3 * (progress - 0.25f) * 4;
startEnd[1] = startEnd[0] + length;
}
private void calcPhase1(float[] startEnd, float progress) {
final ShineLayerState state = (ShineLayerState) mState;
// Start point: 1/4 of icon radius
final int fullRadius = mState.getFullRadius();
final int fullRadius = state.getFullRadius();
startEnd[0] = fullRadius / 3;
startEnd[1] = startEnd[0] + (fullRadius / 4 * progress * 4);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
final int fullRadius = Math.min(bounds.width(), bounds.height()) / 2;
mState.setFullRadius(fullRadius);
}
/**
* Created by mariotaku on 16/2/22.
*/
static class ShineLayerState extends AnimationLayerState {
private final Paint mPaint;
private int mFullRadius;
private float mLineWidth;
public ShineLayerState(int intrinsicWidth, int intrinsicHeight, LikeAnimationDrawable.Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeCap(Paint.Cap.ROUND);
setProgress(-1);
}
public Paint getPaint() {
return mPaint;
}
@Override
public Drawable newDrawable() {
return new ShineLayerDrawable(mIntrinsicWidth, mIntrinsicHeight, mPalette);
}
@Override
public int getChangingConfigurations() {
return 0;
}
public int getFullRadius() {
return mFullRadius;
}
public void setFullRadius(int fullRadius) {
mFullRadius = fullRadius;
mLineWidth = fullRadius / 10f;
}
public float getLineWidth() {
return mLineWidth;
}
}
}

View File

@ -2,10 +2,12 @@ package org.mariotaku.twidere.graphic.like.palette;
import android.animation.ArgbEvaluator;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public final class FavoritePalette implements Palette {
public final class FavoritePalette implements LikeAnimationDrawable.Palette {
private final ArgbEvaluator evaluator = new ArgbEvaluator();

View File

@ -3,10 +3,12 @@ package org.mariotaku.twidere.graphic.like.palette;
import android.animation.ArgbEvaluator;
import android.graphics.Color;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
/**
* Created by mariotaku on 16/2/22.
*/
public final class LikePalette implements Palette {
public final class LikePalette implements LikeAnimationDrawable.Palette {
private final ArgbEvaluator evaluator = new ArgbEvaluator();
private final float[] hsv = new float[3];

View File

@ -1,10 +0,0 @@
package org.mariotaku.twidere.graphic.like.palette;
/**
* Created by mariotaku on 16/2/22.
*/
public interface Palette {
int getParticleColor(int count, int index, float progress);
int getCircleColor(float progress);
}

View File

@ -1,42 +0,0 @@
package org.mariotaku.twidere.graphic.like.state;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
/**
* Created by mariotaku on 16/2/22.
*/
public abstract class AbsLayerState extends Drawable.ConstantState {
protected final int mIntrinsicWidth;
protected final int mIntrinsicHeight;
protected final Palette mPalette;
private float mProgress;
public AbsLayerState(int intrinsicWidth, int intrinsicHeight, Palette palette) {
this.mPalette = palette;
this.mIntrinsicHeight = intrinsicHeight;
this.mIntrinsicWidth = intrinsicWidth;
}
public final float getProgress() {
return mProgress;
}
public final void setProgress(float progress) {
mProgress = progress;
}
public final Palette getPalette() {
return mPalette;
}
public final int getIntrinsicWidth() {
return mIntrinsicWidth;
}
public final int getIntrinsicHeight() {
return mIntrinsicHeight;
}
}

View File

@ -1,42 +0,0 @@
package org.mariotaku.twidere.graphic.like.state;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.layer.CircleLayerDrawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
/**
* Created by mariotaku on 16/2/22.
*/
public class CircleState extends AbsLayerState {
private final Paint mPaint;
private int mFullRadius;
public CircleState(int intrinsicWidth, int intrinsicHeight, Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
@Override
public Drawable newDrawable() {
return new CircleLayerDrawable(mIntrinsicWidth, mIntrinsicHeight, mPalette);
}
@Override
public int getChangingConfigurations() {
return 0;
}
public void setFullRadius(int fullRadius) {
mFullRadius = fullRadius;
}
public Paint getPaint() {
return mPaint;
}
public int getFullRadius() {
return mFullRadius;
}
}

View File

@ -1,51 +0,0 @@
package org.mariotaku.twidere.graphic.like.state;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.layer.ParticleLayerDrawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
/**
* Created by mariotaku on 16/2/22.
*/
public class ParticleLayerState extends AbsLayerState {
private final Paint mPaint;
private float mFullRadius;
private float mParticleSize;
public ParticleLayerState(int intrinsicWidth, int intrinsicHeight, Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.FILL);
setProgress(-1);
}
@Override
public Drawable newDrawable() {
return new ParticleLayerDrawable(mIntrinsicWidth, mIntrinsicHeight, mPalette);
}
@Override
public int getChangingConfigurations() {
return 0;
}
public float getFullRadius() {
return mFullRadius;
}
public float getParticleSize() {
return mParticleSize;
}
public Paint getPaint() {
return mPaint;
}
public void setFullRadius(int fullRadius) {
mFullRadius = fullRadius;
mParticleSize = fullRadius / 4f;
}
}

View File

@ -1,52 +0,0 @@
package org.mariotaku.twidere.graphic.like.state;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import org.mariotaku.twidere.graphic.like.layer.ShineLayerDrawable;
import org.mariotaku.twidere.graphic.like.palette.Palette;
/**
* Created by mariotaku on 16/2/22.
*/
public class ShineLayerState extends AbsLayerState {
private final Paint mPaint;
private int mFullRadius;
private float mLineWidth;
public ShineLayerState(int intrinsicWidth, int intrinsicHeight, Palette palette) {
super(intrinsicWidth, intrinsicHeight, palette);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeCap(Paint.Cap.ROUND);
setProgress(-1);
}
public Paint getPaint() {
return mPaint;
}
@Override
public Drawable newDrawable() {
return new ShineLayerDrawable(mIntrinsicWidth, mIntrinsicHeight, mPalette);
}
@Override
public int getChangingConfigurations() {
return 0;
}
public int getFullRadius() {
return mFullRadius;
}
public void setFullRadius(int fullRadius) {
mFullRadius = fullRadius;
mLineWidth = fullRadius / 10f;
}
public float getLineWidth() {
return mLineWidth;
}
}

View File

@ -2,6 +2,7 @@ package org.mariotaku.twidere.menu.support;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ActionProvider;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ActionMenuView;
@ -62,8 +63,10 @@ public class FavoriteItemProvider extends ActionProvider {
public void init(final ActionMenuView menuBar, MenuItem item) {
if (MenuItemCompat.getActionProvider(item) != this) throw new IllegalArgumentException();
final LikeAnimationDrawable drawable = new LikeAnimationDrawable(getContext(), mIcon,
mDefaultColor, mActivatedColor, mUseStar ? Style.FAVORITE : Style.LIKE);
final Drawable icon = ContextCompat.getDrawable(getContext(), mIcon);
final LikeAnimationDrawable drawable = new LikeAnimationDrawable(icon, mDefaultColor,
mActivatedColor, mUseStar ? Style.FAVORITE : Style.LIKE);
drawable.mutate();
drawable.setCallback(new ViewCallback(menuBar));
item.setIcon(drawable);
}

View File

@ -5,26 +5,33 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.preference.CheckBoxPreference;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
public class ComponentStatePreference extends CheckBoxPreference {
import org.jraf.android.backport.switchwidget.SwitchPreference;
public class ComponentStatePreference extends SwitchPreference {
private final PackageManager mPackageManager;
private final ComponentName mComponentName;
public ComponentStatePreference(final Context context) {
this(context, null);
public ComponentStatePreference(Context context) {
super(context);
mPackageManager = context.getPackageManager();
mComponentName = getComponentName(context, null);
setDefaultValue(isComponentEnabled());
}
public ComponentStatePreference(final Context context, final AttributeSet attrs) {
this(context, attrs, android.R.attr.checkBoxPreferenceStyle);
public ComponentStatePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPackageManager = context.getPackageManager();
mComponentName = getComponentName(context, attrs);
setDefaultValue(isComponentEnabled());
}
public ComponentStatePreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
public ComponentStatePreference(Context context, AttributeSet attrs) {
super(context, attrs);
mPackageManager = context.getPackageManager();
mComponentName = getComponentName(context, attrs);
setDefaultValue(isComponentEnabled());

View File

@ -79,17 +79,17 @@ public class CacheProvider extends ContentProvider {
@Nullable
@Override
public Uri insert(@NonNull Uri uri, ContentValues values) {
throw new UnsupportedOperationException();
return null;
}
@Override
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
return 0;
}
@Override
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
return 0;
}
@Nullable

View File

@ -35,6 +35,7 @@ import org.mariotaku.twidere.util.media.preview.PreviewMediaExtractor;
import org.mariotaku.twidere.util.net.NoIntercept;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by mariotaku on 16/1/28.
@ -137,7 +138,24 @@ public class TwidereMediaDownloader implements MediaDownloader, Constants {
throw new IOException("Unable to get media, response code: " + resp.getStatus());
}
final Body body = resp.getBody();
return new CacheDownloadLoader.DownloadResult(body.length(), body.stream());
final long length = body.length();
final InputStream stream = body.stream();
return new CacheDownloadLoader.DownloadResult() {
@Override
public void close() throws IOException {
body.close();
}
@Override
public long getLength() {
return length;
}
@Override
public InputStream getStream() {
return stream;
}
};
}
private String getEndpoint(Uri uri) {

View File

@ -227,7 +227,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
manager.getUserColor(status.user_id, false));
} else {
statusContentSpace.setVisibility(adapter.isCardActionsHidden() ? View.VISIBLE :View.GONE);
statusContentSpace.setVisibility(adapter.isCardActionsHidden() ? View.VISIBLE : View.GONE);
quotedNameView.setVisibility(View.GONE);
quotedTextView.setVisibility(View.GONE);
@ -428,10 +428,11 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
likeIcon = R.drawable.ic_action_heart;
likeStyle = LikeAnimationDrawable.Style.LIKE;
}
final LikeAnimationDrawable drawable = new LikeAnimationDrawable(adapter.getContext(),
likeIcon, favoriteCountView.getColor(), favoriteCountView.getActivatedColor(),
likeStyle);
final Drawable icon = ContextCompat.getDrawable(adapter.getContext(), likeIcon);
final LikeAnimationDrawable drawable = new LikeAnimationDrawable(icon,
favoriteCountView.getColor(), favoriteCountView.getActivatedColor(), likeStyle);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.mutate();
TextViewCompat.setCompoundDrawablesRelative(favoriteCountView, drawable, null, null, null);
drawable.setCallback(favoriteCountView);
timeView.setShowAbsoluteTime(adapter.isShowAbsoluteTime());

View File

@ -55,7 +55,7 @@
android:id="@+id/status_info_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/element_spacing_minus_small"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/element_spacing_small"
android:layout_marginStart="@dimen/element_spacing_small"
android:layout_toEndOf="@+id/status_info_icon"
@ -222,7 +222,7 @@
<android.support.v4.widget.Space
android:id="@+id/status_content_space"
android:layout_width="match_parent"
android:layout_height="@dimen/element_spacing_small"
android:layout_height="@dimen/element_spacing_normal"
android:layout_below="@+id/media_preview"/>
</RelativeLayout>
@ -234,7 +234,7 @@
android:layout_alignLeft="@id/status_content"
android:layout_alignStart="@id/status_content"
android:layout_below="@+id/status_content"
android:layout_marginTop="@dimen/element_spacing_minus_small"
android:layout_marginTop="@dimen/element_spacing_minus_normal"
android:layout_toLeftOf="@+id/item_menu"
android:layout_toStartOf="@+id/item_menu"
android:clipChildren="false"
@ -246,12 +246,13 @@
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card_compact"
android:layout_height="wrap_content"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_reply"
android:drawableStart="@drawable/ic_action_reply"
android:focusable="false"
android:gravity="center"
android:minHeight="@dimen/button_size_content_card_compact"
android:paddingLeft="@dimen/element_spacing_msmall"
android:paddingRight="@dimen/element_spacing_msmall"
android:textAppearance="?android:textAppearanceSmall"
@ -262,12 +263,13 @@
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_height="wrap_content"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_retweet"
android:drawableStart="@drawable/ic_action_retweet"
android:focusable="false"
android:gravity="center"
android:minHeight="@dimen/button_size_content_card_compact"
android:paddingLeft="@dimen/element_spacing_msmall"
android:paddingRight="@dimen/element_spacing_msmall"
android:textAppearance="?android:textAppearanceSmall"
@ -278,10 +280,11 @@
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_height="wrap_content"
android:layout_weight="0"
android:focusable="false"
android:gravity="center"
android:minHeight="@dimen/button_size_content_card_compact"
android:paddingLeft="@dimen/element_spacing_msmall"
android:paddingRight="@dimen/element_spacing_msmall"
android:textAppearance="?android:textAppearanceSmall"

View File

@ -745,4 +745,5 @@
<string name="recent_media">Recent media</string>
<string name="reply_to_name_text">Reply to <xliff:g id="name">%1$s</xliff:g>: <xliff:g id="text">%2$s</xliff:g></string>
<string name="quote_name_text">Quote <xliff:g id="name">%1$s</xliff:g>: <xliff:g id="text">%2$s</xliff:g></string>
<string name="unsupported_login_verification_type_name">Unsupported login verification type <xliff:g id="name">%1$s</xliff:g>, please report to support account.</string>
</resources>