Randomize question on Android Studio - Kotlin - android

I made a simple quiz on Android Studio which contains 8 questions. How to make the questions become random without duplicated. This app does not use a database. I'm new to programming so I don't know what to do about this
Here's the code Kuis Activity
private lateinit var kuis: TextView
private lateinit var rg: RadioGroup
private lateinit var choiceA: RadioButton
private lateinit var choiceB: RadioButton
private lateinit var choiceC: RadioButton
private lateinit var choiceD: RadioButton
private var number = 0
val question: Array<String> = arrayOf(
"Mandau merupakan senjata tradisional yang berasal dari suku...",
"Pakaian tradisional suku Madura bernama...",
"Suku yang teridentifikasi memiliki 13 kerajaan adalah...",
"Cheongsam merupakan pakaian tradisional dari...",
"Lagu Jubata merupakan lagu yang berasal dari suku Dayak yang memiliki arti...",
"Berikut ini merupakan kuliner khas Kalimantan Barat kecuali...",
"'Takadang jantu barang dah latih'. Penggalan lirik tersebut berasal dari lagu...",
"Rumah Adat Saoraja merupakan rumah adat yang berasal dari suku..."
)
val option = arrayOf(
"Jawa", "Dayak", "Melayu", "Bugis",
"Batik", "Teluk Belanga", "King Baba", "Pesa'an",
"Jawa", "Dayak", "Melayu", "Madura",
"Tionghoa", "Dayak", "Melayu", "Bugis",
"Tanah", "Tuhan", "Sungai", "Keselamatan",
"Kwetiau", "Pengkang", "Rendang", "Chai Kwe",
"Tanah Parenean", "Jubata", "Cik Cik Periuk", "Sungai Kapuas",
"Dayak", "Tionghoa", "Melayu", "Bugis"
)
val answer = arrayOf(
"Dayak",
"Pesa'an",
"Melayu",
"Tionghoa",
"Tuhan",
"Rendang",
"Jubata",
"Bugis"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kuis)
supportActionBar?.title = "Kuis"
kuis = findViewById(R.id.kuis)
rg = findViewById(R.id.pilihan)
choiceA = findViewById(R.id.pilihanA)
choiceB = findViewById(R.id.pilihanB)
choiceC = findViewById(R.id.pilihanC)
ChoiceD = findViewById(R.id.pilihanD)
kuis.setText(question[number])
choiceA.setText(option[0])
choiceB.setText(option[1])
choiceC.setText(option[2])
choiceD.setText(option[3])
rg.check(0)
correct = 0
wrong = 0
}
fun next(view: View) {
if (choiceA.isChecked || choiceB.isChecked || choiceC.isChecked || choiceD.isChecked) {
val userAnswer: RadioButton = findViewById(rg.checkedRadioButtonId)
val takeUserAnswer: String = userAnswer.text.toString()
rg.check(0)
if (takeUserAnswer.equals(answer[number])) correct++
else wrong++
number++
if (number< 8) {
kuis.setText(question[number])
choiceA.setText(option[(number * 4) + 0])
choiceB.setText(option[(number * 4) + 1])
choiceC.setText(option[(number * 4) + 2])
choiceD.setText(option[(number * 4) + 3])
} else {
result = correct * 100 / 8
val intent = Intent(this, HasilKuis::class.java)
startActivity(intent)
}
} else {
Toast.makeText(this, "Belum Dijawab", Toast.LENGTH_SHORT).show()
}

Inefficient way would be something like this:
val soal = mutableListOf<String>(...)
val indices = mutableSetOf<Int>()
do {
val randomIndex = Random.nextInt(soal.size)
if (randomIndex !in indices) {
// Update views with their respective data using the randomIndex, e.g. soal[randomIndex]
indices.add(randomIndex)
}
} while (indices.size < 8)
The efficient way would be to make your arrays MutableList<String> and modify their size along the way:
val soal = mutableListOf<String>(...)
var upperBound = soal.lastIndex
do {
val randomIndex = if (upperBound != 0) Random.nextInt(upperBound) else 0
// Update views with their respective data using the randomIndex, e.g. soal.removeAt(randomIndex)
upperBound--
} while (soal.isNotEmpty())

Related

Android/Kotlin: Intent always NULL

I have searched through multiple posts on here which seem to all have the same problem but with different causes. I am getting NULL results from my bundle when calling them from the second activity. I will post more of my code if required;
Here is where i package my bundle on initial activity:
val extras = Bundle()
extras.putString("EXTRA_DIFFICULTY", dif_spinner.getSelectedItem().toString())
extras.putString("EXTRA_CAT", cat_spinner.getSelectedItem().toString())
intent.putExtras(extras)
And when I am in my second activity:
val bundle :Bundle ?=intent.extras
val difficultystring = bundle?.getString("EXTRA_DIFFICULTY")
val catstring = bundle?.getString("EXTRA_CAT")
txtV.text = "Your difficulty level is " + difficultystring + " and your cat is " + catstring
In both cases it return null. The spinners initialise on create so there should always be a value to call, can anyone point me in the right direction please?
FULL CODE (less functions - not causing any issues)
Activity 1
class MainActivity : AppCompatActivity() {
lateinit var btnSTART: Button
lateinit var switchSNOW: Switch
lateinit var imageviewSNOW: ImageView
lateinit var requested_difficulty: String
lateinit var dif_spinner: Spinner
lateinit var cat_spinner: Spinner
var difficulty_array = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dif_spinner = findViewById(R.id.difficulty_spinner)
cat_spinner = findViewById(R.id.cat_spinner)
switchSNOW = findViewById(R.id.snow_switch) as Switch
imageviewSNOW = findViewById(R.id.imageViewSnow) as ImageView
imageviewSNOW.setVisibility(View.INVISIBLE);
switchSNOW.setOnCheckedChangeListener { _, isChecked ->
if(isChecked){
imageviewSNOW.setVisibility(View.VISIBLE);
} else {
imageviewSNOW.setVisibility(View.INVISIBLE);
}
}
btnSTART = findViewById(R.id.buttonSTART) as Button
btnSTART.setOnClickListener{
val intent = Intent(this, Quiz::class.java)
startActivity(intent)
}
// Create an ArrayAdapter using the string array and a default spinner layout
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter.createFromResource(
this,
R.array.difficulty_array,
android.R.layout.simple_spinner_item
).also { adapter ->
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
// Apply the adapter to the spinner
dif_spinner.adapter = adapter
}
ArrayAdapter.createFromResource(
this,
R.array.cat_array,
android.R.layout.simple_spinner_item
).also { adapter ->
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
// Apply the adapter to the spinner
cat_spinner.adapter = adapter
}
val extras = Bundle()
extras.putString("EXTRA_DIFFICULTY", dif_spinner.getSelectedItem().toString())
extras.putString("EXTRA_CAT", cat_spinner.getSelectedItem().toString())
intent.putExtras(extras)
}
}
Activity 2
class Quiz : AppCompatActivity() {
lateinit var txtV: TextView
lateinit var btn1: Button
lateinit var btn2: Button
lateinit var btn3: Button
lateinit var btn4: Button
lateinit var viewQ: TextView
var ans: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_quiz)
btn1 = findViewById(R.id.button1) as Button
btn2 = findViewById(R.id.button2) as Button
btn3 = findViewById(R.id.button3) as Button
btn4 = findViewById(R.id.button4) as Button
viewQ = findViewById(R.id.textview_question)
txtV = findViewById(R.id.textView_info) as TextView
ans = GetQuestion(1, rand(1, 6))
btn1.setOnClickListener{
val theirans: String = btn1.getText().toString() //this will get a string
val TheirAnswer = theirans.toInt() //this will get a no from the string
if(TheirAnswer==ans) {
btn1.setBackgroundResource(R.color.lime_green);
} else {
btn1.setBackgroundResource(R.color.red);
}
next()
};
btn2.setOnClickListener {
val theirans: String = btn2.getText().toString() //this will get a string
val TheirAnswer = theirans.toInt() //this will get a no from the string
if(TheirAnswer==ans) {
btn2.setBackgroundResource(R.color.lime_green);
} else {
btn2.setBackgroundResource(R.color.red);
}
next()
};
btn3.setOnClickListener{
val theirans: String = btn3.getText().toString() //this will get a string
val TheirAnswer = theirans.toInt() //this will get a no from the string
if(TheirAnswer==ans) {
btn3.setBackgroundResource(R.color.lime_green);
} else {
btn3.setBackgroundResource(R.color.red);
}
next()
};
btn4.setOnClickListener{
val theirans: String = btn4.getText().toString() //this will get a string
val TheirAnswer = theirans.toInt() //this will get a no from the string
if(TheirAnswer==ans) {
btn4.setBackgroundResource(R.color.lime_green);
} else {
btn4.setBackgroundResource(R.color.red);
}
next()
};
val bundle :Bundle ?=intent.extras
val difficultystring = bundle?.getString("EXTRA_DIFFICULTY")
val catstring = bundle?.getString("EXTRA_CAT")
txtV.text = "Your difficulty level is " + difficultystring + " and your category is " + catstring
}
Use below answer
val intent = intent
val difficultystring = intent.getStringExtra("EXTRA_DIFFICULTY")
val catstring = intent.getStringExtra("EXTRA_CAT")
txtV.text = "Your difficulty level is " + difficultystring + " and your cat is " + catstring
Question raised by #cutiko provided the answer to my problem. For some reason I added the bundle to the end of my code rather than with my start activity intent.
From activity 1 my code went from:
btnSTART.setOnClickListener{
val intent = Intent(this, Quiz::class.java)
startActivity(intent)
}
&
val extras = Bundle()
extras.putString("EXTRA_DIFFICULTY", dif_spinner.getSelectedItem().toString())
extras.putString("EXTRA_CAT", cat_spinner.getSelectedItem().toString())
intent.putExtras(extras)
to
btnSTART.setOnClickListener{
val intent = Intent(this, Quiz::class.java)
val extras = Bundle()
extras.putString("EXTRA_DIFFICULTY", dif_spinner.getSelectedItem().toString())
extras.putString("EXTRA_CAT", cat_spinner.getSelectedItem().toString())
intent.putExtras(extras)
startActivity(intent)
}

