Android studio kotlin, how to get array of random images? - android-studio

i have image files in drawable folder, named like this:
img1.png, img2.png, img3.png ... img16.png
is there any way to get random 5 images and put them in array?

Define list of drawables
Random the indexs
Convert the indexs to Drawable
val drawables = arrayOf(
1, 2, 3, 4,
5, 6, 7, 8
)
var selected = Random.asJavaRandom().ints(5, 0, drawables.size).mapToObj {
ContextCompat.getDrawable(this, drawables[it]);
}

Random integers and get drawable resource id with Resources#getIdentifier
fun getDrawables(context: Context): Array<Drawable> {
val imgIndices = ArrayList<Int>()
val drawables = ArrayList<Drawable>()
while (imgIndices.size < 5) {
val index = Random.nextInt(16)
if (!imgIndices.contains(index)) {
imgIndices.add(index)
}
}
for (i in imgIndices) {
val drawableRes = context.resources.getIdentifier("img${i + 1}", "drawable", context.packageName)
val drawable = ContextCompat.getDrawable(context, drawableRes)
drawable?.let {
drawables.add(it)
}
}
return drawables.toTypedArray();
}

Related

Not getting Audios from Android 11 even download and other music files

Here I am receiving only media Alarm Ringtones in android 11 but found all audios in other devices on android 10 and below versions
Here in picture you can see i am getting only Alarm bells in android 11
I found solution of this problem. In android 11 now Android introduces new Table MediaStore.Downloads to get other audio files:
#SuppressLint("Range")
suspend fun getAllAudioFiles(): ArrayList<AudioModel> {
val list = ArrayList<AudioModel>()
val files = ArrayList<File>()
list.clear()
withContext(Dispatchers.IO) {
try {
val columns = arrayOf(
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media._ID,
)
//Some audio may be explicitly marked as not being music
//Some audio may be explicitly marked as not being music
val selection = MediaStore.Audio.Media.IS_MUSIC + " == 0"
//For Android 10 and Android 11
val cursor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MergeCursor(
arrayOf(
context.contentResolver.query(
MediaStore.Downloads.INTERNAL_CONTENT_URI,
columns, null,
null,
null
),
context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
columns, null,
null,
null
)
)
)
} else {
//For Below Android 11
MergeCursor(
arrayOf(
context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
columns, null,
null,
null
)
)
)
}
cursor?.moveToFirst()
// files.clear()
while (!cursor?.isAfterLast!!) {
val model = AudioModel()
val path =
cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))
// files.add(File(path))
val id =
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID))
val title =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE))
var duration =""
try {
duration =
cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))
.toLong().convertLongToDurationTime()
}catch (e:Exception){
duration = "-1"
}
val size =
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE))
.toLong().convertToLongTMbSize()
model.duration = duration
model.path = path
model.id = id
model.title = title
model.size = size
list.add(model)
cursor.moveToNext()
}
cursor.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
return list
}
reference here: https://developer.android.com/training/data-storage/shared/media

How do I run every exported function

So i have this mess of a js file
cardPool = []
class Card {
constructor(name = "", portrait = "", bloodCost = 0, boneCost = 0, power = 0, health = 1, sigilList = ["No sigil"]) {
this.name = name
this.portrait = portrait;
this.bloodCost = bloodCost;
this.boneCost = boneCost;
this.power = power;
this.health = health;
this.sigilList = sigilList;
cardPool.push(this)
}
Damage(dmg = 1) {
this.health -= dmg
}
}
blank = new Card("blank", "🔳");
income = new Card("income", "⬇️");
module.exports = {
Card,
blank,
income,
bear: function () { new Card("Grizzly", "🐻", 3, 0, 4, 6) },
wolf: function () { new Card("Wolf", "🐺", 2, 0, 3, 2) },
cardPool,
};
All I want to do is on start up it run all of the function being exported. There more function that I export but here only a few so stack overflow won't scream at me. This is for a game that I'm making to be able to handle multiple instance of the same card. You can read about why I make new card using function here: How to change a local class varible node js . And I need a card pool so that I can do stuff in another file here my other question: How can i put an object inside a list on Initialization. Now I need on startup put all the card that I make in the module.export in the cardPool.
The best way to do this would be placing the functions in some kind of container (for example an array or a map) (in case you later want to export other functions from the file that don't create cards). Here's the simplest way with an array:
// Note the return statements! The functions will not return anything without them!
function bear () { return new Card("Grizzly", "🐻", 3, 0, 4, 6) }
function wolf () { return new Card("Wolf", "🐺", 2, 0, 3, 2) }
module.exports = {
// ...
cardCreatorFunctions: [bear, wolf, /* and maybe others */],
}
Then, you can iterate through the array and push created cards into cardPool one-by-one:
for (let fun of cardLib.cardCreatorFunctions) {
cardLib.cardPool.push(fun())
}
Or you can do it in one statement:
cardLib.cardPool = cardLib.cardCreatorFunctions.map(fun => fun())

TornadoFX datagrid empty

So I have been following this tutorial that tells you how to make a datagrid in TornadoFX, and everything works fine. However, I want to add multiple Views to each cell of my datagrid, so I want to replace the stackpane with a borderpane. This breaks it. Cells still show up, but they are blank white squares. None of the Views show up inside.
I'm not really sure why this happens. It seems to me that cellFormat and cellCache act like for-each loops, making a graphic described inside of them for each element in the list of cells that need formatting. I'm not sure, though.
As such, I'm really not sure how to fix this. I really appreciate it if anybody can help.
Code that puts a green circle and a label on each of the white squares:
class DatagridDemo: View("Datagrid Demo") {
val data = listOf("one", "two", "three")
override val root = datagrid(data) {
cellFormat {
graphic = stackpane() {
circle(radius = 50.0) {
fill = Color.ALICEBLUE;
}
label(it);
}
}
}
}
My code:
class DatagridDemo: View("Datagrid Demo") {
val data = listOf("one", "two", "three")
override val root = datagrid(data) {
cellFormat {
graphic = borderpane() {
//The widgets implement View()
top<TopWidget>();
bottom<BottomWidget>()
label(it);
}
}
}
}
This uses two custom Fragments to create objects that are added to the top and the bottom.
class TopWidget(msg : String) : Fragment() {
override val root = label(msg)
}
class BottomWidget(msg : String) : Fragment() {
override val root = label(msg)
}
class DatagridDemo: View("Datagrid Demo") {
val data = listOf("one", "two", "three")
override val root = datagrid(data) {
cellFormat {
graphic = borderpane {
top { add(TopWidget("Top ${it}")) }
center { label(it) }
bottom { add(BottomWidget("Bottom ${it}")) }
}
}
}
}
class DGDemo : App(DatagridDemo::class)

How to implement Haskell's splitEvery in Swift?

PROBLEM
let x = (0..<10).splitEvery( 3 )
XCTAssertEqual( x, [(0...2),(3...5),(6...8),(9)], "implementation broken" )
COMMENTS
I am running into problems calculating number of elements in the Range, etc...
extension Range
{
func splitEvery( nInEach: Int ) -> [Range]
{
let n = self.endIndex - self.startIndex // ERROR - cannot invoke '-' with an argument list of type (T,T)
}
}
The values in a range are of ForwardIndexType, so you can only advance() them,
or compute the distance(), but the subtraction - is not defined. The advance amount has to be of the corresponding
type T.Distance. So this would be a possible implementation:
extension Range {
func splitEvery(nInEach: T.Distance) -> [Range] {
var result = [Range]() // Start with empty array
var from = self.startIndex
while from != self.endIndex {
// Advance position, but not beyond the end index:
let to = advance(from, nInEach, self.endIndex)
result.append(from ..< to)
// Continue with next interval:
from = to
}
return result
}
}
Example:
println( (0 ..< 10).splitEvery(3) )
// Output: [0..<3, 3..<6, 6..<9, 9..<10]
Note however that 0 ..< 10 is not a list (or array) of integers. To split an array into subarrays you could define a similar extension:
extension Array {
func splitEvery(nInEach: Int) -> [[T]] {
var result = [[T]]()
for from in stride(from: 0, to: self.count, by: nInEach) {
let to = advance(from, nInEach, self.count)
result.append(Array(self[from ..< to]))
}
return result
}
}
Example:
println( [1, 1, 2, 3, 5, 8, 13].splitEvery(3) )
// Output: [[1, 1, 2], [3, 5, 8], [13]]
A more general approach could be to split all sliceable objects. But Sliceable
is protocol and protocols cannot be extended. What you can do instead is to
define a function that takes the sliceable object as the first argument:
func splitEvery<S : Sliceable>(seq : S, nInEach : S.Index.Distance) -> [S.SubSlice] {
var result : [S.SubSlice] = []
var from = seq.startIndex
while from != seq.endIndex {
let to = advance(from, nInEach, seq.endIndex)
result.append(seq[from ..< to])
from = to
}
return result
}
(Note that this function is completely unrelated to the (extension) methods
defined above.)
Example:
println( splitEvery("abcdefg", 2) )
// Output: [ab, cd, ef, g]
println( splitEvery([3.1, 4.1, 5.9, 2.6, 5.3], 2) )
// Output: [[3.1, 4.1], [5.9, 2.6], [5.3]]
Ranges are not sliceable, but you could define a separate function that takes a
range argument:
func splitEvery<T>(range : Range<T>, nInEach : T.Distance) -> [Range<T>] {
var result : [Range<T>] = []
var from = range.startIndex
while from != range.endIndex {
let to = advance(from, nInEach, range.endIndex)
result.append(from ..< to)
from = to
}
return result
}
Example:
println( splitEvery(0 ..< 10, 3) )
// Output: [0..<3, 3..<6, 6..<9, 9..<10]

How to 'Slice' a Collection in Groovy

I have a collection of objects that I want to break up into a collection of collections, where each sequential group of 3 elements is in one collection.
For example, if I have
def l = [1,4,2,4,5,9]
I want to turn this into:
def r = [[1,4,2], [4,5,9]]
I'm doing it now by iterating over the collection and breaking it up.. but I then need to pass those 'groups' into a parallelized function that processes them.. It would be nice to eliminate this O(n) pre-processing work and just say something like
l.slice(3).collectParallel { subC -> process(subC) }
I've found the step method on the Range class, but it looks like that only acts on the indices. Any clever ideas?
Update:
I don't think this is a duplicate of the referenced link, although it's very close. As suggested below, it's more of the iterator-type thing I'm looking for.. the sub-collections will then be passed into a GPars collectParallel. Ideally I wouldn't need to allocate an entire new collection.
Check out groovy 1.8.6. There is a new collate method on List.
def list = [1, 2, 3, 4]
assert list.collate(4) == [[1, 2, 3, 4]] // gets you everything
assert list.collate(2) == [[1, 2], [3, 4]] //splits evenly
assert list.collate(3) == [[1, 2, 3], [4]] // won't split evenly, remainder in last list.
Take a look at the Groovy List documentation for more info because there are a couple of other params that give you some other options, including dropping the remainder.
As far as your parallel processing goes, you can cruise through the lists with gpars.
def list = [1, 2, 3, 4, 5]
GParsPool.withPool {
list.collate(2).eachParallel {
println it
}
}
If I understand you correctly, you're currently copying the elements from the original collection into the sub-collections. For more suggestions along those lines, checkout the answers to the following question: Split collection into sub collections in Groovy
It sounds like what you're instead looking for is a way for the sub-collections to effectively be a view into the original collection. If that's the case, check out the List.subList() method. You could either loop over the indices from 0 to size() in increments of 3 (or whatever slice size you choose) or you could get fancier and build an Iterable/List which would hide the details from the caller. Here's an implementation of the latter, inspired by Ted's answer.
class Slicer implements Iterator {
private List backingList
private int sliceSize
private int index
Slicer(List backingList, int sliceSize) {
this.backingList = backingList
this.sliceSize = sliceSize
}
Object next() {
if (!hasNext()) {
throw new NoSuchElementException()
}
def ret
if (index + sliceSize <= backingList.size()) {
ret = backingList.subList(index, index+sliceSize)
} else if (hasNext()) {
ret = backingList.subList(index, backingList.size())
}
index += sliceSize
return ret
}
boolean hasNext() {
return index < backingList.size()
}
void remove() {
throw new UnsupportedOperationException() //I'm lazy ;)
}
}
I like both solutions but here is a slightly improved version of the first solution that I like very much:
class Slicer implements Iterator {
private List backingList
private int sliceSize
private int index
Slicer(List backingList, int sliceSize) {
this.backingList = backingList;
int ss = sliceSize;
// negitive sliceSize = -N means, split the list into N equal (or near equal) pieces
if( sliceSize < 0) {
ss = -sliceSize;
ss = (int)((backingList.size()+ss-1)/ss);
}
this.sliceSize = ss
}
Object next() {
if (!hasNext()) {
throw new NoSuchElementException()
}
def ret = backingList.subList(index, Math.min(index+sliceSize , backingList.size()) );
index += sliceSize
return ret
}
boolean hasNext() {
return index < backingList.size() - 1
}
void remove() {
throw new UnsupportedOperationException() //I'm lazy ;)
}
List asList() {
this.collect { new ArrayList(it) }
}
List flatten() {
backingList.asImmutable()
}
}
// ======== TESTS
def a = [1,2,3,4,5,6,7,8];
assert [1,2,3,4,5,6,7,8] == a;
assert [[1, 2], [3, 4], [5, 6], [7, 8]] == new Slicer(a,2).asList();
assert [[1,2,3], [4,5,6], [7,8]] == (new Slicer(a,3)).collect { it } // alternative to asList but inner items are subList
assert [3, 2, 1, 6, 5, 4, 8, 7] == ((new Slicer(a,3)).collect { it.reverse() } ).flatten()
// show flatten iterator
//new Slicer(a,2).flattenEach { print it }
//println ""
// negetive slice into N pieces, in this example we split it into 2 pieces
assert [[1, 2, 3, 4], [5, 6, 7, 8]] == new Slicer(a,-2).collect { it as List } // same asList
assert [[1, 2, 3], [4, 5, 6], [7, 8]] == new Slicer(a,-3).asList()
//assert a == (new Slicer(a,3)).flattenCollect { it }
assert [9..10, 19..20, 29..30] == ( (new Slicer(1..30,2)).findAll { slice -> !(slice[1] % 10) } )
assert [[9, 10], [19, 20], [29, 30]] == ( (new Slicer(1..30,2)).findAll { slice -> !(slice[1] % 10) }.collect { it.flatten() } )
println( (new Slicer(1..30,2)).findAll { slice -> !(slice[1] % 10) } )
println( (new Slicer(1..30,2)).findAll { slice -> !(slice[1] % 10) }.collect { it.flatten() } )
There isn't anything built in to do exactly what you want, but if we #Delegate calls to the native lists's iterator, we can write our own class that works just like an Iterator that returns the chunks you're looking for:
class Slicer {
protected Integer sliceSize
#Delegate Iterator iterator
Slicer(objectWithIterator, Integer sliceSize) {
this.iterator = objectWithIterator.iterator()
this.sliceSize = sliceSize
}
Object next() {
List currentSlice = []
while(hasNext() && currentSlice.size() < sliceSize) {
currentSlice << this.iterator.next()
}
return currentSlice
}
}
assert [[1,4,2], [4,5,9]] == new Slicer([1,4,2,4,5,9], 3).collect { it }
Because it has all of the methods that a normal Iterator does, you get the groovy syntactic sugar methods for free with lazy evaluation on anything that has an iterator() method, like a range:
assert [5,6] == new Slicer(1..100, 2).find { slice -> slice.first() == 5 }
assert [[9, 10], [19, 20], [29, 30]] == new Slicer(1..30, 2).findAll { slice -> !(slice[1] % 10) }

Resources