// Create new 6 Pot
val list = mutableListOf<Int>()
val pot = listOf<Pot>(Pot(50), Pot(50), Pot(50), Pot(50), Pot(50), Pot(50))
val linearLayout: LinearLayout = findViewById(R.id.text)
linearLayout.removeAllViews()
// random 6 number from 1 - 50 without duplicate
// Create textview to print out roll result
pot.forEach {
val d = it
val rollResult = d.roll()
list.add(rollResult)
val textView = TextView(this)
textView.append(this.toString())
val param = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
param.marginStart = 10
textView.layoutParams = param
textView.text = rollResult.toString()
linearLayout.addView(textView)
}
I have a code like this, after add rollResult to a list like a temp paper, what should i do to compare next result to previous result which is in the list, if it already present then do another roll, from start to end. Thanks
You can use distinct(),
Ref : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/distinct.html
Example
var list = listOf(1,2,4,5,1,6,8,2,4,3,3,5)
list = list.distinct();
println(list)
First loop for generating roll results
pot.forEach {
val d = it
val rollResult = d.roll()
list.add(rollResult)
}
Second Loop for adding dynamic views
list = list.distinct();
list.forEach {
// Add Views etc
}
Modify as per your needs.
Check whether the element is present in the whole list or not try below code :
if(list.contains(element)){ // do rollout again}
Related
I have a multiple TextInput named input_x where x is a number (e.g input_1, input_2 etc.,). I also have multiple buttons named btn_x where x is a number (e.g btn_1, btn_2 etc.,).
When a btn_x is pressed, I should be able to print the value of the input that has matches the x value (e.g when btn_2 is pressed, value inside input_2 will be printed.)
This is my current attempt that does not work:
fun handleClickButton (view: View) {
with (view as Button) {
var this_btn = view.resources.getResourceEntryName(id)
val id_string = this_btn
val delim = "_"
val arr = id_string.split(delim).toTypedArray()
val id_num = arr[2]
val this_input = "input_" + arr[2].toString()
print(binding.this_input.text)
}
}
Any help would be really really appreciated! I am very new to android development and Kotlin.
Here are the issues that need to fix:
Getting arr[2] while the length of the arr is 2; So this should be arr[1] as arrays are 0-baed indices to avoid ArrayIndexOutOfBoundsException
A text value is invoked on the binding object with this expression binding.this_input and binding requires to have a view id:
Not sure if you can use view bindings for an int as view ID, because this reference name of that view is not registered in the generated binding class.
But at least you can achieve that with findViewById:
Applying that in your code:
fun handleClickButton(view: View) {
with(view as Button) {
val this_btn = view.resources.getResourceEntryName(id)
val id_string = this_btn
val delim = "_"
val arr = id_string.split(delim).toTypedArray()
val id_num = arr[1]
val this_input = "input_" + arr[1]
val id = resources.getIdentifier(this_input, "id", context.packageName)
val input = this#MainActivity.findViewById<EditText>(id)
print(input.text)
}
}
Note: I'm assuming the surrounding activity as MainActivity, you can replace it with your activity as omitting it will get findViewById() called on the button.
I am having a hard time converting the result of map in to its model type
val options = message.options.map {{
it.lastShare = user?.lastShare
it.lastWatch = user?.lastWatch
}}
I want the options to return as type ArrayList<Option> but I can't find anything on the internet. The message.options is of type List. when I do .map it returns List<() -> Unit>.
Please try next code:
val options = message.options.map {
it.lastShare = user?.lastShare
it.lastWatch = user?.lastWatch
it
}
or in your case I think you don't need to use map function, you can simply use forEach to update properties of each object in the list:
message.options.forEach {
it.lastShare = user?.lastShare
it.lastWatch = user?.lastWatch
}
val optionsArrayList: ArrayList<Option> = arrayListOf(*message.options.toTypedArray())
* - is a spread operator.
Or simpler way to create an ArrayList is just use its constructor:
val optionsArrayList: ArrayList<Option> = ArrayList(message.options)
Just write
val options = message.options.map {{
it.lastShare = user?.lastShare
it.lastWatch = user?.lastWatch
}}.toMutableList()
I have a for loop that creates a cardView for every time it loops, then it uses setOnClickListener for every view with different extras , the problem is only the last loop parameters is being set to every created card, here is my code :
for (finalItem1 in finalList1) {
thePoints.clear()
theSteps.clear()
theIcons.clear()
val step1 =
"${getString(R.string.from_your_location)} \n ${getString(R.string.move_to)} \n $theStartStation"
theSteps.add(step1)
theIcons.add("ic_walk")
thePoints.add(stationData[theStartStation]?.latitude.toString())
thePoints.add(stationData[theStartStation]?.longitude.toString())
val step2 =
"${getString(R.string.from)} : $theStartStation \n ${getString(R.string.take)} : ${finalItem1.child("transportation_type").value} \n ${finalItem1.child("notes").value} \n ${finalItem1.child("price").value} EGP \n ${getString(R.string.to)} : $theEndStation"
theSteps.add(step2)
theIcons.add("ic_bus")
thePoints.add(stationData[theEndStation]?.latitude.toString())
thePoints.add(stationData[theEndStation]?.longitude.toString())
val cardView = CardView(this)
val cardLinearLayout = LinearLayout(this)
cardLinearLayout.orientation = LinearLayout.VERTICAL
val params = RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
params.setMargins(16, 16, 16, 16)
cardView.radius = 15f
cardView.setCardBackgroundColor(Color.parseColor("#64b0e3"))
cardView.setContentPadding(36, 36, 36, 36)
cardView.layoutParams = params
cardView.cardElevation = 30f
val quote = TextView(this)
quote.text = "${getString(R.string.from)} $theStartStation \n ${finalItem1.child("notes").value} \n ${finalItem1.child("price").value} EGP"
cardLinearLayout.addView(quote)
cardView.addView(cardLinearLayout)
optionsLayout.addView(cardView)
cardView.setOnClickListener {
val tripIntent =
Intent(this, NavigationActivity::class.java)
tripIntent.putStringArrayListExtra("theSteps",
theSteps as java.util.ArrayList<String>?
)
tripIntent.putStringArrayListExtra("theIcons",
theIcons as java.util.ArrayList<String>?
)
tripIntent.putStringArrayListExtra("thePoints",
thePoints as java.util.ArrayList<String>?
)
tripIntent.putExtra("fromLat", fromLocation.latitude)
tripIntent.putExtra("fromLon", fromLocation.longitude)
tripIntent.putExtra("toLat", toLocation.latitude)
tripIntent.putExtra("toLon", toLocation.longitude)
startActivity(tripIntent)
}
the problem lies here :
val cardView = CardView(this)
as it created the same listener for every card cardView.setOnClickListener
Every listener instance references theSteps, theIcons and theIcons objects which are declared outside the loop. You clear these lists and then add items to them in every loop iteration, so only values from last iteration are actually used. Just declare these lists inside a loop.
How to make list of random numbers and use it to set image from array?
val randomValues = List(15) { Random.nextInt(0, 5) }
var array = intArrayOf(R.drawable.cat1,R.drawable.cat2,R.drawable.cat3,R.drawable.cat4,R.drawable.cat5)
imageView.setImageResource(array[randomValues])
I'm getting Type mismatch on randomValues in imageView.setImageResource(array[randomValues]). Required: Int and Found: List <int>.
Edited
val randomValues = List(15) { Random.nextInt(0, 5) }
var array = intArrayOf(R.drawable.cat1,R.drawable.cat2,R.drawable.cat3,R.drawable.cat4,R.drawable.cat5)
imageView.setOnClickListener {
randomValues
.map { array[it] }
.forEach { imageView.setImageResource(it) }
}
If you want to select a new random image at each click you just need to do:
val array = intArrayOf(R.drawable.cat1, R.drawable.cat2, R.drawable.cat3, R.drawable.cat4, R.drawable.cat5)
imageView.setOnClickListener {
imageView.setImageResource(array.random())
}
If you absolutely need to use a predefined list of random values (what's the point?), then you need to track the last index you used. Something like:
// in your class
var lastIndex = 0
val randomValues = List(15) { Random.nextInt(0, 5) }
// setting the listener
val array = intArrayOf(R.drawable.cat1, R.drawable.cat2, R.drawable.cat3, R.drawable.cat4, R.drawable.cat5)
imageView.setOnClickListener {
imageView.setImageResource(array[randomValues[lastIndex]])
lastIndex = (lastIndex + 1) % randomValues.size
}
If you'd like to select simply a random element from the array, you can use the Array.random() method which just returns a random element from the array:
var array = intArrayOf(R.drawable.cat1,R.drawable.cat2,R.drawable.cat3,R.drawable.cat4,R.drawable.cat5)
imageView.setImageResource(array.random())
Edit
If you want to select a list of resources based on a randomly generated list of indices, you can achieve this by transforming every index into the right resource. Then you can perform your action on every selected item using the forEach method:
var array = intArrayOf(R.drawable.cat1,R.drawable.cat2,R.drawable.cat3,R.drawable.cat4,R.drawable.cat5)
val randomValues = List(15) { Random.nextInt(0, 5) }
randomValues
.map { array[it] }
.forEach { imageView.setImageResource(it) }
Basically your approach failed because you tried to use the entire randomValues list as a single index value. Instead you should iterate over the list in one way or another and select the resource for each randomly generated number.
I try to manage text in PieChart of MPAndroidChart. But when my text is difficult situation like True = 2, False = 3 , Not = 95, in this situation my pie chart layout is very bad.
Here is my code :-
fun setupPieChartView() {
mPie = findViewById(R.id.piechart)
mPie?.setUsePercentValues(true)
val desc: Description = Description()
desc.text = "PieChart"
mPie?.description = desc
val legend: Legend? = mPie?.legend
legend?.horizontalAlignment = Legend.LegendHorizontalAlignment.LEFT
val value = Arrays.asList(trueAns.toFloat(), wrongAns.toFloat(), noAns.toFloat())
val label = Arrays.asList("True", "false", "Not")
val entry = ArrayList<PieEntry>()
for (i in value.indices) {
entry.add(PieEntry(value.get(i), label.get(i)))
}
val dataSet = PieDataSet(entry, "Result")
dataSet.setColors(Color.GREEN, Color.RED, Color.GRAY);
dataSet.setDrawValues(true)
val pieData = PieData(dataSet)
pieData.setValueFormatter(PercentFormatter())
pieData.setValueTextSize(10f)
pieData.setValueTextColor(Color.WHITE)
mPie?.data = pieData
}
Result is like that :-
here in my Pie-Chart data is not set in good format . Help me for this
You need this line, so your labels will be outside graph:
dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
And value will be outside . You can also control position, line length and coloring like this:
pieData.setValueTextColor(Color.BLACK);
dataSet.setValueLinePart1OffsetPercentage(10.f);
dataSet.setValueLinePart1Length(0.43f);
dataSet.setValueLinePart2Length(.1f);
dataSet.setValueTextColor(Color.BLACK);
dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
mPie.setEntryLabelColor(Color.BLUE);
Here is result: