parent
73ee647e89
commit
de4073e6b8
|
@ -1,13 +1,13 @@
|
|||
# Kapng-Android
|
||||
An android library to create or display apng
|
||||
|
||||
Exemple of apng :
|
||||
Example of apng :
|
||||
|
||||
![apng-example](https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png)
|
||||
|
||||
How to use this library :
|
||||
|
||||
To load animated png to an imageview :
|
||||
To load animated png to an imageView :
|
||||
```kotlin
|
||||
|
||||
val imageUrl = "https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png" // image url could be an url, or a file path. You could also load byteArray and file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="oupson.apng">
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
</manifest>
|
||||
|
|
|
@ -41,9 +41,10 @@ class APNGDisassembler {
|
|||
if (isApng(byteArray)) {
|
||||
var cursor = 8
|
||||
while (cursor < byteArray.size) {
|
||||
val chunk = byteArray.copyOfRange(cursor, cursor + parseLength(byteArray.copyOfRange(cursor, cursor + 4)) + 12)
|
||||
val length = parseLength(byteArray.copyOfRange(cursor, cursor + 4))
|
||||
val chunk = byteArray.copyOfRange(cursor, cursor + length + 12)
|
||||
parseChunk(chunk)
|
||||
cursor += parseLength(byteArray.copyOfRange(cursor, cursor + 4)) + 12
|
||||
cursor += length + 12
|
||||
}
|
||||
return apng
|
||||
} else {
|
||||
|
|
|
@ -164,8 +164,7 @@ class ApngAnimator(private val context: Context?) {
|
|||
* @return [ApngAnimator] The Animator
|
||||
* @throws NotApngException
|
||||
*/
|
||||
@Suppress("unused")
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@JvmOverloads
|
||||
fun load(file: File, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator {
|
||||
GlobalScope.launch {
|
||||
val bytes = file.readBytes()
|
||||
|
@ -200,6 +199,7 @@ class ApngAnimator(private val context: Context?) {
|
|||
* @return [ApngAnimator] The Animator
|
||||
* @throws NotApngException
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun load(uri : Uri, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator {
|
||||
GlobalScope.launch {
|
||||
context?.contentResolver?.openInputStream(uri)?.readBytes()?.also {
|
||||
|
@ -235,7 +235,7 @@ class ApngAnimator(private val context: Context?) {
|
|||
* @return [ApngAnimator] The Animator
|
||||
* @throws NotApngException
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@JvmOverloads
|
||||
fun loadUrl(url: URL, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator {
|
||||
GlobalScope.launch {
|
||||
this@ApngAnimator.speed = speed
|
||||
|
@ -275,7 +275,7 @@ class ApngAnimator(private val context: Context?) {
|
|||
* @return [ApngAnimator] The Animator
|
||||
* @throws NotApngException
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@JvmOverloads
|
||||
fun load(byteArray: ByteArray, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator {
|
||||
GlobalScope.launch {
|
||||
this@ApngAnimator.speed = speed
|
||||
|
@ -310,6 +310,7 @@ class ApngAnimator(private val context: Context?) {
|
|||
* @return [ApngAnimator] The Animator
|
||||
* @throws NotApngException
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun load(string: String, speed : Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator {
|
||||
GlobalScope.launch {
|
||||
this@ApngAnimator.speed = speed
|
||||
|
@ -357,6 +358,7 @@ class ApngAnimator(private val context: Context?) {
|
|||
* @return [ApngAnimator] The Animator
|
||||
* @throws NotApngException
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun load(@RawRes res : Int, speed : Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator {
|
||||
GlobalScope.launch {
|
||||
val byteArray = context?.resources?.openRawResource(res)?.readBytes() ?: byteArrayOf()
|
||||
|
@ -462,25 +464,25 @@ class ApngAnimator(private val context: Context?) {
|
|||
val animResume = CustomAnimationDrawable()
|
||||
activeAnimation?.stop()
|
||||
val currentFrame = activeAnimation!!.current
|
||||
val dura = ArrayList<Float>()
|
||||
val durations = ArrayList<Float>()
|
||||
frameLoop@ for (i in 0 until anim?.numberOfFrames!!) {
|
||||
val checkFrame = activeAnimation!!.getFrame(i)
|
||||
if (checkFrame === currentFrame) {
|
||||
for (k in i until activeAnimation!!.numberOfFrames) {
|
||||
val frame = activeAnimation!!.getFrame(k)
|
||||
animResume.addFrame(frame, (duration!![k] / (speed ?: 1f)).toInt())
|
||||
dura.add(duration!![k])
|
||||
durations.add(duration!![k])
|
||||
}
|
||||
for (k in 0 until i) {
|
||||
val frame = activeAnimation!!.getFrame(k)
|
||||
animResume.addFrame(frame, (duration!![k] / (speed ?: 1f)).toInt())
|
||||
dura.add(duration!![k])
|
||||
durations.add(duration!![k])
|
||||
}
|
||||
activeAnimation = animResume
|
||||
imageView?.setImageDrawable(activeAnimation)
|
||||
activeAnimation?.setOnFrameChangeListener(frameChangeLister)
|
||||
imageView?.invalidate()
|
||||
duration = dura
|
||||
duration = durations
|
||||
break@frameLoop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@file:Suppress("unused")
|
||||
|
||||
package oupson.apng.exceptions
|
||||
|
||||
class NoFrameException : Exception()
|
||||
|
|
|
@ -11,6 +11,7 @@ class BitmapDiffCalculator(firstBitmap: Bitmap, secondBitmap : Bitmap) {
|
|||
val res : Bitmap
|
||||
var xOffset : Int = 0
|
||||
var yOffset : Int = 0
|
||||
@Suppress("unused")
|
||||
var blendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_OVER
|
||||
init {
|
||||
val difBitmap = Bitmap.createBitmap(firstBitmap.width, firstBitmap.height, Bitmap.Config.ARGB_8888)
|
||||
|
|
|
@ -9,41 +9,45 @@ Copyright (c) 2018 Miller Cy Chan
|
|||
https://github.com/mcychan/nQuant.android/blob/master/nQuant.master/src/main/java/com/android/nQuant/PnnQuantizer.java
|
||||
*/
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class PnnQuantizer {
|
||||
private final short SHORT_MAX = Short.MAX_VALUE;
|
||||
private final char BYTE_MAX = -Byte.MIN_VALUE + Byte.MAX_VALUE;
|
||||
private boolean hasTransparency = false, hasSemiTransparency = false;
|
||||
protected int width, height;
|
||||
protected int pixels[] = null;
|
||||
protected int[] pixels = null;
|
||||
private Integer m_transparentColor;
|
||||
private HashMap<Integer, short[]> closestMap = new HashMap();
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressLint("UseSparseArrays")
|
||||
private final HashMap<Integer, short[]> closestMap = new HashMap();
|
||||
|
||||
public PnnQuantizer(String fname) throws IOException {
|
||||
@SuppressWarnings("unused")
|
||||
public PnnQuantizer(String fname) {
|
||||
fromBitmap(fname);
|
||||
}
|
||||
|
||||
public PnnQuantizer(Bitmap bitmap) throws IOException{
|
||||
public PnnQuantizer(Bitmap bitmap) {
|
||||
fromBitmap(bitmap);
|
||||
}
|
||||
|
||||
private void fromBitmap(Bitmap bitmap) throws IOException {
|
||||
private void fromBitmap(Bitmap bitmap) {
|
||||
width = bitmap.getWidth();
|
||||
height = bitmap.getHeight();
|
||||
pixels = new int [width * height];
|
||||
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
|
||||
}
|
||||
|
||||
private void fromBitmap(String fname) throws IOException {
|
||||
private void fromBitmap(String fname) {
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(fname);
|
||||
fromBitmap(bitmap);
|
||||
}
|
||||
|
@ -204,6 +208,7 @@ public class PnnQuantizer {
|
|||
List<Integer> palette = new ArrayList<>();
|
||||
short k = 0;
|
||||
for (int i = 0;; ++k) {
|
||||
assert bins[i] != null;
|
||||
int alpha = (int) Math.rint(bins[i].ac);
|
||||
palette.add(Color.argb(alpha, (int) Math.rint(bins[i].rc), (int) Math.rint(bins[i].gc), (int) Math.rint(bins[i].bc)));
|
||||
if (hasTransparency && palette.get(k).equals(m_transparentColor)) {
|
||||
|
@ -292,6 +297,7 @@ public class PnnQuantizer {
|
|||
return k;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "UnusedReturnValue", "UnusedAssignment", "SameReturnValue"})
|
||||
boolean quantize_image(final int[] pixels, final Integer[] palette, int[] qPixels, final boolean dither)
|
||||
{
|
||||
int nMaxColors = palette.length;
|
||||
|
@ -301,6 +307,7 @@ public class PnnQuantizer {
|
|||
sqr_tbl[i + BYTE_MAX] = i * i;
|
||||
|
||||
int[] squares3 = new int[sqr_tbl.length - BYTE_MAX];
|
||||
//noinspection ManualArrayCopy
|
||||
for (int i = 0; i < squares3.length; i++)
|
||||
squares3[i] = sqr_tbl[i + BYTE_MAX];
|
||||
|
||||
|
@ -412,6 +419,7 @@ public class PnnQuantizer {
|
|||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedAssignment")
|
||||
private Bitmap quantize_image(final int[] pixels, int[] qPixels)
|
||||
{
|
||||
int pixelIndex = 0;
|
||||
|
@ -519,6 +527,7 @@ public class PnnQuantizer {
|
|||
return Bitmap.createBitmap(qPixels, width, height, Bitmap.Config.RGB_565);
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public Bitmap convert(int nMaxColors, boolean dither) {
|
||||
final int[] cPixels = new int[pixels.length];
|
||||
for (int i =0; i<cPixels.length; ++i) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<application
|
||||
android:fullBackupContent="false"
|
||||
android:allowBackup="true"
|
||||
android:hardwareAccelerated="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
|
|
@ -8,11 +8,11 @@ import android.graphics.BitmapFactory
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.text.Html
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import android.widget.ListView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import org.jetbrains.anko.*
|
||||
import org.jetbrains.anko.design.appBarLayout
|
||||
|
@ -27,10 +27,10 @@ class CreatorActivity : AppCompatActivity() {
|
|||
companion object {
|
||||
private const val PICK_IMAGE = 999
|
||||
}
|
||||
var items : ArrayList<Bitmap> = ArrayList()
|
||||
var bitmapAdapter : AnkoAdapter<Bitmap>? = null
|
||||
private var items : ArrayList<Bitmap> = ArrayList()
|
||||
private var bitmapAdapter : AnkoAdapter<Bitmap>? = null
|
||||
|
||||
var view = CreatorActivityLayout()
|
||||
private var view = CreatorActivityLayout()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -66,16 +66,14 @@ class CreatorActivity : AppCompatActivity() {
|
|||
a.onLoaded { anim ->
|
||||
alert {
|
||||
customView {
|
||||
ctx.setTheme(R.style.AppTheme_DarkDialog)
|
||||
imageView {
|
||||
this.setImageDrawable(anim.anim)
|
||||
}
|
||||
|
||||
}
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
bitmapAdapter = AnkoAdapter({items}) {index, items, view ->
|
||||
bitmapAdapter = AnkoAdapter({items}) { index, items, _ ->
|
||||
with(items[index]) {
|
||||
verticalLayout {
|
||||
lparams {
|
||||
|
@ -93,15 +91,18 @@ class CreatorActivity : AppCompatActivity() {
|
|||
}
|
||||
/* frameListViewAdapter(this, items) */
|
||||
view.listView.adapter = bitmapAdapter
|
||||
setSupportActionBar(view.toolbar)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when(requestCode) {
|
||||
PICK_IMAGE -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
contentResolver.openInputStream(data?.data).readBytes().apply {
|
||||
items.add(BitmapFactory.decodeByteArray(this, 0, this.size))
|
||||
bitmapAdapter?.notifyDataSetChanged()
|
||||
if (data?.data != null) {
|
||||
contentResolver.openInputStream(data.data!!)?.readBytes()?.apply {
|
||||
items.add(BitmapFactory.decodeByteArray(this, 0, this.size))
|
||||
bitmapAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,18 +115,16 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
lateinit var addFrameButton : FloatingActionButton
|
||||
lateinit var createButton : FloatingActionButton
|
||||
lateinit var optimiseCheckBox : CheckBox
|
||||
lateinit var toolbar : Toolbar
|
||||
override fun createView(ui: AnkoContext<CreatorActivity>) = with(ui) {
|
||||
relativeLayout {
|
||||
|
||||
backgroundColor = Color.BLACK
|
||||
backgroundColor = Color.WHITE
|
||||
val bar = verticalLayout {
|
||||
id = View.generateViewId()
|
||||
backgroundColor = Color.DKGRAY
|
||||
backgroundColor = Color.WHITE
|
||||
appBarLayout {
|
||||
backgroundColor = Color.BLACK
|
||||
toolbar {
|
||||
toolbar = xToolbar {
|
||||
id = View.generateViewId()
|
||||
title = Html.fromHtml("<font color='#ffffff'>Create APNG</font>")
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
|
@ -141,7 +140,6 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
}
|
||||
optimiseCheckBox = checkBox("Optimise APNG, WIP !") {
|
||||
id = View.generateViewId()
|
||||
this.textColor = Color.WHITE
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
below(bar)
|
||||
|
@ -155,7 +153,8 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
}
|
||||
addFrameButton = floatingActionButton {
|
||||
imageResource = R.drawable.ic_add_black_24dp
|
||||
backgroundTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
imageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
backgroundTintList = ColorStateList.valueOf(Color.BLACK)
|
||||
isClickable = true
|
||||
}.lparams {
|
||||
width = wrapContent
|
||||
|
@ -166,7 +165,8 @@ class CreatorActivityLayout : AnkoComponent<CreatorActivity> {
|
|||
}
|
||||
createButton = floatingActionButton {
|
||||
imageResource = R.drawable.ic_play_arrow_black_24dp
|
||||
backgroundTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
imageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
backgroundTintList = ColorStateList.valueOf(Color.BLACK)
|
||||
isClickable = true
|
||||
}.lparams {
|
||||
width = wrapContent
|
||||
|
|
|
@ -8,7 +8,7 @@ import kotlin.Unit;
|
|||
import oupson.apng.ApngAnimator;
|
||||
import oupson.apng.ApngAnimatorKt;
|
||||
public class JavaActivity extends AppCompatActivity {
|
||||
static String TAG = "JavaActivity";
|
||||
private static final String TAG = "JavaActivity";
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package oupson.apngcreator
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toolbar
|
||||
import android.view.ViewManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.squareup.picasso.Picasso
|
||||
|
@ -14,16 +14,17 @@ 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.onMenuItemClick
|
||||
import org.jetbrains.anko.sdk27.coroutines.onSeekBarChangeListener
|
||||
import oupson.apng.ApngAnimator
|
||||
import oupson.apng.loadApng
|
||||
|
||||
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 : Toolbar
|
||||
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"
|
||||
// val imageUrl = "http://orig06.deviantart.net/7812/f/2012/233/7/5/twilight_rapidash_shaded_and_animated_by_tamalesyatole-d5bz7hd.png"
|
||||
|
@ -31,32 +32,11 @@ class MainActivity : AppCompatActivity() {
|
|||
// val imageUrl = "file:///android_asset/image.png"
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val buttonDrawable = GradientDrawable().apply {
|
||||
shape = GradientDrawable.RECTANGLE
|
||||
cornerRadius = dip(5).toFloat()
|
||||
setStroke(2, Color.WHITE)
|
||||
}
|
||||
verticalLayout {
|
||||
backgroundColor = Color.BLACK
|
||||
verticalLayout {
|
||||
backgroundColor = Color.DKGRAY
|
||||
appBarLayout {
|
||||
backgroundColor = Color.BLACK
|
||||
tool = toolbar {
|
||||
tool = xToolbar {
|
||||
id = View.generateViewId()
|
||||
title = Html.fromHtml("<font color='#ffffff'>MainActivity</font>", Html.FROM_HTML_MODE_LEGACY)
|
||||
inflateMenu(R.menu.main_menu)
|
||||
onMenuItemClick { item ->
|
||||
when (item!!.itemId) {
|
||||
R.id.action_open_create_activity -> {
|
||||
startActivity<CreatorActivity>()
|
||||
finish()
|
||||
}
|
||||
R.id.action_open_java_activity -> {
|
||||
startActivity<JavaActivity>()
|
||||
}
|
||||
}
|
||||
}
|
||||
}.lparams {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
|
@ -72,9 +52,10 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
constraintLayout {
|
||||
backgroundColor = Color.WHITE
|
||||
val pauseButton = button("pause") {
|
||||
backgroundColor = Color.WHITE
|
||||
id = View.generateViewId()
|
||||
background = buttonDrawable
|
||||
onClick {
|
||||
animator.pause()
|
||||
}
|
||||
|
@ -83,7 +64,7 @@ class MainActivity : AppCompatActivity() {
|
|||
height = wrapContent
|
||||
)
|
||||
val playButton = button("play") {
|
||||
background = buttonDrawable
|
||||
backgroundColor = Color.WHITE
|
||||
id = View.generateViewId()
|
||||
onClick {
|
||||
animator.play()
|
||||
|
@ -92,15 +73,15 @@ class MainActivity : AppCompatActivity() {
|
|||
width = wrapContent,
|
||||
height = wrapContent
|
||||
)
|
||||
val seekBar = themedSeekBar(R.style.AppTheme_SeekBar){
|
||||
val seekBar = seekBar {
|
||||
id = View.generateViewId()
|
||||
max = 200
|
||||
progress = 10
|
||||
progress = 100
|
||||
onSeekBarChangeListener {
|
||||
onProgressChanged { _, _, _ -> }
|
||||
onStartTrackingTouch { }
|
||||
onStopTrackingTouch { seekBar ->
|
||||
animator.speed = (seekBar?.progress?.toFloat() ?: 100f / 100f)
|
||||
animator.speed = (seekBar?.progress?.toFloat() ?: 100f) / 100f
|
||||
}
|
||||
}
|
||||
}.lparams(
|
||||
|
@ -168,7 +149,21 @@ class MainActivity : AppCompatActivity() {
|
|||
width = matchParent
|
||||
height = matchParent
|
||||
}
|
||||
|
||||
}
|
||||
setSupportActionBar(tool)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
val inflater = menuInflater
|
||||
inflater.inflate(R.menu.main_menu, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
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>()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,10 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.BaseAdapter
|
||||
|
||||
class AnkoAdapter<T>(itemFactory: () -> List<T>, viewFactory: Context.(index: Int, items: List<T>, view: View?) -> View): BaseAdapter() {
|
||||
val viewFactory = viewFactory
|
||||
class AnkoAdapter<T>(itemFactory: () -> List<T>,
|
||||
val viewFactory: Context.(index: Int, items: List<T>, view: View?) -> View
|
||||
): BaseAdapter() {
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val items: List<T> by lazy { itemFactory() }
|
||||
|
||||
override fun getView(index: Int, view: View?, viewGroup: ViewGroup?): View {
|
||||
|
@ -18,11 +20,10 @@ class AnkoAdapter<T>(itemFactory: () -> List<T>, viewFactory: Context.(index: In
|
|||
}
|
||||
|
||||
override fun getItem(index: Int): T {
|
||||
return items.get(index)
|
||||
return items[index]
|
||||
}
|
||||
|
||||
override fun getItemId(index: Int): Long {
|
||||
|
||||
return (items.get(index) as Any).hashCode().toLong() + (index.toLong() * Int.MAX_VALUE)
|
||||
return (items[index] as Any).hashCode().toLong() + (index.toLong() * Int.MAX_VALUE)
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
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"
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
<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="Create apng"
|
||||
android:title="@string/create_apng"
|
||||
app:showAsAction="never" />
|
||||
<item android:id="@+id/action_open_java_activity"
|
||||
android:title="Java Activity"
|
||||
android:title="@string/java_activity"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
|
@ -1,6 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
<color name="colorPrimary">#ffffff</color>
|
||||
<color name="colorPrimaryDark">#ffffff</color>
|
||||
<color name="colorAccent">#b00020</color>
|
||||
|
||||
<color name="gray">#999999</color>
|
||||
</resources>
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
<resources>
|
||||
<string name="app_name">APNGCreator</string>
|
||||
|
||||
<string name="create_apng">Create APNG</string>
|
||||
<string name="java_activity">Java Activity</string>
|
||||
<string name="apng_imageView">An ImageView with an APNG</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,33 +1,18 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">#000</item>
|
||||
<item name="colorPrimaryDark">#000</item>
|
||||
<item name="colorAccent">#fff</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:textColorPrimary">#ffffff</item>
|
||||
<item name="actionMenuTextColor">#fff</item>
|
||||
<item name="android:itemBackground">#000</item>
|
||||
<item name="android:textColorSecondary">#fff</item>
|
||||
<item name="android:colorEdgeEffect">#fff</item>
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.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">true</item>
|
||||
<item name="toolbarStyle">@style/AppTheme.ActionBar</item>
|
||||
<item name="colorControlNormal">@color/gray</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.SeekBar" parent="Widget.AppCompat.SeekBar">
|
||||
<item name="android:progressBackgroundTint">#999999</item>
|
||||
<item name="android:progressTint">#fff</item>
|
||||
<item name="android:colorControlActivated">#fff</item>
|
||||
<style name="AppTheme.ActionBar" parent="Widget.AppCompat.Toolbar">
|
||||
<item name="titleTextColor">@color/gray</item>
|
||||
<item name="subtitleTextColor">@color/gray</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.DarkDialog" parent="Theme.AppCompat.Dialog.Alert">
|
||||
<!-- Used for the buttons -->
|
||||
<item name="colorAccent">#fff</item>
|
||||
<!-- Used for the title and text -->
|
||||
<item name="android:textColorPrimary">#FFFFFF</item>
|
||||
<!-- Used for the background -->
|
||||
<item name="android:background">#000</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue