XuanImageView extends ImageView with scaling function, rotating function, ect. Particularly, its auto-rotate-back-to-initial-state behavior mimics that in Google Photo.
Demo app is available on Googl Play :
Or you can get demo apk under /demo/demo-release.apk.
XuanImageView is now compatible with Glide, Picasso and other image loading libraries that use ImageView as image container.
Fresco's DraweeView is a descendant of Android View class, if you want extended functionality
like scaling and rotating on it, I suggest that you search for other libraries compatible with Fresco.
- An image will be scaled and centered to fit the screen size at the very beginning (initial state).
- Double-tap triggers auto-scale behavior.
- If image's current scale level is bigger than maximum scale level or smaller than minimum scale level, the image will spring back to maximum scale level or minimum scale level.
- The Image can only start to be rotated when it's in initial state.
- Image will rotate back to initial state when rotation gesture is released.
This library is available on JCenter, so you need add this to your project's build.gradle (usually it is already there by default).
allprojects {
repositories {
jcenter()
}
}
and add this to your module's build.gradle.
dependencies {
compile 'com.github.allenxuan:xuanimageview:0.5.0'
}
In xml, .e.g.,
<com.allenxuan.xuanyihuang.xuanimageview.XuanImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/wallpaper1" />
In code, e.g.,
XuanImageView xuanImageView = new XuanImageView(context);
xuanImageView.setImageResource(resId);
Set a boolean value to determine whether rotation function is turned on.
Set AutoRotateCategory, there are two alternative values of it : XuanImageViewSettings.AUTO_ROTATE_CATEGORY_RESTORATION, XuanImageViewSettings.AUTO_ROTATE_CATEGORY_MAGNETISM.
An image is scaled to an InitScale to fit the size of XuanImageView at the very beginning. MaxScale = MaxScaleMultiple * InitScale holds.
DoubleTapScale = DoubleTabScaleMultiple * InitScale holds. when image's current scale level is smaller than DoubleTabScale, the image will scale up to DoubleTapScale if a double-tap gesture is detected.
If current scale level is smaller than InitScale and image is not in rotation state, the image will scale up to InitScale with SpringBackGradientScaleUpLevel step by step. Default springBackGradientScaleUpLevel is 1.01f.
If current scale level is bigger than MaxScale and image is not in rotation state, the image will scale down to MaxScale with SpringBackGradientScaleDownLevel step by step. Default springBackGradientScaleDownLevel is 0.99f.
When image's current scale level is smaller than DoubleTabScale, the image will scale up to DoubleTapScale with DoubleTapGradientScaleUpLevel step by step if a double-tap gesture is detected. Default doubleTalGradientScaleUpLevel is 1.05f.
When image's current scale level is bigger than DoubleTabScale, the image will scale down to InitScale with DoubleTapGradientScaleDownLevel step by step if a double-tap gesture is detected. Default doubleTabGradientScaleDownLevel is 0.95f.
When image's current rotation angle is bigger than AutoRotationTrigger, the image will rotate in the same direction and scale back to it's initial state if rotation gesture is released. When image's current rotation angle is smaller than AutoRotationTrigger, the image will rotate in the opposite direction and scale back to it's initial state if rotation gesture is released. Default AutoRotationTrigger is 60 (degrees).
Default SpringBackRunnableDelay is 10 (milliseconds).
Default DoubleTapScaleRunnableDelay is 10 (milliseconds).
Default AutoRotationRunnableDelay is 5 (milliseconds).
Default AutoRotationRunnableTimes is 10 (times).
Notice the Image can only start to be rotated when it's in initial state. But the image may be scaled up or down a little bit by ScaleGestureDetector in advance when you try to rotate it, hence, currentScaleLevel is not precisely equal to initScaleLevel. Here, an AllowableFloatError is existed to handle this situation. When Math.abs(currentScaleLevel - initScaleLevel) < allowableFloatError, RotateGestureDetector.onTouchEvent() can be invoked. Default allowableFloatError is 1E-6, it should be compatible with most of devices. For devices whose display resolution and aspect ratio is not normal, allowableFloatError may need to be tuned. eg., for Galaxy S8, 3E-3 works well. Of course, 3E-3 also works for most of devices because 1E-6 < 3E-3.
In AUTO_ROTATE_CATEGORY_MAGNETISM mode, the image may be showed under a fixed rotation angle like 90 degrees, 270 degrees,450 degrees, ect., then allowablePortraitFloatError should handle the situation when currentPortraitScaleLevel is not precisely equal to initPortraitScaleLevel. Default allowablePortraitFloatError is 1E-12, it should be compatible with most of devices. For devices whose display resolution and aspect ratio is not normal, allowablePortraitFloatError may need to be tuned. eg., for Galaxy S8, 5E-8 works well. Of course, 5E-8 also works for most of devices because 1E-12 < 5E-8.
<com.allenxuan.xuanyihuang.xuanimageview.XuanImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/wallpaper1"
android:scaleType="matrix"
android:background="@android:color/background_dark"
app:RotationToggle="boolean value"
app:AutoRotateCategory="int value (1 for AUTO_ROTATE_CATEGORY_RESTORATION, 2 for AUTO_ROTATE_CATEGORY_MAGNETISM)"
app:MaxScaleMultiple="float value"
app:DoubleTabScaleMultiple="float value"
app:SpringBackGradientScaleUpLevel="float value"
app:SpringBackGradientScaleDownLevel="float value"
app:DoubleTapGradientScaleUpLevel="float value"
app:DoubleTapGradientScaleDownLevel="float value"
app:AutoRotationTrigger="float value"
app:SpringBackRunnableDelay="int value"
app:DoubleTapScaleRunnableDelay="int value"
app:AutoRotationRunnableDelay="int value"
app:AutoRotationRunnableTimes="int value"
app:AllowableFloatError="double value"
app:AllowablePortraitFloatError="double value"
/>
return current RotationToggle.
return current AutoRotateCategory.
Return current MaxScaleMultiple.
Return current DoubleTabScaleMultiple.
Return current SpringBackGradientScaleUpLevel.
Return current SpringBackGradientScaleDownLevel.
Return current DoubleTapGradientScaleUpLevel.
Return current DoubleTapGradientScaleDownLevel.
Return current AutoRotationTrigger.
Return springBackRunnableDelay;
Return doubleTabScaleRunnableDelay.
return current AutoRotationRunnableDelay.
Return current AutoRotationRunnableTimes.
Return allowableFloatError.
Return allowablePortraitFloatError
Copyright 2017 Xuanyi Huang
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.