1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-03 10:07:38 +01:00

improved theme on pre-lollipop devices

This commit is contained in:
Mariotaku Lee 2017-03-06 15:12:18 +08:00
parent 087ccbe927
commit 4580ff8aa5
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
5 changed files with 85 additions and 24 deletions

View File

@ -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'

View File

@ -0,0 +1,30 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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";
}

View File

@ -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);
}
}

View File

@ -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<String?> {
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<String?> {
return loadProfileImage(context, account.user, shapeStyle)
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE,
size: String? = null): DrawableRequestBuilder<String?> {
return loadProfileImage(context, account.user, shapeStyle, size)
}
fun RequestManager.loadProfileImage(context: Context, user: ParcelableUser,
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE): DrawableRequestBuilder<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE,
size: String? = null): DrawableRequestBuilder<String?> {
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<String?> {
@ImageShapeStyle shapeStyle: Int = ImageShapeStyle.SHAPE_CIRCLE,
size: String? = null): DrawableRequestBuilder<String?> {
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)
}
}

View File

@ -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<AccountsInfo>,
//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<AccountsInfo>,
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()