Android Multi-row summation: Request for code shortening

I have a table with fifteen rows. Each row have three columns and a total column. I want to get the total per row, the grand total, and the overall average.
The user may not enter data for all rows, and the user may skip a row.
So the code checks if the user have entered data in one of three fields of each row.
If the row is blank, ignore it.
If some of the fields are filled-up, tell the user to fill up the rest of the row.
If all the fields in a row is filled up, sum all its fields and increment the divider.
I have only pasted the codes for Rows 1 & 2 for brevity, but it shows the gist of what I'm trying to achieve:
The code:
var a1 = 0
var a2 = 0
var total = 0
var divider = 0
// Row 1
if (b1p1.text.isNotEmpty() or b2p1.text.isNotEmpty() or b3p1.text.isNotEmpty()) {
var y = 0
listOf(b1p1, b2p1, b3p1).forEach {
if (it.text.isEmpty()) {
it.error = "Fill up empty fields!"
y = 1
}
}
if (y == 0) {
divider++
listOf(b1p1, b2p1, b3p1).forEach {
a1 += it.text.toString().toInt()
}
total1.text = a1.toString()
total += a1
e2 = 1
} else {
Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
}
}
// Row 2
if (b1p2.text.isNotEmpty() or b2p2.text.isNotEmpty() or b3p2.text.isNotEmpty()) {
var y = 0
listOf(b1p2, b2p2, b3p2).forEach {
if (it.text.isEmpty()) {
it.error = "Fill up empty fields!"
y = 1
}
}
if (y == 0) {
divider++
listOf(b1p2, b2p2, b3p2).forEach {
a2 += it.text.toString().toInt()
}
total2.text = a2.toString()
total += a2
} else {
Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
}
}
if (e2 == 1) {
grandTotalTextView.text = total.toString()
average = total.toDouble()/divider
val decimalFormatter = DecimalFormat("#,###.##")
averageTextView.text = decimalFormatter.format(average).toString()
cyeSingleton.anct3b = decimalFormatter.format(average).toString()
} else {
Toast.makeText(activity, "Error 2", Toast.LENGTH_SHORT).show()
}
The table:
This is the best I could come up with. Should there be no other suggestion, I will settle for this.
Thanks in advance!
**EDIT: Thanks to ** https://stackoverflow.com/users/3736955/jemshit-iskenderov
data class TotalResult(val divider:Int, val allTotal:Int, val showError:Boolean)
private fun calculateTotalResult(allTextViews:List<List<TextView>>, totalTextViews:List<TextView>): TotalResult {
var divider = 0
var allTotal = 0
var showError=false
allTextViews.forEachIndexed{index, rowTextViews->
val rowResult = calculateRowResult(rowTextViews as List<EditText>, totalTextViews[index])
if(!rowResult.ignoreRow){
if(rowResult.allFieldsFilled){
divider+=1
allTotal+=rowResult.rowTotal
}else{
showError = true
}
}
}
Toast.makeText(
activity,
"$divider, $allTotal, $showError", Toast.LENGTH_SHORT)
.show()
return TotalResult(divider, allTotal, showError)
}
data class RowResult(val ignoreRow:Boolean, val allFieldsFilled:Boolean, val rowTotal:Int)
private fun calculateRowResult(rowTextViews:List<EditText>, totalTextView:TextView): RowResult {
val ignore = rowTextViews.filter{it.text.isBlank()}.count() == rowTextViews.size
if(ignore)
return RowResult(true, false, 0)
var emptyFieldCount = 0
var total = 0
rowTextViews.forEach {textView ->
if (textView.text.isEmpty()) {
textView.error = "Fill up empty fields!"
emptyFieldCount +=1
}else{
val fieldValue:Int? = textView.text.toString().toIntOrNull() // or toIntOrElse{0}
if(fieldValue!=null) total+=fieldValue
}
}
if(emptyFieldCount==0)
totalTextView.text = total.toString()
return RowResult(false, emptyFieldCount==0, total)
}
fun main(){
val totalResult = calculateTotalResult(
allTextViews = listOf(
listOf(t11,t12,t13),
listOf(t21,t22,t23)
),
totalTextViews = listOf(totalView1, totalView2)
)
// single Toast error
if(totalResult.showError){
// showToast(error)
}
// use totalResult.divider, totalResult.allTotal
}
data class TotalResult(val divider:Int, val allTotal:Int, val showError:Boolean)
fun calculateTotalResult(allTextViews:List<List<TextView>>, totalTextViews:List<TextView>){
var divider = 0
var allTotal = 0
var showError=false
allTextViews.forEachIndexed{index, rowTextViews->
val rowResult = calculateRowResult(rowTextViews, totalTextViews[index])
if(!rowResult.ignore){
if(rowResult.allFieldsFilled){
divider+=1
allTotal+=rowResult.rowTotal
}else{
showError = true
}
}
}
return TotalResult(divider, allTotal, showError)
}
data class RowResult(val ignoreRow:Boolean, val allFieldsFilled:Boolean, val rowTotal:Int)
fun calculateRowResult(rowTextViews:List<TextView>, totalTextView:TextView): RowResult {
val ignore = rowTextViews.filter{it.isBlank()}.count() == rowTextViews.size
if(ignore)
return RowResult(true, false, 0)
var emptyFieldCount = 0
var total = 0
rowTextViews.forEach {textView ->
if (textView.text.isEmpty()) {
textView.error = "Fill up empty fields!"
emptyFieldCount +=1
}else{
val fieldValue:Int? = textView.text.toString().toIntOrNull() // or toIntOrElse{0}
if(fieldValue!=null) total+=fieldValue
}
}
if(emptyFieldCount==0)
totalTextView.text = total.toString()
return RowResult(false, emptyFieldCount==0, total)
}
Extracted calculateTotalResult() and calculateRowResult() so multiple rows and columns do not need to repeat same code.
calculateRowResult() processes singlet row of TextViews. I had to iterate rowTextViews twice, one to calculate ignore, the other to show error on TextView if not ignore. We don't show Toast Error here yet.
calculateTotalResult() iterates through all rows and gets total result. We show only one Toast Error (if required) after this step.
Code is pseudo-code, not tested.

