From d23d7a455cd81c7b762705a6c9e6ef4b4f057c79 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Thu, 9 Jun 2022 19:29:26 +0200 Subject: [PATCH] Open album in full screen --- app/build.gradle | 2 + .../java/org/pixeldroid/app/HomeFeedTest.kt | 14 +- app/src/main/AndroidManifest.xml | 6 +- .../org/pixeldroid/app/posts/AlbumActivity.kt | 38 ++++ .../app/posts/MediaViewerActivity.kt | 11 +- .../app/posts/NestedScrollableHost.kt | 32 ++- .../pixeldroid/app/posts/StatusViewHolder.kt | 129 +++++++++--- .../pixeldroid/app/posts/TouchImageView.kt | 196 ------------------ app/src/main/res/layout/activity_album.xml | 25 +++ app/src/main/res/layout/opened_album.xml | 26 +++ app/src/main/res/values/styles.xml | 13 ++ 11 files changed, 235 insertions(+), 257 deletions(-) create mode 100644 app/src/main/java/org/pixeldroid/app/posts/AlbumActivity.kt delete mode 100644 app/src/main/java/org/pixeldroid/app/posts/TouchImageView.kt create mode 100644 app/src/main/res/layout/activity_album.xml create mode 100644 app/src/main/res/layout/opened_album.xml diff --git a/app/build.gradle b/app/build.gradle index b10aca63..d54e1eaf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -142,6 +142,8 @@ dependencies { // CameraX View class implementation "androidx.camera:camera-view:$cameraX_version" + implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0' + def room_version = "2.4.2" implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" diff --git a/app/src/androidTest/java/org/pixeldroid/app/HomeFeedTest.kt b/app/src/androidTest/java/org/pixeldroid/app/HomeFeedTest.kt index 84c9e735..8d6cefb1 100644 --- a/app/src/androidTest/java/org/pixeldroid/app/HomeFeedTest.kt +++ b/app/src/androidTest/java/org/pixeldroid/app/HomeFeedTest.kt @@ -6,7 +6,6 @@ import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions -import androidx.test.espresso.action.ViewActions.openLinkWithText import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition @@ -24,9 +23,6 @@ import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TestRule -import org.junit.rules.Timeout -import org.junit.runner.Description import org.junit.runner.RunWith import org.junit.runners.model.Statement @@ -68,22 +64,22 @@ class HomeFeedTest { @RepeatTest fun clickingTabOnAlbumShowsNextPhoto() { //Wait for the feed to load - waitForView(R.id.postPager) + waitForView(R.id.albumPager) activityScenario.onActivity { a -> run { //Pick the second photo - a.findViewById(R.id.postPager).currentItem = 2 + a.findViewById(R.id.albumPager).currentItem = 2 } } - onView(first(withId(R.id.postPager))).check(matches(isDisplayed())) + onView(first(withId(R.id.albumPager))).check(matches(isDisplayed())) } @Test @RepeatTest fun tabReClickScrollUp() { //Wait for the feed to load - waitForView(R.id.postPager) + waitForView(R.id.albumPager) onView(withId(R.id.list)).perform(scrollToPosition(4)) @@ -97,7 +93,7 @@ class HomeFeedTest { @RepeatTest fun hashtag() { //Wait for the feed to load - waitForView(R.id.postPager) + waitForView(R.id.albumPager) onView(allOf(withClassName(endsWith("RecyclerView")), not(withId(R.id.material_drawer_recycler_view)))) .perform( diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cfcdb8c7..4a3bdf48 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,9 +23,13 @@ android:theme="@style/AppTheme" tools:replace="android:allowBackup"> + + binding.albumPager.adapter = AlbumViewPagerAdapter(mediaAttachments, + sensitive = false, + opened = true) + + if(mediaAttachments.size == 1){ + binding.albumPager.isUserInputEnabled = false + } + else if((mediaAttachments.size) > 1) { + binding.postIndicator.setViewPager(binding.albumPager) + binding.postIndicator.visibility = View.VISIBLE + } else { + binding.postIndicator.visibility = View.GONE + } + + + + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowTitleEnabled(false) + supportActionBar?.setBackgroundDrawable(null) + window.statusBarColor = ContextCompat.getColor(this,android.R.color.transparent); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt b/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt index 39c91472..aa414d57 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt @@ -7,6 +7,7 @@ import android.media.AudioManager.STREAM_MUSIC import android.os.Bundle import androidx.core.net.toUri import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat.getInsetsController import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.media.AudioAttributesCompat @@ -50,19 +51,19 @@ class MediaViewerActivity : BaseActivity() { mediaPlayer.setMediaItem(mediaItem) binding.videoView.mediaControlView?.setOnFullScreenListener{ view, fullscreen -> - val windowInsetsController = ViewCompat.getWindowInsetsController(window.decorView) + val windowInsetsController = getInsetsController(window, window.decorView) if (!fullscreen) { // Configure the behavior of the hidden system bars - windowInsetsController?.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE // Hide both the status bar and the navigation bar - windowInsetsController?.show(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) supportActionBar?.show() requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED } else { // Configure the behavior of the hidden system bars - windowInsetsController?.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE // Hide both the status bar and the navigation bar - windowInsetsController?.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) requestedOrientation = if (mediaPlayer.videoSize.height < mediaPlayer.videoSize.width) { diff --git a/app/src/main/java/org/pixeldroid/app/posts/NestedScrollableHost.kt b/app/src/main/java/org/pixeldroid/app/posts/NestedScrollableHost.kt index fb2e84e4..e048244d 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/NestedScrollableHost.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/NestedScrollableHost.kt @@ -1,32 +1,17 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.pixeldroid.app.posts import android.content.Context +import android.content.Intent import android.util.AttributeSet import android.view.GestureDetector import android.view.MotionEvent import android.view.View import android.view.ViewConfiguration -import android.widget.Toast import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.GestureDetectorCompat import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL +import org.pixeldroid.app.utils.api.objects.Attachment import kotlin.math.absoluteValue import kotlin.math.sign @@ -53,6 +38,7 @@ class NestedScrollableHost(context: Context, attrs: AttributeSet? = null) : } + var images: ArrayList = ArrayList(); var doubleTapCallback: (() -> Unit)? = null private val child: View? get() = if (childCount > 0) getChildAt(0) else null @@ -96,8 +82,16 @@ class NestedScrollableHost(context: Context, attrs: AttributeSet? = null) : } override fun onSingleTapConfirmed(e: MotionEvent?): Boolean { - //TODO open image full screen - Toast.makeText(this@NestedScrollableHost.context, "yay you did it", Toast.LENGTH_SHORT).show() + // Disable opening AlbumActivity if the only image is a video (let the video open directly) + if(images.size == 1 && images.first().type == Attachment.AttachmentType.video){ + return super.onSingleTapConfirmed(e) + } + val intent = Intent(context, AlbumActivity::class.java) + + intent.putExtra("images", images) + + context.startActivity(intent) + return super.onSingleTapConfirmed(e) } override fun onScroll( diff --git a/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt b/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt index 72b18cb3..4b51009a 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt @@ -1,11 +1,13 @@ package org.pixeldroid.app.posts import android.Manifest +import android.app.Activity import android.app.AlertDialog import android.content.Intent import android.graphics.Typeface import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.Drawable +import android.net.Uri import android.text.method.LinkMovementMethod import android.util.Log import android.view.LayoutInflater @@ -13,15 +15,29 @@ import android.view.View import android.view.ViewGroup import android.widget.* import androidx.core.content.ContextCompat +import androidx.core.view.WindowCompat import androidx.lifecycle.LifecycleCoroutineScope import androidx.recyclerview.widget.RecyclerView import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat +import androidx.viewbinding.ViewBinding import com.bumptech.glide.Glide import com.bumptech.glide.RequestBuilder +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.request.target.CustomViewTarget +import com.bumptech.glide.request.transition.Transition +import com.davemorrissey.labs.subscaleview.ImageSource +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.google.android.material.snackbar.Snackbar +import com.karumi.dexter.Dexter +import com.karumi.dexter.listener.PermissionDeniedResponse +import com.karumi.dexter.listener.PermissionGrantedResponse +import com.karumi.dexter.listener.single.BasePermissionListener +import kotlinx.coroutines.launch import org.pixeldroid.app.R import org.pixeldroid.app.databinding.AlbumImageViewBinding +import org.pixeldroid.app.databinding.OpenedAlbumBinding import org.pixeldroid.app.databinding.PostFragmentBinding +import org.pixeldroid.app.posts.MediaViewerActivity.Companion.openActivity import org.pixeldroid.app.utils.BlurHashDecoder import org.pixeldroid.app.utils.ImageConverter import org.pixeldroid.app.utils.api.PixelfedAPI @@ -32,15 +48,8 @@ import org.pixeldroid.app.utils.api.objects.Status.Companion.POST_TAG import org.pixeldroid.app.utils.api.objects.Status.Companion.VIEW_COMMENTS_TAG import org.pixeldroid.app.utils.db.AppDatabase import org.pixeldroid.app.utils.di.PixelfedAPIHolder -import com.karumi.dexter.Dexter -import com.karumi.dexter.listener.PermissionDeniedResponse -import com.karumi.dexter.listener.PermissionGrantedResponse -import com.karumi.dexter.listener.single.BasePermissionListener -import kotlinx.coroutines.launch -import org.pixeldroid.app.posts.MediaViewerActivity.Companion.VIDEO_DESCRIPTION_TAG -import org.pixeldroid.app.posts.MediaViewerActivity.Companion.VIDEO_URL_TAG -import org.pixeldroid.app.posts.MediaViewerActivity.Companion.openActivity import retrofit2.HttpException +import java.io.File import java.io.IOException import kotlin.math.roundToInt @@ -88,7 +97,7 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold private fun setupPost( request: RequestBuilder, domain: String, - isActivity: Boolean + isActivity: Boolean, ) { //Setup username as a button that opens the profile binding.username.apply { @@ -148,9 +157,9 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold binding.postPager.visibility = View.VISIBLE //Attach the given tabs to the view pager - binding.postPager.adapter = AlbumViewPagerAdapter(status?.media_attachments ?: emptyList(), status?.sensitive) + binding.postPager.adapter = AlbumViewPagerAdapter(status?.media_attachments ?: emptyList(), status?.sensitive, false) - if(status?.media_attachments?.size ?: 0 > 1) { + if((status?.media_attachments?.size ?: 0) > 1) { binding.postIndicator.setViewPager(binding.postPager) binding.postIndicator.visibility = View.VISIBLE } else { @@ -206,7 +215,7 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold apiHolder: PixelfedAPIHolder, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope, - isActivity: Boolean + isActivity: Boolean, ){ //Set the special HTML text setDescription(apiHolder, lifecycleScope) @@ -459,7 +468,7 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold } } - //Activate double tap liking + //Activate tap interactions (double and single) binding.postPagerHost.doubleTapCallback = { lifecycleScope.launchWhenCreated { //Check that the post isn't hidden @@ -479,6 +488,8 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold } } } + status?.media_attachments?.let { binding.postPagerHost.images = ArrayList(it) } + } private fun ImageView.animateView() { visibility = View.VISIBLE @@ -534,8 +545,8 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold //endregion private fun showComments( - lifecycleScope: LifecycleCoroutineScope, - isActivity: Boolean + lifecycleScope: LifecycleCoroutineScope, + isActivity: Boolean, ) { //Show number of comments on the post if (status?.replies_count == 0) { @@ -574,14 +585,20 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold } } -private class AlbumViewPagerAdapter(private val media_attachments: List, private var sensitive: Boolean?) : +class AlbumViewPagerAdapter( + private val media_attachments: List, private var sensitive: Boolean?, + private val opened: Boolean, //TODO if opened don't open again, and use PhotoView instead of shite +) : RecyclerView.Adapter() { + private var isActionBarHidden: Boolean = false + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val itemBinding = AlbumImageViewBinding.inflate( + return if(!opened) ViewHolderClosed(AlbumImageViewBinding.inflate( LayoutInflater.from(parent.context), parent, false - ) - return ViewHolder(itemBinding) + )) else ViewHolderOpen(OpenedAlbumBinding.inflate( + LayoutInflater.from(parent.context), parent, false + )) } override fun getItemCount() = media_attachments.size @@ -598,19 +615,69 @@ private class AlbumViewPagerAdapter(private val media_attachments: List((holder.image as SubsamplingScaleImageView)) { + override fun onResourceReady(resource: File, t: Transition?) = + view.setImage(ImageSource.uri(Uri.fromFile(resource))) + override fun onLoadFailed(errorDrawable: Drawable?) {} + override fun onResourceCleared(placeholder: Drawable?) {} + }) + (holder.image as SubsamplingScaleImageView).apply { + setMinimumDpi(80) + setDoubleTapZoomDpi(240) + resetScaleAndCenter() + } + holder.image.setOnClickListener { + val windowInsetsController = WindowCompat.getInsetsController((it.context as Activity).window, it) + // Configure the behavior of the hidden system bars + + if (isActionBarHidden) { + (it.context as Activity).window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) + isActionBarHidden = false + } else { + (it.context as Activity).window.getDecorView().setSystemUiVisibility( + (View.SYSTEM_UI_FLAG_LAYOUT_STABLE + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_FULLSCREEN + or View.SYSTEM_UI_FLAG_IMMERSIVE)) + isActionBarHidden = true + } + /*if (isActionBarHidden) { + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + // Hide both the status bar and the navigation bar + (it.context as AppCompatActivity).supportActionBar?.show() + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) + isActionBarHidden = false + } else { + // Configure the behavior of the hidden system bars + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + // Hide both the status bar and the navigation bar + (it.context as AppCompatActivity).supportActionBar?.hide() + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + isActionBarHidden = true + }*/ + } + } + else Glide.with(holder.binding.root) .asDrawable().fitCenter() .placeholder(blurhashBitMap) - .load(imageUrl).into(holder.image) - } else { + .load(imageUrl).into(holder.image as ImageView) + } else if(!opened){ Glide.with(holder.binding.root) .asDrawable().fitCenter() - .load(blurhashBitMap).into(holder.image) + .load(blurhashBitMap).into(holder.image as ImageView) } holder.videoPlayButton.visibility = if(video) View.VISIBLE else View.GONE - if(video){ + if(video && (opened || media_attachments.size == 1)){ holder.videoPlayButton.setOnClickListener { openActivity(holder.binding.root.context, url, description) } @@ -636,9 +703,17 @@ private class AlbumViewPagerAdapter(private val media_attachments: List - mScaleDetector!!.onTouchEvent(event) - val curr = PointF(event.x, event.y) - when (event.action) { - MotionEvent.ACTION_MOVE -> if (mode == DRAG) { - val deltaX = curr.x - last.x - val deltaY = curr.y - last.y - val fixTransX = - getFixDragTrans(deltaX, viewWidth.toFloat(), origWidth * saveScale) - val fixTransY = - getFixDragTrans(deltaY, viewHeight.toFloat(), origHeight * saveScale) - touchMatrix!!.postTranslate(fixTransX, fixTransY) - fixTrans() - last[curr.x] = curr.y - val transX = m[Matrix.MTRANS_X] - if ((getFixTrans(transX, - viewWidth.toFloat(), - origWidth * saveScale) + fixTransX).toInt() == 0 - ) startInterceptEvent() else stopInterceptEvent() - } - MotionEvent.ACTION_DOWN -> { - last.set(curr) - start.set(last) - mode = DRAG - stopInterceptEvent() - } - MotionEvent.ACTION_UP -> { - mode = NONE - val xDiff = abs(curr.x - start.x).toInt() - val yDiff = abs(curr.y - start.y).toInt() - if (xDiff < CLICK && yDiff < CLICK) performClick() - startInterceptEvent() - } - MotionEvent.ACTION_POINTER_UP -> mode = NONE - } - imageMatrix = touchMatrix - invalidate() - true // indicate event was handled - } - } - - private fun startInterceptEvent() { - parent.requestDisallowInterceptTouchEvent(false) - } - - private fun stopInterceptEvent() { - parent.requestDisallowInterceptTouchEvent(true) - } - - fun setMaxZoom(x: Float) { - maxScale = x - } - - private inner class ScaleListener : SimpleOnScaleGestureListener() { - override fun onScaleBegin(detector: ScaleGestureDetector): Boolean { - mode = ZOOM - return true - } - - override fun onScale(detector: ScaleGestureDetector): Boolean { - var mScaleFactor = detector.scaleFactor - val origScale = saveScale - saveScale *= mScaleFactor - if (saveScale > maxScale) { - saveScale = maxScale - mScaleFactor = maxScale / origScale - } else if (saveScale < minScale) { - saveScale = minScale - mScaleFactor = minScale / origScale - } - if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight) touchMatrix!!.postScale( - mScaleFactor, - mScaleFactor, - (viewWidth / 2).toFloat(), - (viewHeight / 2).toFloat()) else touchMatrix!!.postScale(mScaleFactor, - mScaleFactor, - detector.focusX, - detector.focusY) - fixTrans() - return true - } - } - - fun fixTrans() { - touchMatrix!!.getValues(m) - val transX = m[Matrix.MTRANS_X] - val transY = m[Matrix.MTRANS_Y] - val fixTransX = getFixTrans(transX, viewWidth.toFloat(), origWidth * saveScale) - val fixTransY = getFixTrans(transY, viewHeight.toFloat(), origHeight * saveScale) - if (fixTransX != 0f || fixTransY != 0f) touchMatrix!!.postTranslate(fixTransX, fixTransY) - } - - fun getFixTrans(trans: Float, viewSize: Float, contentSize: Float): Float { - val minTrans: Float - val maxTrans: Float - if (contentSize <= viewSize) { - minTrans = 0f - maxTrans = viewSize - contentSize - } else { - minTrans = viewSize - contentSize - maxTrans = 0f - } - if (trans < minTrans) return -trans + minTrans - return if (trans > maxTrans) -trans + maxTrans else 0f - } - - fun getFixDragTrans(delta: Float, viewSize: Float, contentSize: Float): Float { - return if (contentSize <= viewSize) { - 0f - } else delta - } - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec) - viewWidth = MeasureSpec.getSize(widthMeasureSpec) - viewHeight = MeasureSpec.getSize(heightMeasureSpec) - - // Rescales image on rotation - if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight || viewWidth == 0 || viewHeight == 0) return - oldMeasuredHeight = viewHeight - oldMeasuredWidth = viewWidth - if (saveScale == 1f) { - //Fit to screen. - val scale: Float - val drawable = drawable - if (drawable == null || drawable.intrinsicWidth == 0 || drawable.intrinsicHeight == 0) return - val bmWidth = drawable.intrinsicWidth - val bmHeight = drawable.intrinsicHeight - Log.d("bmSize", "bmWidth: $bmWidth bmHeight : $bmHeight") - val scaleX = viewWidth.toFloat() / bmWidth.toFloat() - val scaleY = viewHeight.toFloat() / bmHeight.toFloat() - scale = min(scaleX, scaleY) - touchMatrix!!.setScale(scale, scale) - - // Center the image - var redundantYSpace = viewHeight.toFloat() - scale * bmHeight.toFloat() - var redundantXSpace = viewWidth.toFloat() - scale * bmWidth.toFloat() - redundantYSpace /= 2f - redundantXSpace /= 2f - touchMatrix!!.postTranslate(redundantXSpace, redundantYSpace) - origWidth = viewWidth - 2 * redundantXSpace - origHeight = viewHeight - 2 * redundantYSpace - imageMatrix = touchMatrix - } - fixTrans() - } - - companion object { - // We can be in one of these 3 states - const val NONE = 0 - const val DRAG = 1 - const val ZOOM = 2 - const val CLICK = 3 - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml new file mode 100644 index 00000000..31728921 --- /dev/null +++ b/app/src/main/res/layout/activity_album.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/opened_album.xml b/app/src/main/res/layout/opened_album.xml new file mode 100644 index 00000000..5f2dcc9f --- /dev/null +++ b/app/src/main/res/layout/opened_album.xml @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2b32ba41..20fc5dc0 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -21,6 +21,19 @@ @android:style/TextAppearance.Large + +