Work on demo app

This commit is contained in:
oupson 2020-01-24 22:46:19 +01:00
parent d8d9945daf
commit a307f35346
33 changed files with 730 additions and 366 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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"/>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_theme_light">false</bool>
</resources>

View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_theme_light">true</bool>
</resources>

View File

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

View File

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

View File

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