Function to animate an ImageView in a RecyclerView

To forward my application, i need a function that will rotate an imageView in a recyclerView.
The recyclerView is one of 3 recyclerviews that are already working well, and are clickable through a cardView.
shortvideo there:
https://mega.nz/#!W6AyAYaY!07WG8kr_POYiGsgt0yja6fk8RaclZLw2-MiMFrmEQmk
I created Classes with a few members, which permit to know the state of the objects.
I am newbie in Android programmation, and it was difficult for me to make these recyclerView working well :-)
7 April : i finally succeeded to implement my function
but the result is weird !
can see there :
https://mega.nz/#!DzI2iaiB!VBG9Ex4TZlAsoUYPSRhXXMP4weH-9hXyjbqF1nCRyeA
There is an imageView which is rotating, but this is the left one, not the clicked one, and there is a mix, a swap between pictures.
My question is : are the imageViews clickable and focusable like cardViews ?
if so i can try to make the imageView focusable and clickable (actually the cardView is... )
What about the index is recyclerViews ? isn't it the cardview which is clicked which has the index ? or the left one in the screen ?
I am puzzled :-)
Following: the layout with CardView and imageView; MainActivity where i tried to write the function; and the Adapter for the Top RecyclerView where the function is supposed to
rotate (180 °) the imageView at the index ( index, tag and position )
no change about that xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="#+id/flag_card_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:focusable="true"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/flagcountry"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintDimensionRatio="W,55:100"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="2dp"/>
<TextView
android:id="#+id/flagname"
android:layout_width="6dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="#id/flagcountry"
android:layout_centerVertical="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
under new kt file
package training.geography.triplerecyclerview
import android.provider.Settings.Global.getString
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
class FlagAdapter(val flagcountrylist: List<FlagCard>,
val flagitemClickListener : View.OnClickListener
//val flagitemOnLongClickListener : View.OnLongClickListener
):
RecyclerView.Adapter<FlagAdapter.FlagViewHolder> () {
class FlagViewHolder(flagView: View) : RecyclerView.ViewHolder(flagView) {
val flagcardView = flagView.findViewById<CardView>(R.id.flag_card_view)
val flagcountry = flagView.findViewById<ImageView>(R.id.flagcountry)
val flagname = flagView.findViewById<TextView>(R.id.flagname)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
FlagViewHolder {
val inflater = LayoutInflater.from(parent.context)
val viewItem = inflater.inflate(R.layout.item_flag, parent, false)
return FlagViewHolder(viewItem)
}
override fun onBindViewHolder(flagholder: FlagViewHolder, position: Int) {
//val flagcountry: String = flagcountrylist.FlagCard.flagimage[position]
//var flagimageList: List<String> = flagcountrylist.map { it.flagimage }
var flagsouthList: List<String> = flagcountrylist.map { it.flagsouth }
var iflagsouth = flagsouthList[position]
flagholder.flagname.text = iflagsouth
flagholder.flagcardView.tag = position
flagholder.flagcardView.setOnClickListener(flagitemClickListener)
//flagholder.flagcardView.setOnLongClickListener(itemOnLongClickListener)
when (position){
0 -> flagholder.flagcountry.setImageResource(R.drawable.afgcol)
1 -> flagholder.flagcountry.setImageResource(R.drawable.argsvk)
2 -> flagholder.flagcountry.setImageResource(R.drawable.armche)
3 -> flagholder.flagcountry.setImageResource(R.drawable.auttgo)
4 -> flagholder.flagcountry.setImageResource(R.drawable.azepry)
5 -> flagholder.flagcountry.setImageResource(R.drawable.bhrtur)
6 -> flagholder.flagcountry.setImageResource(R.drawable.bratls)
7 -> flagholder.flagcountry.setImageResource(R.drawable.bwasur)
8 -> flagholder.flagcountry.setImageResource(R.drawable.cafbtn)
9 -> flagholder.flagcountry.setImageResource(R.drawable.critun)
10 -> flagholder.flagcountry.setImageResource(R.drawable.pandza)
11 -> flagholder.flagcountry.setImageResource(R.drawable.persau)
12 -> flagholder.flagcountry.setImageResource(R.drawable.svnago)
13 -> flagholder.flagcountry.setImageResource(R.drawable.sweben)
14 -> flagholder.flagcountry.setImageResource(R.drawable.tcdgbr)
15 -> flagholder.flagcountry.setImageResource(R.drawable.thabol)
16 -> flagholder.flagcountry.setImageResource(R.drawable.tjkdeu)
17 -> flagholder.flagcountry.setImageResource(R.drawable.tkmbel)
18 -> flagholder.flagcountry.setImageResource(R.drawable.tzablz)
19 -> flagholder.flagcountry.setImageResource(R.drawable.ukrcmr)
20 -> flagholder.flagcountry.setImageResource(R.drawable.uryblr)
21 -> flagholder.flagcountry.setImageResource(R.drawable.venbgd)
22 -> flagholder.flagcountry.setImageResource(R.drawable.vnmbfa)
23 -> flagholder.flagcountry.setImageResource(R.drawable.yembih)
24 -> flagholder.flagcountry.setImageResource(R.drawable.zmbchl)
25 -> flagholder.flagcountry.setImageResource(R.drawable.zwealb)
}
//var iflagcard:String = imagelist[position]
//holder.flagcountry.setImageResource(iflagcard)
}
override fun getItemCount(): Int {
return flagcountrylist.size
}
}
---------------------------------------
//under new MainActivity file with function modified
// i don't know what to do with the variable
// flagtempup, i use it to set the string in
// iflagtrigramdown, and i have te warning variable not used...
package training.geography.triplerecyclerview
import android.nfc.Tag
import android.os.Bundle
import android.view.View
import android.view.View.OnClickListener
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_flag.*
data class FlagCard(var flagtrigramup: String, var flagtrigramdown: String,
var flagimage: String, var flagsouth: String, var rotationpossible: Boolean=(true))
data class CountryCard(val countrytrigram: String, val description: String)
data class MapCard(var map_left_up: String,
var map_right_up: String,
var map_left_down: String,
var map_right_down: String,
var maps_img: String,
var mapnorth: String)
class MainActivity : AppCompatActivity(), OnClickListener {
var afg_col = FlagCard("col", "afg", "afgcol", "afg", true)
var arg_svk = FlagCard("arg", "svk", "argsvk", "svk", true)
var arm_che = FlagCard("che", "arm", "armche", "arm", true)
var aut_tgo = FlagCard("tgo", "aut", "auttgo", "aut", true)
var aze_pry = FlagCard("aze", "pry", "azepry", "pry", true)
var bhr_tur = FlagCard("tur", "bhr", "bhrtur", "bhr", true)
var bra_tls = FlagCard("tls", "bra", "bratls", "bra", true)
var bwa_sur = FlagCard("sur", "bwa", "bwasur", "bwa", true)
var caf_btn = FlagCard("btn", "caf", "cafbtn", "caf", true)
var cri_tun = FlagCard("cri", "tun", "critun", "tun", true)
var pan_dza = FlagCard("pan", "dza", "pandza", "dza", true)
var per_sau = FlagCard("per", "sau", "persau", "sau", true)
var svn_ago = FlagCard("svn", "ago", "svnago", "ago", true)
var swe_ben = FlagCard("swe", "ben", "sweben", "ben", true)
var tcd_gbr = FlagCard("tcd", "gbr", "tcdgbr", "gbr", true)
var tha_bol = FlagCard("tha", "bol", "thabol", "bol", true)
var tjk_deu = FlagCard("tjk", "deu", "tjkdeu", "deu", true)
var tkm_bel = FlagCard("tkm", "bel", "tkmbel", "bel", true)
var tza_blz = FlagCard("tza", "blz", "tzablz", "blz", true)
var ukr_cmr = FlagCard("ukr", "cmr", "ukrcmr", "cmr", true)
var ury_blr = FlagCard("ury", "blr", "uryblr", "blr", true)
var ven_bgd = FlagCard("ven", "bgd", "venbgd", "bgd", true)
var vnm_bfa = FlagCard("vnm", "bfa", "vnmbfa", "bfa", true)
var yem_bih = FlagCard("yem", "bih", "yembih", "bih", true)
var zmb_chl = FlagCard("zmb", "chl", "zmbchl", "chl", true)
var zwe_alb = FlagCard("zwe", "alb", "zwealb", "alb", true)
var afg = CountryCard("afg", "afg")
var ago = CountryCard("ago", "ago")
var alb = CountryCard("alb", "alb")
var arg = CountryCard("arg", "arg")
var arm = CountryCard("arm", "arm")
var aut = CountryCard("aut", "aut")
var aze = CountryCard("aze", "aze")
var bel = CountryCard("bel", "bel")
var bfa = CountryCard("bfa", "bfa")
var bhr = CountryCard("bhr", "bhr")
var bih = CountryCard("bih", "bih")
var blz = CountryCard("blz", "blz")
var bol = CountryCard("bol", "bol")
var bra = CountryCard("bra", "bra")
var btn = CountryCard("btn", "btn")
var bwa = CountryCard("bwa", "bwa")
var caf = CountryCard("caf", "caf")
var che = CountryCard("che", "che")
var chl = CountryCard("chl", "chl")
var cmr = CountryCard("cmr", "cmr")
var col = CountryCard("col", "col")
var cri = CountryCard("cri", "cri")
var deu = CountryCard("deu", "deu")
var gbr = CountryCard("gbr", "gbr")
var pan = CountryCard("pan", "pan")
var per = CountryCard("per", "per")
var pry = CountryCard("pry", "pry")
var sau = CountryCard("sau", "sau")
var sur = CountryCard("sur", "sur")
var svk = CountryCard("svk", "svk")
var svn = CountryCard("svn", "svn")
var swe = CountryCard("swe", "swe")
var tcd = CountryCard("tcd", "tcd")
var tgo = CountryCard("tgo", "tgo")
var tha = CountryCard("tha", "tha")
var tjk = CountryCard("tjk", "tjk")
var tkm = CountryCard("tkm", "tkm")
var tls = CountryCard("tls", "tls")
var tun = CountryCard("tun", "tun")
var tur = CountryCard("tur", "tur")
var tza = CountryCard("tza", "tza")
var ukr = CountryCard("ukr", "ukr")
var ury = CountryCard("ury", "ury")
var ven = CountryCard("ven", "ven")
var vnm = CountryCard("vnm", "vnm")
var yem = CountryCard("yem", "yem")
var zmb = CountryCard("zmb", "zmb")
var zwe = CountryCard("zwe", "zwe")
var arm_bol_gbr_ago = MapCard("arm", "bol", "gbr", "ago", "bol", "armbolgbrago")
var aze_bra_aut_ben = MapCard("aze", "bra", "aut", "ben", "bra", "azebraautben")
var bfa_blr_col_bgd = MapCard("bfa", "blr", "col", "bgd", "blr", "bfablrcolbgd")
var bwa_bel_bhr_chl = MapCard("bwa", "bel", "bhr", "chl", "bel", "bwabelbhrchl")
var caf_afg_alb_arg = MapCard("caf", "afg", "alb", "arg", "afg", "cafafgalbarg")
var che_tkm_tur_sur = MapCard("che", "tkm", "tur", "sur", "tkm", "chetkmtursur")
var cri_cmr_btn_bih = MapCard("cri", "cmr", "btn", "bih", "cmr", "cricmrbtnbih")
var sau_blz_deu_dza = MapCard("sau", "blz", "deu", "dza", "blz", "saublzdeudza")
var svn_tha_tcd_pry = MapCard("svn", "tha", "tcd", "pry", "tha", "svnthatcdpry")
var swe_tls_tgo_per = MapCard("swe", "tls", "tgo", "per", "tls", "swetlstgoper")
var tjk_pan_svk_tza = MapCard("tjk", "pan", "svk", "tza", "pan", "tjkpansvktza")
var ven_zwl_yem_ukr = MapCard("ven", "zwl", "yem", "ukr", "zwl", "venzwlyemukr")
var zmb_tur_ury_vnm = MapCard("zmb", "tur", "ury", "vnm", "tur", "zmbtururyvnm")
var flagcountrylist = listOf<FlagCard>(
afg_col,
arg_svk,
arm_che,
aut_tgo,
aze_pry,
bhr_tur,
bra_tls,
bwa_sur,
caf_btn,
cri_tun,
pan_dza,
per_sau,
svn_ago,
swe_ben,
tcd_gbr,
tha_bol,
tjk_deu,
tkm_bel,
tza_blz,
ukr_cmr,
ury_blr,
ven_bgd,
vnm_bfa,
yem_bih,
zmb_chl,
zwe_alb
)
val flagadapter = FlagAdapter(flagcountrylist, this)
var countryList = listOf<CountryCard>(
afg,
ago,
alb,
arg,
arm,
aut,
aze,
bel,
bfa,
bhr,
bih,
blz,
blz,
bol,
bra,
btn,
bwa,
caf,
che,
chl,
cmr,
col,
cri,
deu,
gbr,
pan,
per,
pry,
sau,
sur,
svk,
svn,
swe,
tcd,
tgo,
tha,
tjk,
tkm,
tls,
tun,
tur,
tza,
ukr,
ury,
ven,
vnm,
yem,
zmb,
zwe
)
val countryadapter = CountryAdapter(countryList)
var mapcountrylist = listOf<MapCard>(
arm_bol_gbr_ago,
aze_bra_aut_ben,
bfa_blr_col_bgd,
bwa_bel_bhr_chl,
caf_afg_alb_arg,
che_tkm_tur_sur,
cri_cmr_btn_bih,
sau_blz_deu_dza,
svn_tha_tcd_pry,
swe_tls_tgo_per,
tjk_pan_svk_tza,
ven_zwl_yem_ukr,
zmb_tur_ury_vnm
)
val mapadapter = MapAdapter(mapcountrylist)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val flagsrecyclerView = findViewById<RecyclerView>(R.id.flagsRecyclerView)
flagsrecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
flagsrecyclerView.adapter = flagadapter
val countryrecyclerView = findViewById<RecyclerView>(R.id.countriesRecyclerView)
countryrecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
countryrecyclerView.adapter = countryadapter
val maprecyclerView = findViewById<RecyclerView>(R.id.mapsRecyclerView)
maprecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
maprecyclerView.adapter = mapadapter
}
fun rotateFlagCard (flagCard: FlagCard, position: Int) : FlagCard {
var flagtrigramuplist: List<String> = flagcountrylist.map{it.flagtrigramup }
var iflagtrigramup : String = flagtrigramuplist[position]
var flagimagelist = flagcountrylist.map{it.flagimage}
var iflagimage = flagimagelist[position]
var flagsouthlist = flagcountrylist.map { it.flagsouth }
var iflagsouth = flagsouthlist[position]
var rotationpossiblelist : List<Boolean> = flagcountrylist.map{ it.rotationpossible }
var irotationpossible = rotationpossiblelist[position]
var iflagimageView = findViewById<ImageView>(R.id.flagcountry)
when (position) {
0 -> iflagimageView.setImageResource(R.drawable.afgcol)
1 -> iflagimageView.setImageResource(R.drawable.argsvk)
2 -> iflagimageView.setImageResource(R.drawable.armche)
3 -> iflagimageView.setImageResource(R.drawable.auttgo)
4 -> iflagimageView.setImageResource(R.drawable.azepry)
5 -> iflagimageView.setImageResource(R.drawable.bhrtur)
6 -> iflagimageView.setImageResource(R.drawable.bratls)
7 -> iflagimageView.setImageResource(R.drawable.bwasur)
8 -> iflagimageView.setImageResource(R.drawable.cafbtn)
9 -> iflagimageView.setImageResource(R.drawable.critun)
10 -> iflagimageView.setImageResource(R.drawable.pandza)
11 -> iflagimageView.setImageResource(R.drawable.persau)
12 -> iflagimageView.setImageResource(R.drawable.svnago)
13 -> iflagimageView.setImageResource(R.drawable.sweben)
14 -> iflagimageView.setImageResource(R.drawable.tcdgbr)
15 -> iflagimageView.setImageResource(R.drawable.thabol)
16 -> iflagimageView.setImageResource(R.drawable.tjkdeu)
17 -> iflagimageView.setImageResource(R.drawable.tkmbel)
18 -> iflagimageView.setImageResource(R.drawable.tzablz)
19 -> iflagimageView.setImageResource(R.drawable.ukrcmr)
20 -> iflagimageView.setImageResource(R.drawable.uryblr)
21 -> iflagimageView.setImageResource(R.drawable.venbgd)
22 -> iflagimageView.setImageResource(R.drawable.vnmbfa)
23 -> iflagimageView.setImageResource(R.drawable.yembih)
24 -> iflagimageView.setImageResource(R.drawable.zmbchl)
25 -> iflagimageView.setImageResource(R.drawable.zwealb)
else -> throw AssertionError()
}
if (irotationpossible)
{
iflagimageView.animate().apply {
rotationBy(180f)
duration = 1000L
start()
// permutation of values north south
var flagtrigramdownlist :List<String> = flagcountrylist.map{it.flagtrigramdown}
var iflagtrigramdown : String = flagtrigramdownlist[position]
var flagtempup: String = iflagtrigramup
var flagtempdown: String = iflagtrigramdown
iflagtrigramup = iflagsouth
//flagtempdown = flagtempup
iflagtrigramdown = flagtempup
var iflagCard = FlagCard( iflagtrigramup, iflagtrigramdown, iflagimage, iflagsouth, irotationpossible )
return iflagCard
}
} else {
return flagCard
//Toast.makeText(this, "flag already matched country", Toast.LENGTH_LONG).show()
}
}
override fun onClick(flagcardView: View) {
if (flagcardView.tag != null) {
val index = flagcardView.tag as Int
var flagsouthList: List<String> = flagcountrylist.map{it.flagsouth }
val flags = flagsouthList[index]
Toast.makeText(this, "country : ${flags}", Toast.LENGTH_LONG).show()
var flagcard:FlagCard = flagcountrylist[index]
rotateFlagCard (flagcard, index)
}
}
}
It looks like nobody is interested by what is possible to do with RecyclerViews...
I still have the problem that when an imageView is clicked, this is the one at left which is rotating ! i can't understand what happens, examination in debugger shows the variables are ok, the index is position and do not change...
I tried to apply rotate function to the cardView, same result !
I modified the code in the function and replace the flagCard by iflagCard if rotation was done (because two flags, one up, one down, and of course the FlagCard is different... )
Here the new code :
if (irotationpossible)
{
iflagcardView.animate().apply {
rotationBy(180f)
duration = 1000L
start()
// permutation of values north south
var flagtrigramdownlist :List<String> = flagcountrylist.map{it.flagtrigramdown}
var iflagtrigramdown : String = flagtrigramdownlist[position]
var flagtempup: String = iflagtrigramup
var flagtempdown: String = iflagtrigramdown
iflagtrigramup = iflagsouth
iflagsouth = flagtempup
iflagtrigramdown = flagtempup
var iflagCard = FlagCard( iflagtrigramup, iflagtrigramdown, iflagimage, iflagsouth, irotationpossible )
//flagcountrylist.toSet(position, iflagCard)
//abstract operator fun set(position: Int, iflagCard: FlagCard): FlagCard
flagcountrylist.removeAt(position)
flagcountrylist.add(position, iflagCard)
return iflagCard
}
} else {
return flagCard
//Toast.makeText(this, "flag already matched country", Toast.LENGTH_LONG).show()
}
my question is now about the set function for mutableListOf in Kotlin :
i tried to use " abstract operator fun set(index: Int, element: E): E "
but couldn't build because of abstract !
Is there any other way than my solution to remove then add at the same index ?
Is there any experimented developper curious about the strange rotation in that app ?
https://www.youtube.com/watch?v=d9o7fttLBxk
Why not the image with right index ?

