Work on demo app
This commit is contained in:
parent
d8d9945daf
commit
a307f35346
|
@ -18,7 +18,7 @@
|
|||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/content/ic_add_black_24dp.xml" />
|
||||
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/navigation/ic_menu_black_24dp.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
@ -29,8 +29,8 @@
|
|||
<option name="values">
|
||||
<map>
|
||||
<entry key="color" value="ffffff" />
|
||||
<entry key="outputName" value="ic_add_white_24dp" />
|
||||
<entry key="sourceFile" value="C:\Users\oupso" />
|
||||
<entry key="outputName" value="ic_menu_white_24dp" />
|
||||
<entry key="sourceFile" value="C:\Users\oupso\Downloads\java-seeklogo.com.svg" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
|
|
Binary file not shown.
|
@ -128,8 +128,9 @@ class APNGDisassembler {
|
|||
val crc = CRC32()
|
||||
crc.update(byteArray.copyOfRange(i, byteArray.size - 4))
|
||||
if (chunkCRC == crc.value.toInt()) {
|
||||
when (byteArray.copyOfRange(i, i + 4).contentToString()) {
|
||||
Utils.fcTL -> {
|
||||
val name= byteArray.copyOfRange(i, i + 4)
|
||||
when {
|
||||
name.contentEquals(Utils.fcTL) -> {
|
||||
if (png == null) {
|
||||
cover?.let {
|
||||
it.addAll(to4Bytes(0).asList())
|
||||
|
@ -198,7 +199,7 @@ class APNGDisassembler {
|
|||
}
|
||||
}
|
||||
}
|
||||
Utils.IEND -> {
|
||||
name.contentEquals(Utils.IEND) -> {
|
||||
if (isApng) {
|
||||
png?.addAll(to4Bytes(0).asList())
|
||||
// Add IEND
|
||||
|
@ -235,7 +236,7 @@ class APNGDisassembler {
|
|||
apng.isApng = false
|
||||
}
|
||||
}
|
||||
Utils.IDAT -> {
|
||||
name.contentEquals(Utils.IDAT) -> {
|
||||
if (png == null) {
|
||||
if (cover == null) {
|
||||
cover = ArrayList()
|
||||
|
@ -267,7 +268,7 @@ class APNGDisassembler {
|
|||
png?.addAll(to4Bytes(crC32.value.toInt()).asList())
|
||||
}
|
||||
}
|
||||
Utils.fdAT -> {
|
||||
name.contentEquals(Utils.fdAT) -> {
|
||||
// Find the chunk length
|
||||
val bodySize = parseLength(byteArray.copyOfRange(i - 4, i))
|
||||
png?.addAll(to4Bytes(bodySize - 4).asList())
|
||||
|
@ -280,18 +281,18 @@ class APNGDisassembler {
|
|||
png?.addAll(body)
|
||||
png?.addAll(to4Bytes(crC32.value.toInt()).asList())
|
||||
}
|
||||
Utils.plte -> {
|
||||
name.contentEquals(Utils.plte) -> {
|
||||
plte = byteArray
|
||||
}
|
||||
Utils.tnrs -> {
|
||||
name.contentEquals(Utils.tnrs) -> {
|
||||
tnrs = byteArray
|
||||
}
|
||||
Utils.IHDR -> {
|
||||
name.contentEquals(Utils.IHDR) -> {
|
||||
ihdr.parse(byteArray)
|
||||
maxWidth = ihdr.pngWidth
|
||||
maxHeight = ihdr.pngHeight
|
||||
}
|
||||
Utils.acTL -> {
|
||||
name.contentEquals(Utils.acTL) -> {
|
||||
isApng = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class ExperimentalApngDecoder {
|
|||
* @param speed Optional parameter.
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
@JvmStatic
|
||||
fun decodeApng(inStream: InputStream, speed : Float = 1f) : Drawable {
|
||||
val inputStream = BufferedInputStream(inStream)
|
||||
val bytes = ByteArray(8)
|
||||
|
@ -85,8 +86,9 @@ class ExperimentalApngDecoder {
|
|||
val crc = CRC32()
|
||||
crc.update(byteArray.copyOfRange(i, byteArray.size - 4))
|
||||
if (chunkCRC == crc.value.toInt()) {
|
||||
when (byteArray.copyOfRange(i, i + 4).contentToString()) {
|
||||
Utils.fcTL -> {
|
||||
val name = byteArray.copyOfRange(i, i + 4)
|
||||
when {
|
||||
name.contentEquals(Utils.fcTL) -> {
|
||||
if (png == null) {
|
||||
cover?.let {
|
||||
it.addAll(Utils.to4Bytes(0).asList())
|
||||
|
@ -184,7 +186,7 @@ class ExperimentalApngDecoder {
|
|||
}
|
||||
}
|
||||
}
|
||||
Utils.IEND -> {
|
||||
name.contentEquals(Utils.IEND) -> {
|
||||
if (isApng && png != null) {
|
||||
png.addAll(Utils.to4Bytes(0).asList())
|
||||
// Add IEND
|
||||
|
@ -239,7 +241,7 @@ class ExperimentalApngDecoder {
|
|||
}
|
||||
}
|
||||
}
|
||||
Utils.IDAT -> {
|
||||
name.contentEquals(Utils.IDAT) -> {
|
||||
if (png == null) {
|
||||
if (cover == null) {
|
||||
cover = ArrayList()
|
||||
|
@ -275,7 +277,7 @@ class ExperimentalApngDecoder {
|
|||
png.addAll(Utils.to4Bytes(crC32.value.toInt()).asList())
|
||||
}
|
||||
}
|
||||
Utils.fdAT -> {
|
||||
name.contentEquals(Utils.fdAT) -> {
|
||||
// Find the chunk length
|
||||
val bodySize = Utils.parseLength(byteArray.copyOfRange(i - 4, i))
|
||||
png?.addAll(Utils.to4Bytes(bodySize - 4).asList())
|
||||
|
@ -288,19 +290,19 @@ class ExperimentalApngDecoder {
|
|||
png?.addAll(body)
|
||||
png?.addAll(Utils.to4Bytes(crC32.value.toInt()).asList())
|
||||
}
|
||||
Utils.plte -> {
|
||||
name.contentEquals(Utils.plte) -> {
|
||||
plte = byteArray
|
||||
}
|
||||
Utils.tnrs -> {
|
||||
name.contentEquals(Utils.tnrs) -> {
|
||||
tnrs = byteArray
|
||||
}
|
||||
Utils.IHDR -> {
|
||||
name.contentEquals(Utils.IHDR) -> {
|
||||
ihdr.parse(byteArray)
|
||||
maxWidth = ihdr.pngWidth
|
||||
maxHeight =ihdr.pngHeight
|
||||
buffer = Bitmap.createBitmap(maxWidth, maxHeight, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
Utils.acTL -> {
|
||||
name.contentEquals(Utils.acTL) -> {
|
||||
isApng = true
|
||||
}
|
||||
}
|
||||
|
@ -325,6 +327,7 @@ class ExperimentalApngDecoder {
|
|||
* @param speed Optional parameter.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
@JvmStatic
|
||||
fun decodeApng(file : File, speed: Float = 1f) : Drawable = decodeApng(FileInputStream(file), speed)
|
||||
|
||||
/**
|
||||
|
@ -333,6 +336,7 @@ class ExperimentalApngDecoder {
|
|||
* @param uri Uri to open.
|
||||
* @param speed Optional parameter.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun decodeApng(context : Context, uri : Uri, speed: Float = 1f) : Drawable {
|
||||
val inputStream = context.contentResolver.openInputStream(uri)
|
||||
?: throw Exception("Failed to open InputStream, InputStream is null")
|
||||
|
@ -346,6 +350,7 @@ class ExperimentalApngDecoder {
|
|||
* @param speed Optional parameter.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
@JvmStatic
|
||||
fun decodeApng(context : Context, @RawRes res : Int, speed: Float = 1f) : Drawable = decodeApng(context.resources.openRawResource(res), speed)
|
||||
|
||||
/**
|
||||
|
@ -354,6 +359,8 @@ class ExperimentalApngDecoder {
|
|||
* @param url URL to decode.
|
||||
* @param speed Optional parameter.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
@JvmStatic
|
||||
suspend fun decodeApng(context : Context, url : URL, speed: Float = 1f) = withContext(Dispatchers.IO) {
|
||||
decodeApng(FileInputStream(Loader.load(context, url)), speed)
|
||||
}
|
||||
|
|
|
@ -81,18 +81,16 @@ class Frame// Get width and height for image
|
|||
* @param byteArray The frame
|
||||
*/
|
||||
private fun parseChunk(byteArray: ByteArray) {
|
||||
when(byteArray.copyOfRange(4, 8).contentToString()) {
|
||||
IHDR -> {
|
||||
val name = byteArray.copyOfRange(4, 8)
|
||||
if (name.contentEquals(IHDR)) {
|
||||
ihdr = IHDR()
|
||||
ihdr.parse(byteArray)
|
||||
width = ihdr.pngWidth
|
||||
height = ihdr.pngHeight
|
||||
}
|
||||
IDAT -> {
|
||||
} else if (name.contentEquals(IDAT)){
|
||||
// Get IDAT Bytes
|
||||
idat = IDAT()
|
||||
idat.parse(byteArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ class Loader {
|
|||
* @param url Url of the file to download
|
||||
* @return [ByteArray] of the file
|
||||
*/
|
||||
@Suppress("RedundantSuspendModifier")
|
||||
@Throws(IOException::class)
|
||||
suspend fun load(context: Context, url: URL): File = withContext(Dispatchers.IO) {
|
||||
val currentDir = context.filesDir
|
||||
|
|
|
@ -7,7 +7,11 @@ class Utils {
|
|||
* @return [Boolean] True if is a png
|
||||
*/
|
||||
fun isPng(byteArray: ByteArray): Boolean {
|
||||
return byteArray.copyOfRange(0, 8).contentToString() == pngSignature.contentToString()
|
||||
// return byteArray.copyOfRange(0, 8).contentToString() == pngSignature.contentToString()
|
||||
return if (byteArray.size == 8)
|
||||
byteArray.contentEquals(pngSignature)
|
||||
else
|
||||
byteArray.copyOfRange(0, 8).contentEquals(pngSignature)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,13 +150,13 @@ class Utils {
|
|||
return lengthString.toLong(16).toInt()
|
||||
}
|
||||
|
||||
val fcTL : String by lazy { byteArrayOf(0x66, 0x63, 0x54, 0x4c).contentToString() }
|
||||
val IEND : String by lazy { byteArrayOf(0x49, 0x45, 0x4e, 0x44).contentToString() }
|
||||
val IDAT : String by lazy { byteArrayOf(0x49, 0x44, 0x41, 0x54).contentToString() }
|
||||
val fdAT : String by lazy { byteArrayOf(0x66, 0x64, 0x41, 0x54).contentToString() }
|
||||
val plte : String by lazy { byteArrayOf(0x50, 0x4c, 0x54, 0x45).contentToString() }
|
||||
val tnrs : String by lazy { byteArrayOf(0x74, 0x52, 0x4e, 0x53).contentToString() }
|
||||
val IHDR : String by lazy { byteArrayOf(0x49, 0x48, 0x44, 0x52).contentToString() }
|
||||
val acTL : String by lazy { byteArrayOf(0x61, 0x63, 0x54, 0x4c).contentToString() }
|
||||
val fcTL : ByteArray by lazy { byteArrayOf(0x66, 0x63, 0x54, 0x4c) }
|
||||
val IEND : ByteArray by lazy { byteArrayOf(0x49, 0x45, 0x4e, 0x44) }
|
||||
val IDAT : ByteArray by lazy { byteArrayOf(0x49, 0x44, 0x41, 0x54) }
|
||||
val fdAT : ByteArray by lazy { byteArrayOf(0x66, 0x64, 0x41, 0x54) }
|
||||
val plte : ByteArray by lazy { byteArrayOf(0x50, 0x4c, 0x54, 0x45) }
|
||||
val tnrs : ByteArray by lazy { byteArrayOf(0x74, 0x52, 0x4e, 0x53) }
|
||||
val IHDR : ByteArray by lazy { byteArrayOf(0x49, 0x48, 0x44, 0x52) }
|
||||
val acTL : ByteArray by lazy { byteArrayOf(0x61, 0x63, 0x54, 0x4c) }
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ dependencies {
|
|||
//noinspection GradleCompatible
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
|
@ -44,7 +45,7 @@ dependencies {
|
|||
implementation project(":apng_library")
|
||||
// implementation fileTree(include: ['*.aar'], dir: 'libs')
|
||||
//implementation 'com.github.oupson:Kapng-Android:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.2.0-alpha04'
|
||||
implementation "org.jetbrains.anko:anko-appcompat-v7:$anko_version"
|
||||
implementation "org.jetbrains.anko:anko-design:$anko_version"
|
||||
implementation "org.jetbrains.anko:anko-constraint-layout:$anko_version"
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".JavaActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
@ -27,7 +24,7 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".Main2Activity"
|
||||
android:name=".ViewerActivity"
|
||||
android:label="APNG Viewer">
|
||||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
|
|
@ -23,6 +23,7 @@ import oupson.apng.ApngAnimator
|
|||
import oupson.apngcreator.adapter.AnkoAdapter
|
||||
import java.io.File
|
||||
|
||||
// TODO
|
||||
class CreatorActivity : AppCompatActivity() {
|
||||
companion object {
|
||||
private const val PICK_IMAGE = 999
|
||||
|
@ -124,7 +125,7 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
id = View.generateViewId()
|
||||
backgroundColor = Color.WHITE
|
||||
appBarLayout {
|
||||
toolbar = xToolbar {
|
||||
/**toolbar = xToolbar {
|
||||
id = View.generateViewId()
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
|
@ -134,7 +135,7 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
width = matchParent
|
||||
height = wrapContent
|
||||
bottomMargin = 1
|
||||
}
|
||||
}*/
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
|
@ -143,14 +144,14 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
id = View.generateViewId()
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
below(bar)
|
||||
//below(bar)
|
||||
}
|
||||
listView = listView {
|
||||
id = View.generateViewId()
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = matchParent
|
||||
below(optimiseCheckBox)
|
||||
//below(optimiseCheckBox)
|
||||
}
|
||||
addFrameButton = floatingActionButton {
|
||||
imageResource = R.drawable.ic_add_black_24dp
|
||||
|
@ -161,8 +162,8 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
width = wrapContent
|
||||
height = wrapContent
|
||||
margin = dip(5)
|
||||
alignParentBottom()
|
||||
alignParentEnd()
|
||||
//alignParentBottom()
|
||||
//alignParentEnd()
|
||||
}
|
||||
createButton = floatingActionButton {
|
||||
imageResource = R.drawable.ic_play_arrow_black_24dp
|
||||
|
@ -173,8 +174,9 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
width = wrapContent
|
||||
height = wrapContent
|
||||
margin = dip(5)
|
||||
alignParentBottom()
|
||||
alignParentStart()
|
||||
//alignParentBottom()
|
||||
//alignParentStart()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package oupson.apngcreator;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import kotlin.Unit;
|
||||
import oupson.apng.ApngAnimator;
|
||||
import oupson.apng.ApngAnimatorKt;
|
||||
public class JavaActivity extends AppCompatActivity {
|
||||
private static final String TAG = "JavaActivity";
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_java);
|
||||
String imageUrl = "https://metagif.files.wordpress.com/2015/01/bugbuckbunny.png";
|
||||
ImageView image = findViewById(R.id.javaImageView);
|
||||
ApngAnimator a = ApngAnimatorKt.loadApng(image, imageUrl);
|
||||
a.onLoaded((animator) -> {
|
||||
animator.setOnFrameChangeLister((index) -> {
|
||||
if (index == 0) {
|
||||
Log.i(TAG, "Loop");
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package oupson.apngcreator;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import kotlin.Unit;
|
||||
import oupson.apng.ApngAnimator;
|
||||
import oupson.apng.ApngAnimatorKt;
|
||||
|
||||
|
||||
public class JavaFragment extends Fragment {
|
||||
private static final String TAG = "JavaActivity";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Log.i(TAG, "onCreateView()");
|
||||
View v = inflater.inflate(R.layout.fragment_java, container, false);
|
||||
String imageUrl = "https://metagif.files.wordpress.com/2015/01/bugbuckbunny.png";
|
||||
ImageView imageView = v.findViewById(R.id.javaImageView);
|
||||
if (imageView != null) {
|
||||
ApngAnimator a = ApngAnimatorKt.loadApng(imageView, imageUrl);
|
||||
a.onLoaded((animator) -> {
|
||||
animator.setOnFrameChangeLister((index) -> {
|
||||
if (index == 0) {
|
||||
Log.i(TAG, "Loop");
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package oupson.apngcreator
|
||||
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.SeekBar
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.squareup.picasso.Picasso
|
||||
import oupson.apng.ApngAnimator
|
||||
import oupson.apng.loadApng
|
||||
|
||||
|
||||
class KotlinFragment : Fragment() {
|
||||
private var apngImageView : ImageView? = null
|
||||
private var normalImageView : ImageView? = null
|
||||
|
||||
private var pauseButton : Button? = null
|
||||
private var playButton : Button? = null
|
||||
|
||||
private var speedSeekBar : SeekBar? = null
|
||||
|
||||
private var animator : ApngAnimator? = null
|
||||
|
||||
private val imageUrls = arrayListOf(
|
||||
"http://oupson.oupsman.fr/apng/bigApng.png",
|
||||
"https://metagif.files.wordpress.com/2015/01/bugbuckbunny.png",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/3/3f/JPEG_example_flower.jpg",
|
||||
"http://orig06.deviantart.net/7812/f/2012/233/7/5/twilight_rapidash_shaded_and_animated_by_tamalesyatole-d5bz7hd.png",
|
||||
"https://raw.githubusercontent.com/tinify/iMessage-Panda-sticker/master/StickerPackExtension/Stickers.xcstickers/Sticker%20Pack.stickerpack/panda.sticker/panda.png",
|
||||
"file:///android_asset/image.png"
|
||||
)
|
||||
private val selected = 4
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "onCreateView()")
|
||||
// Inflate the layout for this fragment
|
||||
val view = inflater.inflate(R.layout.fragment_kotlin, container, false)
|
||||
|
||||
apngImageView = view.findViewById(R.id.ApngImageView)
|
||||
normalImageView = view.findViewById(R.id.NormalImageView)
|
||||
|
||||
pauseButton = view.findViewById(R.id.PauseButton)
|
||||
playButton = view.findViewById(R.id.PlayButton)
|
||||
|
||||
speedSeekBar = view.findViewById(R.id.SpeedSeekBar)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "onResume()")
|
||||
|
||||
playButton?.setOnClickListener {
|
||||
animator?.play()
|
||||
}
|
||||
|
||||
pauseButton?.setOnClickListener {
|
||||
animator?.pause()
|
||||
}
|
||||
|
||||
speedSeekBar?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||
if (seekBar != null)
|
||||
animator?.speed = seekBar.progress.toFloat() / 100f
|
||||
}
|
||||
})
|
||||
|
||||
if (animator == null) {
|
||||
animator = apngImageView?.loadApng(imageUrls[selected])?.apply {
|
||||
onLoaded {
|
||||
setOnFrameChangeLister {
|
||||
// Log.e("app-test", "onLoop")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Picasso.get().load(imageUrls[selected]).into(normalImageView)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(TAG, "onPause()")
|
||||
|
||||
// animator = null
|
||||
normalImageView?.setImageDrawable(null)
|
||||
// apngImageView?.setImageDrawable(null)
|
||||
|
||||
playButton?.setOnClickListener(null)
|
||||
pauseButton?.setOnClickListener(null)
|
||||
speedSeekBar?.setOnSeekBarChangeListener(null)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "KotlinFragment"
|
||||
@JvmStatic
|
||||
fun newInstance() =
|
||||
KotlinFragment()
|
||||
}
|
||||
}
|
|
@ -1,188 +1,131 @@
|
|||
package oupson.apngcreator
|
||||
|
||||
import android.graphics.Color
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewManager
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.anko.*
|
||||
import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder
|
||||
import org.jetbrains.anko.constraint.layout.applyConstraintSet
|
||||
import org.jetbrains.anko.constraint.layout.constraintLayout
|
||||
import org.jetbrains.anko.constraint.layout.matchConstraint
|
||||
import org.jetbrains.anko.custom.ankoView
|
||||
import org.jetbrains.anko.design.appBarLayout
|
||||
import org.jetbrains.anko.sdk27.coroutines.onClick
|
||||
import org.jetbrains.anko.sdk27.coroutines.onSeekBarChangeListener
|
||||
import oupson.apng.ApngAnimator
|
||||
import oupson.apng.CustomAnimationDrawable
|
||||
import oupson.apng.ExperimentalApngDecoder
|
||||
import java.net.URL
|
||||
import androidx.core.view.GravityCompat
|
||||
import com.google.android.material.bottomappbar.BottomAppBarTopEdgeTreatment
|
||||
import com.google.android.material.shape.CutCornerTreatment
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.shape.ShapeAppearanceModel
|
||||
import com.google.android.material.shape.ShapePath
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import org.jetbrains.anko.startActivity
|
||||
|
||||
|
||||
// TODO REMOVE ANKO
|
||||
fun ViewManager.xToolbar(init : androidx.appcompat.widget.Toolbar.() -> Unit) = ankoView({androidx.appcompat.widget.Toolbar(it)}, 0, init)
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var animator: ApngAnimator
|
||||
private lateinit var tool : androidx.appcompat.widget.Toolbar
|
||||
// val imageUrl = "http://oupson.oupsman.fr/apng/bigApng.png"
|
||||
private val imageUrl = "https://metagif.files.wordpress.com/2015/01/bugbuckbunny.png"
|
||||
//private val imageUrl = "https://upload.wikimedia.org/wikipedia/commons/3/3f/JPEG_example_flower.jpg"
|
||||
// val imageUrl = "http://orig06.deviantart.net/7812/f/2012/233/7/5/twilight_rapidash_shaded_and_animated_by_tamalesyatole-d5bz7hd.png"
|
||||
// val imageUrl = "https://raw.githubusercontent.com/tinify/iMessage-Panda-sticker/master/StickerPackExtension/Stickers.xcstickers/Sticker%20Pack.stickerpack/panda.sticker/panda.png"
|
||||
// val imageUrl = "file:///android_asset/image.png"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
verticalLayout {
|
||||
verticalLayout {
|
||||
appBarLayout {
|
||||
tool = xToolbar {
|
||||
id = View.generateViewId()
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
}
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
bottomMargin = 1
|
||||
}
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
|
||||
setSupportActionBar(bottomAppBar)
|
||||
|
||||
setUpBottomAppBarShapeAppearance()
|
||||
|
||||
fabCreate.setOnClickListener {
|
||||
startActivity<CreatorActivity>()
|
||||
}
|
||||
|
||||
constraintLayout {
|
||||
backgroundColor = Color.WHITE
|
||||
val pauseButton = button("pause") {
|
||||
backgroundColor = Color.WHITE
|
||||
id = View.generateViewId()
|
||||
onClick {
|
||||
animator.pause()
|
||||
}
|
||||
}.lparams(
|
||||
width = wrapContent,
|
||||
height = wrapContent
|
||||
)
|
||||
val playButton = button("play") {
|
||||
backgroundColor = Color.WHITE
|
||||
id = View.generateViewId()
|
||||
onClick {
|
||||
animator.play()
|
||||
}
|
||||
}.lparams(
|
||||
width = wrapContent,
|
||||
height = wrapContent
|
||||
)
|
||||
val seekBar = seekBar {
|
||||
id = View.generateViewId()
|
||||
max = 200
|
||||
progress = 100
|
||||
onSeekBarChangeListener {
|
||||
onProgressChanged { _, _, _ -> }
|
||||
onStartTrackingTouch { }
|
||||
onStopTrackingTouch { seekBar ->
|
||||
animator.speed = (seekBar?.progress?.toFloat() ?: 100f) / 100f
|
||||
val drawerToggle = ActionBarDrawerToggle(this, drawer_layout, bottomAppBar, R.string.open, R.string.close)
|
||||
drawer_layout.addDrawerListener(drawerToggle)
|
||||
drawerToggle.syncState()
|
||||
|
||||
var selected = 0
|
||||
|
||||
navigationView.setNavigationItemSelectedListener { menuItem : MenuItem ->
|
||||
when(menuItem.itemId) {
|
||||
R.id.menu_kotlin_activity -> {
|
||||
if (selected != 0) {
|
||||
supportFragmentManager.beginTransaction().apply {
|
||||
replace(R.id.fragment_container, KotlinFragment.newInstance())
|
||||
addToBackStack(null)
|
||||
}.commit()
|
||||
selected = 0
|
||||
}
|
||||
}
|
||||
}.lparams(
|
||||
width = matchConstraint,
|
||||
height = wrapContent
|
||||
)
|
||||
val imageView2 = imageView {
|
||||
id = View.generateViewId()
|
||||
Picasso.get().load(imageUrl).into(this)
|
||||
}.lparams(
|
||||
width = matchConstraint,
|
||||
height = matchConstraint
|
||||
)
|
||||
val imageView = imageView {
|
||||
id = View.generateViewId()
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val drawable = ExperimentalApngDecoder.decodeApng(this@MainActivity, URL(imageUrl))
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
this@imageView.setImageDrawable(drawable)
|
||||
if (drawable is CustomAnimationDrawable)
|
||||
drawable.start()
|
||||
R.id.menu_java_activity -> {
|
||||
if (selected != 1) {
|
||||
supportFragmentManager.beginTransaction().apply {
|
||||
replace(R.id.fragment_container, JavaFragment())
|
||||
addToBackStack(null)
|
||||
}.commit()
|
||||
selected = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawer_layout.closeDrawer(GravityCompat.START)
|
||||
|
||||
/**
|
||||
animator = this.loadApng(imageUrl).apply {
|
||||
onLoaded {
|
||||
setOnFrameChangeLister {
|
||||
// Log.e("app-test", "onLoop")
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}.lparams(
|
||||
width = matchConstraint,
|
||||
height = matchConstraint
|
||||
)
|
||||
applyConstraintSet {
|
||||
pauseButton {
|
||||
connect(
|
||||
ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.TOP of seekBar margin dip(8),
|
||||
ConstraintSetBuilder.Side.END to ConstraintSetBuilder.Side.END of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8)
|
||||
)
|
||||
}
|
||||
playButton {
|
||||
connect(
|
||||
ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.TOP of seekBar margin dip(8),
|
||||
ConstraintSetBuilder.Side.START to ConstraintSetBuilder.Side.START of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8)
|
||||
)
|
||||
}
|
||||
seekBar {
|
||||
connect(
|
||||
ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.BOTTOM of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8),
|
||||
ConstraintSetBuilder.Side.END to ConstraintSetBuilder.Side.END of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8),
|
||||
ConstraintSetBuilder.Side.START to ConstraintSetBuilder.Side.START of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8)
|
||||
)
|
||||
}
|
||||
imageView2 {
|
||||
connect(
|
||||
ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.TOP of playButton margin dip(8),
|
||||
ConstraintSetBuilder.Side.END to ConstraintSetBuilder.Side.END of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8),
|
||||
ConstraintSetBuilder.Side.START to ConstraintSetBuilder.Side.START of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8),
|
||||
ConstraintSetBuilder.Side.TOP to ConstraintSetBuilder.Side.BOTTOM of imageView
|
||||
)
|
||||
}
|
||||
imageView {
|
||||
connect(
|
||||
ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.TOP of imageView2 margin dip(8),
|
||||
ConstraintSetBuilder.Side.END to ConstraintSetBuilder.Side.END of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8),
|
||||
ConstraintSetBuilder.Side.START to ConstraintSetBuilder.Side.START of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8),
|
||||
ConstraintSetBuilder.Side.TOP to ConstraintSetBuilder.Side.TOP of ConstraintLayout.LayoutParams.PARENT_ID margin dip(8)
|
||||
)
|
||||
}
|
||||
}
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = matchParent
|
||||
}
|
||||
}
|
||||
setSupportActionBar(tool)
|
||||
return@setNavigationItemSelectedListener true
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
val inflater = menuInflater
|
||||
inflater.inflate(R.menu.main_menu, menu)
|
||||
return true
|
||||
supportFragmentManager.beginTransaction().apply {
|
||||
add(R.id.fragment_container, KotlinFragment.newInstance(), "KotlinFragment")
|
||||
}.commit()
|
||||
|
||||
|
||||
navigationView.setCheckedItem(R.id.menu_kotlin_activity)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item!!.itemId) {
|
||||
R.id.action_open_create_activity -> startActivity<CreatorActivity>()
|
||||
R.id.action_open_java_activity -> startActivity<JavaActivity>()
|
||||
private fun setUpBottomAppBarShapeAppearance() {
|
||||
val fabShapeAppearanceModel: ShapeAppearanceModel = fabCreate.shapeAppearanceModel
|
||||
val cutCornersFab =
|
||||
(fabShapeAppearanceModel.bottomLeftCorner is CutCornerTreatment
|
||||
&& fabShapeAppearanceModel.bottomRightCorner is CutCornerTreatment)
|
||||
val topEdge =
|
||||
if (cutCornersFab) BottomAppBarCutCornersTopEdge(
|
||||
bottomAppBar.fabCradleMargin,
|
||||
bottomAppBar.fabCradleRoundedCornerRadius,
|
||||
bottomAppBar.cradleVerticalOffset
|
||||
) else BottomAppBarTopEdgeTreatment(
|
||||
bottomAppBar.fabCradleMargin,
|
||||
bottomAppBar.fabCradleRoundedCornerRadius,
|
||||
bottomAppBar.cradleVerticalOffset
|
||||
)
|
||||
val babBackground = bottomAppBar.background as MaterialShapeDrawable
|
||||
babBackground.shapeAppearanceModel =
|
||||
babBackground.shapeAppearanceModel.toBuilder().setTopEdge(topEdge).build()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
|
||||
|
||||
inner class BottomAppBarCutCornersTopEdge(
|
||||
private val fabMargin: Float,
|
||||
roundedCornerRadius: Float,
|
||||
private val cradleVerticalOffset: Float
|
||||
) :
|
||||
BottomAppBarTopEdgeTreatment(fabMargin, roundedCornerRadius, cradleVerticalOffset) {
|
||||
@SuppressLint("RestrictedApi")
|
||||
override fun getEdgePath(
|
||||
length: Float,
|
||||
center: Float,
|
||||
interpolation: Float,
|
||||
shapePath: ShapePath
|
||||
) {
|
||||
val fabDiameter = fabDiameter
|
||||
if (fabDiameter == 0f) {
|
||||
shapePath.lineTo(length, 0f)
|
||||
return
|
||||
}
|
||||
val diamondSize = fabDiameter / 2f
|
||||
val middle = center + horizontalOffset
|
||||
val verticalOffsetRatio = cradleVerticalOffset / diamondSize
|
||||
if (verticalOffsetRatio >= 1.0f) {
|
||||
shapePath.lineTo(length, 0f)
|
||||
return
|
||||
}
|
||||
shapePath.lineTo(middle - (fabMargin + diamondSize - cradleVerticalOffset), 0f)
|
||||
shapePath.lineTo(
|
||||
middle,
|
||||
(diamondSize - cradleVerticalOffset + fabMargin) * interpolation
|
||||
)
|
||||
shapePath.lineTo(middle + (fabMargin + diamondSize - cradleVerticalOffset), 0f)
|
||||
shapePath.lineTo(length, 0f)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,32 +2,23 @@ package oupson.apngcreator
|
|||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.jetbrains.anko.backgroundColor
|
||||
import org.jetbrains.anko.imageView
|
||||
import org.jetbrains.anko.matchParent
|
||||
import org.jetbrains.anko.verticalLayout
|
||||
import kotlinx.android.synthetic.main.activity_viewer.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import oupson.apng.CustomAnimationDrawable
|
||||
import oupson.apng.ExperimentalApngDecoder
|
||||
|
||||
class Main2Activity : AppCompatActivity() {
|
||||
private lateinit var imageView : ImageView
|
||||
class ViewerActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_viewer)
|
||||
|
||||
verticalLayout {
|
||||
imageView = imageView().lparams {
|
||||
width = matchParent
|
||||
height = matchParent
|
||||
}
|
||||
backgroundColor = Color.parseColor("#323232")
|
||||
}
|
||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
|
@ -50,26 +41,15 @@ class Main2Activity : AppCompatActivity() {
|
|||
|
||||
private fun load() {
|
||||
val uri = intent.data ?: return
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
//val animator = imageView.loadApng(uri, null)
|
||||
val drawable = ExperimentalApngDecoder.decodeApng(this, uri)
|
||||
imageView.setImageDrawable(drawable)
|
||||
val drawable = ExperimentalApngDecoder.decodeApng(this@ViewerActivity, uri)
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
viewerImageView.setImageDrawable(drawable)
|
||||
if (drawable is CustomAnimationDrawable)
|
||||
drawable.start()
|
||||
/**
|
||||
imageView.onClick {
|
||||
try {
|
||||
if (animator.isApng) {
|
||||
if (animator.isPlaying) {
|
||||
animator.pause()
|
||||
} else {
|
||||
animator.play()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int,
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/colorPrimary" android:state_checked="true" />
|
||||
<item android:color="@color/text" />
|
||||
</selector>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
||||
</vector>
|
|
@ -0,0 +1,30 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="346dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="346">
|
||||
<path
|
||||
android:pathData="M82.554,267.473C82.554,267.473 69.356,275.148 91.947,277.745C119.316,280.867 133.303,280.42 163.464,274.711C163.464,274.711 171.393,279.683 182.467,283.99C114.856,312.967 29.448,282.311 82.554,267.473"
|
||||
android:fillColor="#5382A1"/>
|
||||
<path
|
||||
android:pathData="M74.292,229.659C74.292,229.659 59.489,240.617 82.097,242.955C111.333,245.971 134.421,246.218 174.373,238.525C174.373,238.525 179.899,244.127 188.588,247.191C106.841,271.095 15.79,249.076 74.292,229.659"
|
||||
android:fillColor="#5382A1"/>
|
||||
<path
|
||||
android:pathData="M143.942,165.515C160.601,184.695 139.565,201.955 139.565,201.955C139.565,201.955 181.866,180.118 162.439,152.772C144.295,127.271 130.38,114.6 205.707,70.914C205.707,70.914 87.469,100.444 143.942,165.515"
|
||||
android:fillColor="#E76F00"/>
|
||||
<path
|
||||
android:pathData="M233.364,295.442C233.364,295.442 243.131,303.489 222.607,309.715C183.581,321.538 60.175,325.108 25.893,310.186C13.57,304.825 36.68,297.385 43.949,295.824C51.53,294.18 55.863,294.487 55.863,294.487C42.158,284.832 -32.72,313.444 17.829,321.637C155.682,343.993 269.121,311.571 233.364,295.442"
|
||||
android:fillColor="#5382A1"/>
|
||||
<path
|
||||
android:pathData="M88.901,190.48C88.901,190.48 26.129,205.389 66.672,210.803C83.79,213.095 117.915,212.577 149.702,209.913C175.68,207.722 201.765,203.063 201.765,203.063C201.765,203.063 192.605,206.986 185.978,211.511C122.234,228.276 -0.908,220.477 34.543,203.328C64.524,188.836 88.901,190.48 88.901,190.48"
|
||||
android:fillColor="#5382A1"/>
|
||||
<path
|
||||
android:pathData="M201.506,253.422C266.305,219.75 236.345,187.392 215.433,191.751C210.307,192.818 208.022,193.743 208.022,193.743C208.022,193.743 209.925,190.762 213.559,189.472C254.929,174.927 286.746,232.369 200.204,255.119C200.204,255.12 201.207,254.224 201.506,253.422"
|
||||
android:fillColor="#5382A1"/>
|
||||
<path
|
||||
android:pathData="M162.439,0.371C162.439,0.371 198.326,36.27 128.402,91.472C72.331,135.754 115.616,161.002 128.379,189.849C95.649,160.318 71.63,134.323 87.744,110.128C111.395,74.613 176.918,57.394 162.439,0.371"
|
||||
android:fillColor="#E76F00"/>
|
||||
<path
|
||||
android:pathData="M95.268,344.665C157.467,348.647 252.98,342.456 255.242,313.026C255.242,313.026 250.894,324.183 203.838,333.043C150.75,343.033 85.274,341.867 46.439,335.464C46.44,335.463 54.389,342.044 95.268,344.665"
|
||||
android:fillColor="#5382A1"/>
|
||||
</vector>
|
|
@ -0,0 +1,58 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="60dp"
|
||||
android:height="60dp"
|
||||
android:viewportWidth="60"
|
||||
android:viewportHeight="60">
|
||||
<path
|
||||
android:pathData="M0,60l30.1,-30.1l29.9,30.1z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startY="74.0143"
|
||||
android:startX="15.9594"
|
||||
android:endY="45.6668"
|
||||
android:endX="44.3068"
|
||||
android:type="linear">
|
||||
<item android:offset="0.09677" android:color="#FF0095D5"/>
|
||||
<item android:offset="0.3007" android:color="#FF238AD9"/>
|
||||
<item android:offset="0.6211" android:color="#FF557BDE"/>
|
||||
<item android:offset="0.8643" android:color="#FF7472E2"/>
|
||||
<item android:offset="1" android:color="#FF806EE3"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M0,0l30.1,0l-30.1,32.5z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startY="12.0591"
|
||||
android:startX="4.2092"
|
||||
android:endY="-4.405"
|
||||
android:endX="20.6734"
|
||||
android:type="linear">
|
||||
<item android:offset="0.1183" android:color="#FF0095D5"/>
|
||||
<item android:offset="0.4178" android:color="#FF3C83DC"/>
|
||||
<item android:offset="0.6962" android:color="#FF6D74E1"/>
|
||||
<item android:offset="0.8333" android:color="#FF806EE3"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M30.1,0l-30.1,31.7l0,28.3l30.1,-30.1l29.9,-29.9z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startY="55.1638"
|
||||
android:startX="-10.1017"
|
||||
android:endY="-0.6694"
|
||||
android:endX="45.7315"
|
||||
android:type="linear">
|
||||
<item android:offset="0.1075" android:color="#FFC757BC"/>
|
||||
<item android:offset="0.2138" android:color="#FFD0609A"/>
|
||||
<item android:offset="0.4254" android:color="#FFE1725C"/>
|
||||
<item android:offset="0.6048" android:color="#FFEE7E2F"/>
|
||||
<item android:offset="0.743" android:color="#FFF58613"/>
|
||||
<item android:offset="0.8232" android:color="#FFF88909"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
|
||||
</vector>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".JavaActivity">
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/apng_imageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp" app:srcCompat="@mipmap/ic_launcher" android:id="@+id/javaImageView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/drawer_layout">
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/background">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="?actionBarSize">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabCreate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_create_white_24dp"
|
||||
android:text="@string/create"
|
||||
app:tint="@android:color/white"
|
||||
app:backgroundTint="@color/secondary"
|
||||
app:layout_anchor="@id/bottomAppBar"
|
||||
app:shapeAppearance="@style/AppShapeAppearance.MediumComponent" />
|
||||
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/bottomAppBar"
|
||||
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center"
|
||||
app:layout_anchorGravity="start"
|
||||
app:navigationIcon="@drawable/ic_menu_white_24dp">
|
||||
</com.google.android.material.bottomappbar.BottomAppBar>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:id="@+id/navigationView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
app:menu="@menu/navigation_menu"
|
||||
app:itemIconTint="@color/drawer_item"
|
||||
app:itemTextColor="@color/drawer_item"
|
||||
app:itemBackground="@android:color/transparent"/>
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#323232">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/viewerImageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/description_viewer_imageView"/>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".JavaFragment">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/javaImageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@mipmap/ic_launcher"
|
||||
android:contentDescription="@string/description_viewer_imageView"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/background">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ApngImageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/NormalImageView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/NormalImageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/SpeedSeekBar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/ApngImageView" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/SpeedSeekBar"
|
||||
style="@style/Widget.AppCompat.SeekBar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:max="200"
|
||||
android:progress="100"
|
||||
app:layout_constraintBottom_toTopOf="@id/PlayButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/PlayButton"
|
||||
style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@android:color/white"
|
||||
android:text="@string/title_playButton"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/PauseButton"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@android:color/white"
|
||||
android:text="@string/title_pauseButton"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item android:id="@+id/action_open_create_activity"
|
||||
android:title="@string/create_apng"
|
||||
app:showAsAction="never" />
|
||||
<item android:id="@+id/action_open_java_activity"
|
||||
android:title="@string/java_activity"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/menu_kotlin_activity"
|
||||
android:icon="@drawable/ic_kotlin"
|
||||
android:title="@string/menu_title_kotlin_activity" />
|
||||
<item
|
||||
android:id="@+id/menu_java_activity"
|
||||
android:icon="@drawable/ic_java"
|
||||
android:title="@string/menu_title_java_activity" />
|
||||
</group>
|
||||
</menu>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="is_theme_light">false</bool>
|
||||
</resources>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="text">#fff</color>
|
||||
|
||||
<color name="gray">#999999</color>
|
||||
|
||||
<color name="background">#000</color>
|
||||
|
||||
<color name="control">#fff</color>
|
||||
</resources>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="is_theme_light">true</bool>
|
||||
</resources>
|
|
@ -1,8 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#ffffff</color>
|
||||
<color name="colorPrimaryDark">#ffffff</color>
|
||||
<color name="colorPrimary">@color/primary</color>
|
||||
<color name="colorPrimaryDark">@color/primary_dark</color>
|
||||
<color name="colorAccent">#b00020</color>
|
||||
|
||||
<color name="primary">#81c784</color>
|
||||
<color name="primary_light">#b2fab4</color>
|
||||
<color name="primary_dark">#519657</color>
|
||||
|
||||
<color name="secondary">#ff5722</color>
|
||||
<color name="secondary_light">#ff8a50</color>
|
||||
<color name="secondary_dark">#c41c00</color>
|
||||
|
||||
<color name="text">#000</color>
|
||||
|
||||
<color name="gray">#999999</color>
|
||||
|
||||
<color name="background">#ffffff</color>
|
||||
|
||||
<color name="control">#fff</color>
|
||||
</resources>
|
||||
|
|
|
@ -4,4 +4,20 @@
|
|||
<string name="create_apng">Create APNG</string>
|
||||
<string name="java_activity">Java Activity</string>
|
||||
<string name="apng_imageView">An ImageView with an APNG</string>
|
||||
|
||||
<string name="description_viewer_imageView">Loaded Image</string>
|
||||
|
||||
<string name="title_playButton">Play</string>
|
||||
<string name="title_pauseButton">Pause</string>
|
||||
|
||||
<string name="menu_title_kotlin_activity">Kotlin Activity</string>
|
||||
<string name="menu_title_java_activity">Java Activity</string>
|
||||
|
||||
<string name="create">Create</string>
|
||||
|
||||
<string name="open">open</string>
|
||||
<string name="close">close</string>
|
||||
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:textColorPrimary">#000</item>
|
||||
<item name="android:textColorSecondary">#000</item>
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
|
||||
<item name="toolbarStyle">@style/AppTheme.ActionBar</item>
|
||||
<item name="colorControlNormal">@color/gray</item>
|
||||
<item name="colorPrimaryDark">@color/background</item>
|
||||
|
||||
<item name="colorAccent">@color/secondary</item>
|
||||
|
||||
<item name="android:textColorPrimary">@color/text</item>
|
||||
<item name="android:textColorSecondary">@color/text</item>
|
||||
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">@bool/is_theme_light</item>
|
||||
<item name="android:navigationBarColor">@color/colorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.ActionBar" parent="Widget.AppCompat.Toolbar">
|
||||
<item name="titleTextColor">@color/gray</item>
|
||||
<item name="subtitleTextColor">@color/gray</item>
|
||||
<style name="AppShapeAppearance.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent">
|
||||
<item name="cornerFamily">cut</item>
|
||||
<item name="cornerSize">8dp</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue