diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/AlbumViewCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/AlbumViewCell.java index af61511c..653395e9 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/AlbumViewCell.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/AlbumViewCell.java @@ -19,6 +19,7 @@ package org.floens.chan.ui.cell; import android.content.Context; import android.util.AttributeSet; +import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.TextView; @@ -53,6 +54,7 @@ public class AlbumViewCell extends FrameLayout { protected void onFinishInflate() { super.onFinishInflate(); thumbnailView = findViewById(R.id.thumbnail_view); + thumbnailView.setRounding(dp(8)); text = findViewById(R.id.text); } @@ -89,4 +91,12 @@ public class AlbumViewCell extends FrameLayout { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } + + public void hideLabel() { + text.setAlpha(0f); + } + + public void showLabel() { + text.animate().alpha(1f).setDuration(200).setInterpolator(new DecelerateInterpolator(2f)); + } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java index 148f935a..5d630083 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java @@ -84,6 +84,7 @@ import static android.text.TextUtils.isEmpty; import static org.floens.chan.Chan.injector; import static org.floens.chan.utils.AndroidUtils.ROBOTO_CONDENSED_REGULAR; import static org.floens.chan.utils.AndroidUtils.dp; +import static org.floens.chan.utils.AndroidUtils.enableHighEndAnimations; import static org.floens.chan.utils.AndroidUtils.getString; import static org.floens.chan.utils.AndroidUtils.setRoundItemBackground; import static org.floens.chan.utils.AndroidUtils.sp; @@ -160,7 +161,7 @@ public class PostCell extends LinearLayout implements PostCellInterface { filterMatchColor = findViewById(R.id.filter_match_color); int textSizeSp = Integer.parseInt(ChanSettings.fontSize.get()); - paddingPx = dp(textSizeSp - 6); + paddingPx = dp(textSizeSp - 7); detailsSizePx = sp(textSizeSp - 4); title.setTextSize(textSizeSp); title.setPadding(paddingPx, paddingPx, dp(52), 0); @@ -378,7 +379,7 @@ public class PostCell extends LinearLayout implements PostCellInterface { time = DateUtils.getRelativeTimeSpanString(post.time * 1000L, Time.get(), DateUtils.SECOND_IN_MILLIS, 0); } - String noText = "No." + post.no; + String noText = "#" + post.no; SpannableString date = new SpannableString(noText + " " + time); date.setSpan(new ForegroundColorSpanHashed(theme.detailsColor), 0, date.length(), 0); date.setSpan(new AbsoluteSizeSpanHashed(detailsSizePx), 0, date.length(), 0); @@ -565,10 +566,14 @@ public class PostCell extends LinearLayout implements PostCellInterface { p.addRule(RelativeLayout.BELOW, lastId); } + p.topMargin = paddingPx; + p.leftMargin = paddingPx; + p.bottomMargin = paddingPx; + v.setPostImage(image, size, size); v.setClickable(true); v.setOnClickListener(v2 -> callback.onThumbnailClicked(post, image, v)); - v.setRounding(dp(2)); + v.setRounding(dp(enableHighEndAnimations() ? 8 : 2)); relativeLayoutContainer.addView(v, p); thumbnailViews.add(v); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java index 9b558029..1450f8fa 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumDownloadController.java @@ -225,6 +225,7 @@ public class AlbumDownloadController extends Controller implements View.OnClickL itemView.getLayoutParams().height = recyclerView.getRealSpanWidth(); checkbox = itemView.findViewById(R.id.checkbox); thumbnailView = itemView.findViewById(R.id.thumbnail_view); + thumbnailView.setRounding(dp(4)); itemView.setOnClickListener(this); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java index ea445154..90b26c0f 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/AlbumViewController.java @@ -93,26 +93,44 @@ public class AlbumViewController extends Controller implements @Override public ThumbnailView getPreviewImageTransitionView(ImageViewerController imageViewerController, PostImage postImage) { - ThumbnailView thumbnail = null; + AlbumViewCell cell = findCellForImage(postImage); + if (cell != null) { + return cell.getThumbnailView(); + } + return null; + } + + @Override + public void onPreviewCreate(ImageViewerController imageViewerController, PostImage postImage) { + } + + @Override + public void onBeforePreviewDestroy(ImageViewerController imageViewerController, PostImage postImage) { + AlbumViewCell cell = findCellForImage(postImage); + if (cell != null) { + cell.hideLabel(); + } + } + + @Override + public void onPreviewDestroy(ImageViewerController imageViewerController, PostImage postImage) { + AlbumViewCell cell = findCellForImage(postImage); + if (cell != null) { + cell.showLabel(); + } + } + + private AlbumViewCell findCellForImage(PostImage postImage) { for (int i = 0; i < recyclerView.getChildCount(); i++) { View view = recyclerView.getChildAt(i); if (view instanceof AlbumViewCell) { AlbumViewCell cell = (AlbumViewCell) view; if (postImage == cell.getPostImage()) { - thumbnail = cell.getThumbnailView(); - break; + return cell; } } } - return thumbnail; - } - - @Override - public void onPreviewCreate(ImageViewerController imageViewerController) { - } - - @Override - public void onPreviewDestroy(ImageViewerController imageViewerController) { + return null; } @Override diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java index a4f3a7e1..7a05c547 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerController.java @@ -388,7 +388,8 @@ public class ImageViewerController extends Controller implements ImageViewerPres startAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { - imageViewerCallback.onPreviewCreate(ImageViewerController.this); + imageViewerCallback.onPreviewCreate( + ImageViewerController.this, postImage); } @Override @@ -486,16 +487,17 @@ public class ImageViewerController extends Controller implements ImageViewerPres endAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - previewOutAnimationEnded(); + previewOutAnimationEnded(postImage); } }); endAnimation.start(); + imageViewerCallback.onBeforePreviewDestroy(this, postImage); } - private void previewOutAnimationEnded() { + private void previewOutAnimationEnded(PostImage postImage) { setBackgroundAlpha(0f); - imageViewerCallback.onPreviewDestroy(this); + imageViewerCallback.onPreviewDestroy(this, postImage); navigationController.stopPresenting(false); } @@ -513,7 +515,7 @@ public class ImageViewerController extends Controller implements ImageViewerPres startView.getLocationInWindow(loc); Point windowLocation = new Point(loc[0], loc[1]); Point size = new Point(startView.getWidth(), startView.getHeight()); - previewImage.setSourceImageView(windowLocation, size, bitmap); + previewImage.setSourceImageView(windowLocation, size, bitmap, startView.getRounding()); return true; } @@ -556,9 +558,11 @@ public class ImageViewerController extends Controller implements ImageViewerPres public interface ImageViewerCallback { ThumbnailView getPreviewImageTransitionView(ImageViewerController imageViewerController, PostImage postImage); - void onPreviewCreate(ImageViewerController imageViewerController); + void onPreviewCreate(ImageViewerController imageViewerController, PostImage postImage); - void onPreviewDestroy(ImageViewerController imageViewerController); + void onBeforePreviewDestroy(ImageViewerController imageViewerController, PostImage postImage); + + void onPreviewDestroy(ImageViewerController imageViewerController, PostImage postImage); void scrollToImage(PostImage postImage); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java index bc7fbb6c..72567ed1 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/PostRepliesController.java @@ -44,6 +44,8 @@ import org.floens.chan.ui.helper.PostPopupHelper; import org.floens.chan.ui.view.LoadView; import org.floens.chan.ui.view.ThumbnailView; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static org.floens.chan.ui.theme.ThemeHelper.theme; @@ -125,6 +127,28 @@ public class PostRepliesController extends Controller { } } + public List getThumbnails() { + if (listView == null) { + return Collections.emptyList(); + } else { + List thumbnails = new ArrayList<>(7); + for (int i = 0; i < listView.getChildCount(); i++) { + View view = listView.getChildAt(i); + if (view instanceof PostCellInterface) { + PostCellInterface postView = (PostCellInterface) view; + Post post = postView.getPost(); + + if (!post.images.isEmpty()) { + for (int j = 0; j < post.images.size(); j++) { + thumbnails.add(postView.getThumbnailView(post.images.get(j))); + } + } + } + } + return thumbnails; + } + } + public void setPostRepliesData(PostPopupHelper.RepliesData data) { displayData(data); } @@ -180,7 +204,6 @@ public class PostRepliesController extends Controller { } else { repliesBackText.setTextColor(0xffffffff); repliesCloseText.setTextColor(0xffffffff); - dataView.findViewById(R.id.container).setBackgroundResource(R.drawable.dialog_full_dark); } ArrayAdapter adapter = new ArrayAdapter(context, 0) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java index d4709675..0d639551 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java @@ -194,18 +194,45 @@ public abstract class ThreadController extends Controller implements return threadLayout.getThumbnail(postImage); } - public void onPreviewCreate(ImageViewerController imageViewerController) { -// presentingImageView.setVisibility(View.INVISIBLE); + public void onPreviewCreate(ImageViewerController imageViewerController, PostImage postImage) { + ThumbnailView thumbnailView = getPreviewImageTransitionView(imageViewerController, postImage); + if (thumbnailView != null) { + thumbnailView.hide(false); + } } @Override - public void onPreviewDestroy(ImageViewerController imageViewerController) { -// presentingImageView.setVisibility(View.VISIBLE); -// presentingImageView = null; + public void onBeforePreviewDestroy(ImageViewerController imageViewerController, PostImage postImage) { + } + + @Override + public void onPreviewDestroy(ImageViewerController imageViewerController, PostImage postImage) { + ThumbnailView thumbnail = threadLayout.getThumbnail(postImage); + if (thumbnail != null) { + thumbnail.show(false); + } } @Override public void scrollToImage(PostImage postImage) { + ThumbnailView focused = threadLayout.getThumbnail(postImage); + if (focused != null) { + focused.hide(true); + } else { + AndroidUtils.waitForLayout(threadLayout, (v) -> { + ThumbnailView focused2 = threadLayout.getThumbnail(postImage); + if (focused2 != null) { + focused2.hide(true); + } + return true; + }); + } + for (ThumbnailView visible : threadLayout.getAllVisibleThumbnails()) { + if (visible != focused) { + visible.show(true); + } + } + threadLayout.getPresenter().scrollToImage(postImage, true); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/helper/PostPopupHelper.java b/Clover/app/src/main/java/org/floens/chan/ui/helper/PostPopupHelper.java index 6882f524..98d37dea 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/helper/PostPopupHelper.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/helper/PostPopupHelper.java @@ -87,6 +87,10 @@ public class PostPopupHelper { return presentingController.getThumbnail(postImage); } + public List getThumbnails() { + return presentingController.getThumbnails(); + } + public void postClicked(Post p) { popAll(); presenter.highlightPost(p); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java index 018226aa..2a0528de 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java @@ -509,6 +509,14 @@ public class ThreadLayout extends CoordinatorLayout implements } } + public List getAllVisibleThumbnails() { + if (postPopupHelper.isOpen()) { + return postPopupHelper.getThumbnails(); + } else { + return threadListLayout.getThumbnails(); + } + } + public boolean postRepliesOpen() { return postPopupHelper.isOpen(); } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java index 15863af4..bbb997cf 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java @@ -56,6 +56,7 @@ import org.floens.chan.ui.view.FastScrollerHelper; import org.floens.chan.ui.view.ThumbnailView; import org.floens.chan.utils.AndroidUtils; +import java.util.ArrayList; import java.util.Calendar; import java.util.List; @@ -457,6 +458,26 @@ public class ThreadListLayout extends FrameLayout implements ReplyLayout.ReplyLa return null; } + public List getThumbnails() { + List thumbnails = new ArrayList<>(7); + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + + for (int i = 0; i < layoutManager.getChildCount(); i++) { + View view = layoutManager.getChildAt(i); + if (view instanceof PostCellInterface) { + PostCellInterface postView = (PostCellInterface) view; + Post post = postView.getPost(); + + if (!post.images.isEmpty()) { + for (PostImage image : post.images) { + thumbnails.add(postView.getThumbnailView(image)); + } + } + } + } + return thumbnails; + } + public void scrollTo(int displayPosition, boolean smooth) { if (displayPosition < 0) { int bottom = postAdapter.getItemCount() - 1; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailView.java index 7bd18f36..03c297ab 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailView.java @@ -17,6 +17,9 @@ */ package org.floens.chan.ui.view; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Bitmap; @@ -49,6 +52,8 @@ import static org.floens.chan.utils.AndroidUtils.sp; public class ThumbnailView extends View implements ImageLoader.ImageListener { private ImageLoader.ImageContainer container; private int fadeTime = 200; + private ValueAnimator fadeAnimation; + private boolean hidden = false; private boolean circular = false; private int rounding = 0; @@ -62,7 +67,8 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { private Matrix matrix = new Matrix(); BitmapShader bitmapShader; - private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); private boolean foregroundCalculate = false; private Drawable foreground; @@ -90,6 +96,14 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { private void init() { textPaint.setColor(0xff000000); textPaint.setTextSize(sp(14)); + backgroundPaint.setColor(0x22000000); + endAnimations(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + endAnimations(); } public void setUrl(String url, int width, int height) { @@ -117,6 +131,10 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { this.rounding = rounding; } + public int getRounding() { + return rounding; + } + @SuppressWarnings({"deprecation", "ConstantConditions"}) @Override public void setClickable(boolean clickable) { @@ -153,6 +171,30 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { return bitmap; } + public void hide(boolean animateIfNeeded) { + hidden = true; + if (getAlpha() == 0f) return; + + if (animateIfNeeded && fadeAnimation == null && bitmap != null && !calculate) { + animate().alpha(0f).setDuration(150); + } else { + setAlpha(0f); + } + endAnimations(); + } + + public void show(boolean animateIfNeeded) { + hidden = false; + if (getAlpha() == 1f) return; + + if (animateIfNeeded && fadeAnimation == null && bitmap != null && !calculate) { + animate().alpha(1f).setDuration(150); + } else { + setAlpha(1f); + } + endAnimations(); + } + @Override public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { if (response.getBitmap() != null) { @@ -180,7 +222,7 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { if (error) { textPaint.setAlpha(alpha); } else { - paint.setAlpha(alpha); + bitmapPaint.setAlpha(alpha); } invalidate(); @@ -196,14 +238,11 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { @Override protected void onDraw(Canvas canvas) { - if (getAlpha() == 0f) { - return; - } - int width = getWidth() - getPaddingLeft() - getPaddingRight(); int height = getHeight() - getPaddingTop() - getPaddingBottom(); if (error) { + // Render a simple text if there was an error. canvas.save(); textPaint.getTextBounds(errorText, 0, errorText.length(), tmpTextRect); @@ -213,10 +252,23 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { canvas.restore(); } else { + outputRect.set(getPaddingLeft(), getPaddingTop(), + getWidth() - getPaddingRight(), getHeight() - getPaddingBottom()); + + // Gray background if thumbnail is not yet loaded. + if (bitmap == null || fadeAnimation != null) { + if (circular) { + canvas.drawRoundRect(outputRect, width / 2.0f, height / 2.0f, backgroundPaint); + } else { + canvas.drawRoundRect(outputRect, rounding, rounding, backgroundPaint); + } + } + if (bitmap == null) { return; } + // If needed, calculate positions. if (calculate) { calculate = false; bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); @@ -231,21 +283,20 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { drawRect.set(-offsetX, -offsetY, scaledX - offsetX, scaledY - offsetY); drawRect.offset(getPaddingLeft(), getPaddingTop()); - outputRect.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom()); - matrix.setRectToRect(bitmapRect, drawRect, Matrix.ScaleToFit.FILL); bitmapShader.setLocalMatrix(matrix); - paint.setShader(bitmapShader); + bitmapPaint.setShader(bitmapShader); } canvas.save(); canvas.clipRect(outputRect); + // Draw rounded bitmap. if (circular) { - canvas.drawRoundRect(outputRect, width / 2, height / 2, paint); + canvas.drawRoundRect(outputRect, width / 2.0f, height / 2.0f, bitmapPaint); } else { - canvas.drawRoundRect(outputRect, rounding, rounding, paint); + canvas.drawRoundRect(outputRect, rounding, rounding, bitmapPaint); } canvas.restore(); @@ -298,9 +349,8 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { private void onImageSet(boolean isImmediate) { clearAnimation(); - if (fadeTime > 0 && !isImmediate) { - setAlpha(0f); - animate().alpha(1f).setDuration(fadeTime); + if (fadeTime > 0 && !isImmediate && !hidden) { + runFadeInAnimation(); } else { setAlpha(1f); } @@ -308,13 +358,41 @@ public class ThumbnailView extends View implements ImageLoader.ImageListener { private void setImageBitmap(Bitmap bitmap) { bitmapShader = null; - paint.setShader(null); + bitmapPaint.setShader(null); this.bitmap = bitmap; if (bitmap != null) { calculate = true; bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); } + endAnimations(); invalidate(); } + + private void runFadeInAnimation() { + fadeAnimation = ValueAnimator.ofFloat(0.0f, 1.0f); + fadeAnimation.setDuration(fadeTime); + fadeAnimation.addUpdateListener(v -> { + bitmapPaint.setAlpha((int) (((float) v.getAnimatedValue()) * 255)); + invalidate(); + }); + fadeAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + fadeAnimation = null; + if (bitmapPaint.getAlpha() != ((int) getAlpha() * 255)) { + bitmapPaint.setAlpha((int) (getAlpha() * 255)); + invalidate(); + } + } + }); + fadeAnimation.start(); + } + + private void endAnimations() { + if (fadeAnimation != null) { + fadeAnimation.end(); + fadeAnimation = null; + } + } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/TransitionImageView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/TransitionImageView.java index 090a7bf0..450ef709 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/TransitionImageView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/TransitionImageView.java @@ -22,12 +22,15 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; +import static org.floens.chan.utils.AndroidUtils.enableHighEndAnimations; + public class TransitionImageView extends View { private static final String TAG = "TransitionImageView"; @@ -44,6 +47,8 @@ public class TransitionImageView extends View { private float stateBitmapScaleDiff; private PointF stateBitmapSize; private PointF statePos; + private float fromRounding = 0.0f; + private Path roundingPath = new Path(); public TransitionImageView(Context context) { super(context); @@ -84,8 +89,10 @@ public class TransitionImageView extends View { matrix.setRectToRect(bitmapRect, destRect, Matrix.ScaleToFit.FILL); } - public void setSourceImageView(Point windowLocation, Point viewSize, Bitmap bitmap) { + public void setSourceImageView(Point windowLocation, Point viewSize, Bitmap bitmap, + float rounding) { this.bitmap = bitmap; + this.fromRounding = rounding; bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); if (stateBitmapSize != null) { @@ -174,9 +181,17 @@ public class TransitionImageView extends View { if (bitmap != null) { canvas.save(); if (progress < 1f) { - canvas.clipRect(destClip); + if (!enableHighEndAnimations()) { + canvas.clipRect(destClip); + } else { + float rounding = lerp(fromRounding, 0.0f, progress); + roundingPath.reset(); + roundingPath.addRoundRect(destClip, rounding, rounding, Path.Direction.CW); + canvas.clipPath(roundingPath); + } } canvas.drawBitmap(bitmap, matrix, paint); + canvas.restore(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java index b408942d..cc8aa1f3 100644 --- a/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java +++ b/Clover/app/src/main/java/org/floens/chan/utils/AndroidUtils.java @@ -20,6 +20,7 @@ package org.floens.chan.utils; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; +import android.app.ActivityManager; import android.app.Application; import android.app.Dialog; import android.content.ActivityNotFoundException; @@ -43,6 +44,7 @@ import android.os.Looper; import android.preference.PreferenceManager; import android.support.customtabs.CustomTabsIntent; import android.support.design.widget.Snackbar; +import android.support.v4.app.ActivityManagerCompat; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -71,6 +73,7 @@ public class AndroidUtils { @SuppressLint("StaticFieldLeak") private static Application application; private static ConnectivityManager connectivityManager; + private static ActivityManager activityManager; private static final Handler mainHandler = new Handler(Looper.getMainLooper()); @@ -84,6 +87,8 @@ public class AndroidUtils { connectivityManager = (ConnectivityManager) application.getSystemService(Context.CONNECTIVITY_SERVICE); + activityManager = (ActivityManager) + application.getSystemService(Context.ACTIVITY_SERVICE); } } @@ -452,4 +457,9 @@ public class AndroidUtils { NetworkInfo networkInfo = connectivityManager.getNetworkInfo(type); return networkInfo != null && networkInfo.isConnected(); } + + public static boolean enableHighEndAnimations() { + boolean lowRamDevice = ActivityManagerCompat.isLowRamDevice(activityManager); + return !lowRamDevice && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; + } } diff --git a/Clover/app/src/main/res/drawable-hdpi/dialog_full_dark.9.png b/Clover/app/src/main/res/drawable-hdpi/dialog_full_dark.9.png deleted file mode 100644 index 911f3fee..00000000 Binary files a/Clover/app/src/main/res/drawable-hdpi/dialog_full_dark.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-hdpi/dialog_full_light.9.png b/Clover/app/src/main/res/drawable-hdpi/dialog_full_light.9.png deleted file mode 100644 index 2129567f..00000000 Binary files a/Clover/app/src/main/res/drawable-hdpi/dialog_full_light.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-mdpi/dialog_full_dark.9.png b/Clover/app/src/main/res/drawable-mdpi/dialog_full_dark.9.png deleted file mode 100644 index dc373160..00000000 Binary files a/Clover/app/src/main/res/drawable-mdpi/dialog_full_dark.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-mdpi/dialog_full_light.9.png b/Clover/app/src/main/res/drawable-mdpi/dialog_full_light.9.png deleted file mode 100644 index 0c5770a3..00000000 Binary files a/Clover/app/src/main/res/drawable-mdpi/dialog_full_light.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-xhdpi/dialog_full_dark.9.png b/Clover/app/src/main/res/drawable-xhdpi/dialog_full_dark.9.png deleted file mode 100644 index 75d36be3..00000000 Binary files a/Clover/app/src/main/res/drawable-xhdpi/dialog_full_dark.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-xhdpi/dialog_full_light.9.png b/Clover/app/src/main/res/drawable-xhdpi/dialog_full_light.9.png deleted file mode 100644 index d9bd3375..00000000 Binary files a/Clover/app/src/main/res/drawable-xhdpi/dialog_full_light.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-xxhdpi/dialog_full_dark.9.png b/Clover/app/src/main/res/drawable-xxhdpi/dialog_full_dark.9.png deleted file mode 100644 index b029809d..00000000 Binary files a/Clover/app/src/main/res/drawable-xxhdpi/dialog_full_dark.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable-xxhdpi/dialog_full_light.9.png b/Clover/app/src/main/res/drawable-xxhdpi/dialog_full_light.9.png deleted file mode 100644 index 63dd1927..00000000 Binary files a/Clover/app/src/main/res/drawable-xxhdpi/dialog_full_light.9.png and /dev/null differ diff --git a/Clover/app/src/main/res/drawable/album_cell_info_background.xml b/Clover/app/src/main/res/drawable/album_cell_info_background.xml new file mode 100644 index 00000000..fc8ec281 --- /dev/null +++ b/Clover/app/src/main/res/drawable/album_cell_info_background.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/Clover/app/src/main/res/drawable/dialog_full_light.xml b/Clover/app/src/main/res/drawable/dialog_full_light.xml new file mode 100644 index 00000000..2c038d31 --- /dev/null +++ b/Clover/app/src/main/res/drawable/dialog_full_light.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/Clover/app/src/main/res/layout/cell_album_view.xml b/Clover/app/src/main/res/layout/cell_album_view.xml index 7f8d8e32..6272cd39 100644 --- a/Clover/app/src/main/res/layout/cell_album_view.xml +++ b/Clover/app/src/main/res/layout/cell_album_view.xml @@ -31,7 +31,7 @@ along with this program. If not, see . android:layout_width="match_parent" android:layout_height="32dp" android:layout_gravity="bottom" - android:background="#8a000000" + android:background="@drawable/album_cell_info_background" android:gravity="center_vertical" android:maxLines="2" android:paddingLeft="8dp" diff --git a/Clover/app/src/main/res/layout/layout_post_replies.xml b/Clover/app/src/main/res/layout/layout_post_replies.xml index c68cde92..c59414bc 100644 --- a/Clover/app/src/main/res/layout/layout_post_replies.xml +++ b/Clover/app/src/main/res/layout/layout_post_replies.xml @@ -26,10 +26,12 @@ along with this program. If not, see . android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:layout_margin="10dp" android:background="@drawable/dialog_full_light" + android:elevation="8dp" android:minWidth="320dp" android:orientation="vertical" - tools:ignore="UselessParent"> + tools:ignore="UnusedAttribute,UselessParent">