Get the returned list from firestore based on condition when a value is passed to firestore function

I am trying to return a list from inside firestore function based on if a condition is true.I want to return different lists when different categories are selected.
I tried:
putting the return statement out of firestore function which did not work and returned empty list due to firestore async behaviour.
creating my own callback to wait for Firestore to return the data using interface as I saw in some other questions but in that case how am i supposed to access it as my function has a Int value(i.e.private fun getRandomPeople(num: Int): List<String>)?
What could be the way of returning different lists for different categories based on firestore conditions?
My code(Non Activity class):
class Board// Create new game
(private val context: Context, private val board: GridLayout) {
fun newBoard(size: Int) {
val squares = size * size
val people = getRandomPeople(squares)
createBoard(context, board, size, people)
}
fun createBoard(context: Context, board: GridLayout, size: Int, people: List<String>) {
destroyBoard()
board.columnCount = size
board.rowCount = size
var iterator = 0
for(col in 1..size) {
for (row in 1..size) {
cell = RelativeLayout(context)
val cellSpec = { GridLayout.spec(GridLayout.UNDEFINED, GridLayout.FILL, 1f) }
val params = GridLayout.LayoutParams(cellSpec(), cellSpec())
params.width = 0
cell.layoutParams = params
cell.setBackgroundResource(R.drawable.bordered_rectangle)
cell.gravity = Gravity.CENTER
cell.setPadding(5, 0, 5, 0)
text = TextView(context)
text.text = people[iterator++]
words.add(text.text as String)
text.maxLines = 5
text.setSingleLine(false)
text.gravity = Gravity.CENTER
text.setTextColor(0xFF000000.toInt())
cell.addView(text)
board.addView(cell)
cells.add(GameCell(cell, text, false, row, col) { })
}
}
}
private fun getRandomPeople(num: Int): List<String> {
val mFirestore: FirebaseFirestore=FirebaseFirestore.getInstance()
val mAuth: FirebaseAuth=FirebaseAuth.getInstance()
val currentUser: FirebaseUser=mAuth.currentUser!!
var validIndexes :MutableList<Int>
var chosenIndexes = mutableListOf<Int>()
var randomPeople = mutableListOf<String>()
mFirestore.collection("Names").document(gName).get().addOnSuccessListener(OnSuccessListener<DocumentSnapshot>(){ queryDocumentSnapshot->
var categorySelected:String=""
if (queryDocumentSnapshot.exists()) {
categorySelected= queryDocumentSnapshot.getString("selectedCategory")!!
print("categoryselected is:$categorySelected")
Toast.makeText(context, "Got sel category from gameroom:$categorySelected", Toast.LENGTH_LONG).show()
when(categorySelected){
"CardWords"->{
for (i in 1..num) {
validIndexes=(0..CardWords.squares.lastIndex).toMutableList()
val validIndexIndex = (0..validIndexes.lastIndex).random()
val peopleIndex = validIndexes[validIndexIndex]
chosenIndexes.add(peopleIndex)
val person = CardWords.squares[peopleIndex]
randomPeople.add(person)
validIndexes.remove(peopleIndex)
peopleIndexes = chosenIndexes.toList()
}
}
else->{}
}
}
else {
Toast.makeText(context, "Sel category does not exist", Toast.LENGTH_LONG).show()
}
}).addOnFailureListener(OnFailureListener { e->
val error=e.message
Toast.makeText(context,"Error:"+error, Toast.LENGTH_LONG).show()
})
return randomPeople.toList()
}
}
Activity A:
Board(this, gridLay!!)

