From 4580ff8aa5105fc99579af892b5d53f547608cd7 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Mon, 6 Mar 2017 15:12:18 +0800 Subject: [PATCH] improved theme on pre-lollipop devices --- twidere/build.gradle | 2 +- .../twidere/annotation/ProfileImageSize.java | 30 ++++++++++++++++ .../twidere/view/ShapedImageView.java | 35 ++++++++++++++----- .../twidere/extension/GlideExtensions.kt | 34 ++++++++++++------ .../fragment/AccountsDashboardFragment.kt | 8 +++-- 5 files changed, 85 insertions(+), 24 deletions(-) create mode 100644 twidere/src/main/java/org/mariotaku/twidere/annotation/ProfileImageSize.java diff --git a/twidere/build.gradle b/twidere/build.gradle index b5fc64e88..46a95d9ee 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -182,7 +182,7 @@ dependencies { compile "com.github.mariotaku.CommonsLibrary:text:${libVersions['MariotakuCommons']}" compile "com.github.mariotaku.CommonsLibrary:text-kotlin:${libVersions['MariotakuCommons']}" compile 'com.github.mariotaku:KPreferences:0.9.5' - compile 'com.github.mariotaku:Chameleon:0.9.14' + compile 'com.github.mariotaku:Chameleon:0.9.15' compile "org.jetbrains.kotlin:kotlin-stdlib:${libVersions['Kotlin']}" compile 'nl.komponents.kovenant:kovenant:3.3.0' diff --git a/twidere/src/main/java/org/mariotaku/twidere/annotation/ProfileImageSize.java b/twidere/src/main/java/org/mariotaku/twidere/annotation/ProfileImageSize.java new file mode 100644 index 000000000..3afe85abc --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/annotation/ProfileImageSize.java @@ -0,0 +1,30 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.annotation; + +/** + * Created by mariotaku on 2017/3/6. + */ + +public @interface ProfileImageSize { + String REASONABLY_SMALL = "reasonably_small"; + String BIGGER = "bigger"; + String NORMAL = "normal"; +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java b/twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java index ed90155cb..6f888410f 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/ShapedImageView.java @@ -35,9 +35,9 @@ import android.graphics.SweepGradient; import android.os.Build; import android.support.annotation.NonNull; import android.support.v4.view.ViewCompat; +import android.support.v7.widget.AppCompatImageView; import android.util.AttributeSet; import android.view.View; -import android.widget.ImageView; import org.mariotaku.twidere.R; import org.mariotaku.twidere.annotation.ImageShapeStyle; @@ -49,14 +49,14 @@ import org.mariotaku.twidere.util.support.view.ViewOutlineProviderCompat; * An ImageView class with a circle mask so that all images are drawn in a * circle instead of a square. */ -public class ShapedImageView extends ImageView { +public class ShapedImageView extends AppCompatImageView { private static final int SHADOW_START_COLOR = 0x37000000; public static final boolean OUTLINE_DRAW = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; private final RectF mDestination; - private final Paint mBorderPaint; + private final Paint mBackgroundPaint, mBorderPaint; private boolean mBorderEnabled; private Bitmap mShadowBitmap; private float mShadowRadius; @@ -82,6 +82,9 @@ public class ShapedImageView extends ImageView { mDestination = new RectF(); + mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mBackgroundPaint.setStyle(Paint.Style.FILL); + mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBorderPaint.setStyle(Paint.Style.STROKE); @@ -108,12 +111,20 @@ public class ShapedImageView extends ImageView { } else { mShadowRadius = a.getDimensionPixelSize(R.styleable.ShapedImageView_sivElevation, 0); } - setBackgroundColor(a.getColor(R.styleable.ShapedImageView_sivBackgroundColor, 0)); + setShapeBackground(a.getColor(R.styleable.ShapedImageView_sivBackgroundColor, 0)); a.recycle(); initOutlineProvider(); } + public void setShapeBackground(final int color) { + if (OUTLINE_DRAW) { + setBackgroundColor(color); + } else { + mBackgroundPaint.setColor(color); + } + } + public int[] getBorderColors() { return mBorderColors; } @@ -168,6 +179,10 @@ public class ShapedImageView extends ImageView { @Override protected void onDraw(@NonNull Canvas canvas) { + + mDestination.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), + getHeight() - getPaddingBottom()); + if (OUTLINE_DRAW) { super.onDraw(canvas); } else { @@ -181,11 +196,9 @@ public class ShapedImageView extends ImageView { canvas.drawBitmap(mShadowBitmap, contentLeft + (contentWidth - size) / 2 - mShadowRadius, contentTop + (contentHeight - size) / 2 - mShadowRadius, null); } + drawShape(canvas, mDestination, 0, mBackgroundPaint); super.onDraw(canvas); } - - mDestination.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), - getHeight() - getPaddingBottom()); // Then draw the border. if (mBorderEnabled) { drawBorder(canvas, mDestination); @@ -237,14 +250,18 @@ public class ShapedImageView extends ImageView { ViewCompat.setTranslationZ(this, 0); } mBorderPaint.setStrokeWidth(strokeWidth); + drawShape(canvas, dest, strokeWidth, mBorderPaint); + } + + private void drawShape(@NonNull final Canvas canvas, @NonNull final RectF dest, final float strokeWidth, final Paint paint) { if (getStyle() == ImageShapeStyle.SHAPE_CIRCLE) { final float circleRadius = Math.min(dest.width(), dest.height()) / 2f - strokeWidth / 2; - canvas.drawCircle(dest.centerX(), dest.centerY(), circleRadius, mBorderPaint); + canvas.drawCircle(dest.centerX(), dest.centerY(), circleRadius, paint); } else { final float radius = getCalculatedCornerRadius(); final float inset = mStrokeWidth / 2; dest.inset(inset, inset); - canvas.drawRoundRect(dest, radius, radius, mBorderPaint); + canvas.drawRoundRect(dest, radius, radius, paint); dest.inset(-inset, -inset); } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt index 3f190e070..062d889c7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/GlideExtensions.kt @@ -37,7 +37,7 @@ fun RequestManager.loadProfileImage( context: Context, url: String?, @ImageShapeStyle style: Int = ImageShapeStyle.SHAPE_CIRCLE, - size: String = context.getString(R.string.profile_image_size) + size: String? = null ): DrawableRequestBuilder { return configureLoadProfileImage(context, style) { load(Utils.getTwitterProfileImageOfSize(url, size)) } } @@ -48,17 +48,25 @@ fun RequestManager.loadProfileImage(context: Context, resourceId: Int, } fun RequestManager.loadProfileImage(context: Context, account: AccountDetails, - @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder { - return loadProfileImage(context, account.user, shapeStyle) + @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE, + size: String? = null): DrawableRequestBuilder { + return loadProfileImage(context, account.user, shapeStyle, size) } fun RequestManager.loadProfileImage(context: Context, user: ParcelableUser, - @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder { + @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE, + size: String? = null): DrawableRequestBuilder { if (user.extras != null && user.extras.profile_image_url_fallback == null) { // No fallback image, use compatible logic - return loadProfileImage(context, user.profile_image_url) + return loadProfileImage(context, user.profile_image_url, shapeStyle, size) + } + return configureLoadProfileImage(context, shapeStyle) { + if (size != null) { + return@configureLoadProfileImage load(Utils.getTwitterProfileImageOfSize(user.profile_image_url, size)) + } else { + return@configureLoadProfileImage load(user.profile_image_url) + } } - return configureLoadProfileImage(context, shapeStyle) { load(user.profile_image_url) } } fun RequestManager.loadProfileImage(context: Context, userList: ParcelableUserList, @@ -72,25 +80,29 @@ fun RequestManager.loadProfileImage(context: Context, group: ParcelableGroup, } fun RequestManager.loadProfileImage(context: Context, status: ParcelableStatus, - @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder { + @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE, + size: String? = null): DrawableRequestBuilder { if (status.extras != null && status.extras.user_profile_image_url_fallback == null) { // No fallback image, use compatible logic - return loadProfileImage(context, status.user_profile_image_url) + return loadProfileImage(context, status.user_profile_image_url, shapeStyle, size) } return configureLoadProfileImage(context, shapeStyle) { load(status.user_profile_image_url) } } -fun RequestManager.loadProfileImage(context: Context, conversation: ParcelableMessageConversation): DrawableRequestBuilder<*> { +fun RequestManager.loadProfileImage(context: Context, conversation: ParcelableMessageConversation, + @ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE, + size: String? = null): DrawableRequestBuilder<*> { if (conversation.conversation_type == ParcelableMessageConversation.ConversationType.ONE_TO_ONE) { val user = conversation.user if (user != null) { - return loadProfileImage(context, user) + return loadProfileImage(context, user, shapeStyle, size) } else { // TODO: show default conversation icon return loadProfileImage(context, org.mariotaku.twidere.R.drawable.ic_profile_image_default_group) } } else { - return loadProfileImage(context, conversation.conversation_avatar).placeholder(R.drawable.ic_profile_image_default_group) + return loadProfileImage(context, conversation.conversation_avatar, shapeStyle, size) + .placeholder(R.drawable.ic_profile_image_default_group) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt index d164f61a3..5a934e2e7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt @@ -67,6 +67,7 @@ import org.mariotaku.twidere.activity.* import org.mariotaku.twidere.adapter.RecyclerPagerAdapter import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.CustomTabType +import org.mariotaku.twidere.annotation.ProfileImageSize import org.mariotaku.twidere.annotation.Referral import org.mariotaku.twidere.constant.KeyboardShortcutConstants.* import org.mariotaku.twidere.constant.extraFeaturesNoticeVersionKey @@ -450,8 +451,8 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, //TODO complete border color clickedColors = clickedImageView.borderColors val oldSelectedAccount = accountsAdapter.selectedAccount ?: return - Glide.with(this@AccountsDashboardFragment).loadProfileImage(context, - oldSelectedAccount).into(clickedImageView).onLoadStarted(profileDrawable) + Glide.with(this@AccountsDashboardFragment).loadProfileImage(context, oldSelectedAccount) + .into(clickedImageView).onLoadStarted(profileDrawable) //TODO complete border color clickedImageView.setBorderColors(*profileImageView.borderColors) @@ -509,7 +510,8 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, val account = accountsAdapter.selectedAccount ?: return accountProfileNameView.text = account.user.name accountProfileScreenNameView.text = "@${account.user.screen_name}" - Glide.with(this).loadProfileImage(context, account).placeholder(profileImageSnapshot).into(accountProfileImageView) + Glide.with(this).loadProfileImage(context, account, size = ProfileImageSize.REASONABLY_SMALL) + .placeholder(profileImageSnapshot).into(accountProfileImageView) //TODO complete border color accountProfileImageView.setBorderColors(account.color) accountProfileBanner.showNext()