How to pick every time new or unique random item from a array list in android?

I need to pick a new item from a list that hasn't been picked already until there are no more.
Here is my code:
private var quizQuestionList: ArrayList<Quiz>
private var pickedItems: ArrayList<Int>
private var random: Random = Random()
private fun pickItem(): Quiz {
var index = random?.nextInt(quizQuestionList!!.size)
if (pickedItems.contains(index)) {
index = random?.nextInt(quizQuestionList!!.size)
pickedItems.add(index)
} else {
pickedItems.add(index)
}
val item = quizQuestionList!!.get(index!!)
return item
}
Please suggest any solution that gives me a new item every time. I used an int list for all previously picked items and check every time when picked new item but I didn't get success.
It isn't obvious what you are looking for, but it looks like you want to show different Quiz question from ArrayList. In condition of, when that question is shown, no more same question will be shown. Here is how you should do, I will give you just the logic you could try it yourself:
import java.util.Random
fun main(args: Array<String>) {
val random = Random()
var randomInt: Int
var pickedInt: MutableSet<Int> = mutableSetOf()
fun rand(from: Int, to: Int): Int{
do{
randomInt = random.nextInt(to - from) + from
}while(pickedInt.contains(randomInt))
pickedInt.add(randomInt)
return randomInt
}
while(pickedInt.size < 9){
var differentNumber = rand(1,11)
println(differentNumber)
}
}
This will print nine different Number. The way I choosing MutableSet is because it will only have unique values, no duplicated value. Hope it helps!
here is code for same::
val arrayList = ArrayList<String>()
arrayList.add("a")
arrayList.add("b")
arrayList.add("c")
arrayList.add("d")
arrayList.add("e")
arrayList.add("f")
arrayList.add("g")
arrayList.add("h")
arrayList.add("i")
arrayList.add("j")
arrayList.add("k")
random = Random()
Low = 0
High = arrayList.size
val generateRandom = findViewById<View>(R.id.generateRandom) as Button
generateRandom.setOnClickListener {
val Result = random.nextInt(High - Low) + Low
Log.v("check", arrayList[Result])
}
Please let me know if need more!!
Try this way
class MainActivity : AppCompatActivity() {
private var arrayList = ArrayList<String>()
private var lastItem = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
for (i in 0..9) {
arrayList.add(i.toString())
}
btnData.setOnClickListener {
Log.e("RANDOM_NUMBER", "" + getRandomItemFromList())
}
}
private fun getRandomItemFromList(): Int {
val randomValue = Random().nextInt(arrayList.size)
return if (randomValue != lastItem) {
lastItem = randomValue
randomValue
} else {
getRandomItemFromList()
}
}
}
I made this extension for the ArrayList class in Kotlin you can use it multiple times in only one line.
fun <T> ArrayList<T>.generateRandomItems(numberOfItems: Int): ArrayList<T> {
val range = if(numberOfItems > this.size){this.size}else{numberOfItems}
val randomItems = ArrayList<T>()
for (i in 0..range) {
var randomItem: T
do {
randomItem = this.random()
} while (randomItems.contains(randomItem))
randomItems.add(randomItem)
}
return randomItems
}
Usage:
val randomUsersList = usersList.generateRandomItems(20)
Note: the usersList is the list that has items to generate random items from.

Categories

Resources