Create list/array of Textviews to change .text via index - android

So I was hoping to make a list/array of textviews so that I can iterate a loop and set the .text value of the TextViews as I go. Otherwise I would have to set the values in the code statically which would be a whole lot messier and potentially not even feasible for my needs.
So in the code below the idea would be to iterate the loop and when the correct value is confirmed that [index] would then set the corresponding
var refillToken : Double = (0).toDouble()
var tweetStored : BooleanArray = BooleanArray(20)
var tweetActive : BooleanArray = BooleanArray(20)
var userID: MutableList<String> = mutableListOf("")
var textViewToken = 0
while (refillToken > 0) {
var token: Int = 0
while (token < (tweetStored.size)) {
if (tweetStored[token] == true) {
tweetActive[token] = true
textView[textViewToken].text = userID[token]
textViewToken++
refillToken--
token++
if (refillToken < 0) {
break
}
}
}
}
}
I know my loop is probably messy by sane people standards but it makes sense to me and (hopefully) isn't the issue at play. Have found a few articles or ideas searching for the past two hours but they're either 10 years old (and I think deprecated), for java or don't work for whatever reason.

You need to get a value and then add it to the textview and change this value after every action on the page.
Use variable assignment for this task

Related

How do you call a variable created earlier in a when in kotlin?

I'm trying to list the first 100 of a shuffled list. I'm telling it to shuffle if the list is at 0 and then increment. I then am trying to call that list in another section of the when but it's not working. How can I accomplish this?
when (countF) {
0 -> {
//shuffle at 0
val randomChaos = chaosList.asSequence().shuffled().take(chaosList.count()).toList()
cResult.text = randomChaos.elementAt(countF) + countF + "\n\n\n\n\n\n\n\n" + this.cResult.text
countF++
}
1-99 -> {
//show 1-99
cResult.text = randomChaos.elementAt(countF) + countF + "\n\n\n\n\n\n\n\n" + this.cResult.text
countF++
}
100 -> countF = 0
You would need to create the val randomChaos before the when enclosure for it to be available in the scope of multiple branches of the when statement.
That said, the way you're getting a random element is very convoluted. take(chaosList.count()) is completely redundant. And since you don't use multiple sequence operators, creating a sequence is also redundant. Finally, you are only pulling a single item from the random list, so it's unnecessary to create a shuffled list in the first place. Using elementAt() on a shuffled list is no different than picking any element out of that shuffled list, or simply picking a random item out of a list that isn't shuffled at all.
Also, the first two branches of your when statement currently would produce exactly the same results so they can be merged.
Based on what you described, I'm guessing you had this when statement inside a loop that tries to run it 100 times so you can list all the items. For that to work, you would need to shuffle the list one time outside the loop, and then you could iterate its elements in the loop.
However, there are functions that can make it easier to do what you're suggesting. Here's an example:
val randomChaos = chaosList.shuffled()
cResult.text = randomChaos.asSequence()
.take(100)
.withIndex()
.joinToString("\n") { (i, value) ->
"$value-$i"
}
In this case, using a Sequence helps avoid creating an intermediate list to hold the first 100 values.
var randomChaos = chaosList.shuffled()
fun cShuf() { randomChaos = chaosList.shuffled() }
cRoll.setOnClickListener() {
cResult.movementMethod = ScrollingMovementMethod()
if (countF < 1) { cShuf() }
cResult.text = randomChaos.elementAt(countF) + "\n\n\n\n\n\n\n\n" + this.cResult.text
countF++
if (countF > 100) countF = 0
}
I have figured out how to use a function to generate a new shuffe of the list once I've hit > 100 shown.
My issue with making it a function was I was trying to use val variable in the function but the variable already existed so I didn't need to use val, just the name of the variable.

kotlin - Problem with my if statement and operator

This is my goal : user click on minus button the amount decrease by one and there is a if statement to not allow the amount go lower than 0 .
This is my Code :
var number = 0
view.text_amount.visibility = View.GONE
view.plus_btn.setOnClickListener {
if (number == 5) {
Toast.makeText(
requireContext(),
"Limit in order",
Toast.LENGTH_SHORT
).show()
} else {
view.text_amount.visibility = View.VISIBLE
number++
view.text_amount.text = number.toString()
}
}
view.minus_btn.setOnClickListener {
if (number <= 0) {
view.text_amount.visibility = View.GONE
} else {
number--
view.text_amount.text = number.toString()
}
}
there is problem with code : I don't want the amount be visible after getting to 0 . it's better experience when the amount is equal to 0 not be visible .
I think it has a simple solution but I can't see it .
do you have any idea ?
Your code works fine! If you want to make it simpler, there's a bit of repeated logic you could condense into one function that handles the situations:
fun adjustValue(amount: Int) {
val adjusted = number + amount
if (adjusted > 5) // show Toast
number = adjusted.coerceIn(0, 5)
view.text_amount.text = number.toString()
view.text_amount.visibility = if (number == 0) View.GONE else View.VISIBLE
}
view.minus_btn.setOnClickListener { adjustValue(-1) }
view.plus_btn.setOnClickListener { adjustValue(1) }
basically the idea is you work out the new value (I'm using a temporary variable so we never set number to an invalid value) and show whatever warnings you need to. Then the coerceIn line makes sure we lock it within the valid range of allowed values.
You could do if/else checks and only set the new value if it's a valid one, but sometimes it's simpler and shorter to just set things and then worry about the edge cases, so this is just an example of that!
Same thing for the TextView bit - it's easier to just set the value whatever it is, and then set whether it should be displayed or not. You could use if/else branches to look at the value and decide whether to set the text or not... but why make your life hard? We know the value's in the valid 0 to 5 range, we can hide it if it's 0 and show it otherwise... easy!
You could make the function take a Boolean instead, like plus: Boolean and then go val adjusted = number + if (plus) 1 else -1, but making it an Int means you could easily add a +10 button or whatever without adding any more code or any more validation logic, and it's not any more complicated to pass in -1 instead of false (arguably it's clearer!)
that's probably more than you were asking for but hopefully it's useful. If nothing else, the "just set the text and the visibility every time" approach is good and neat
Decrease the value of text_amount only if it contains a value greater than 0 and after that check again its value and if it is 0 then hide it:
view.minus_btn.setOnClickListener {
if (number > 0) {
number--
view.text_amount.text = number.toString()
if (number == 0) view.text_amount.visibility = View.GONE
}
}

removeAt removes elements in passed ArrayList too

I've never saw this
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun eraseOldLocations() {
val a: ArrayList<Ub> =myUbs
val minTime: Long = (now- tenDaysago)
val z = misUbs.size
for(i in 0 until z){
if( myUbs[i].time <minTime) {
a.removeAt(i)
}
}
myUbs = a
}
each time the condition is fulfilled, the element in the position i of a is removed ... BUT also from the myUbs !!! myUbs is a public object, so as the loop continues, appears an error because the variable i exceeds the size of myUbs ...
The function eraseOldLocations() must delete elements with date older than ten days ago. Why is this happening?
Do a shallow copy of myUbs, so that references of list will differ and changes won't reflect to each other:
val a: MutableList<Ub> = myUbs.toMutableList()
MutableList is essentially the same, but if you want ArrayList explicitly (althrough not recommended in Kotlin) you can call ArrayList constructor to delegate to the Collection specified. That essentially does the shallow copy as well:
val a: ArrayList<Ub> = ArrayList(myUbs)

When I edit a list item at a specific index, it affect a similar item in the same list

Found the answer -> dataclass copy with field ArrayList - change the ArrayList of the copied class changes the original
I have this wired bug. I have an array list of size 3. The third item is a duplicate of the second item in the list. I differentiate them based on their position on the list. The problem is that when I do a for loop to change the properties of the item at index 1 the item at index 2 reflects the same change.
What I've tried so far. ...
I have confirmed that the list is being changed at only one spot in the app.
Added more fields to differentiate the duplicate items.
Set if statements to make sure that I am only changing the specific item.
What I think the solution is.
My assumption is that since the items at index 1 & 2 have a coupled relationship since they are duplicates of each other. (even with differentiating factors) I don't know what this relationship is.
My code snippet.
private fun testing(selectedNormalModifier: ToppingModel) {
var modIndex = -1
selectedNormalModifier.parentPosition = selectedModifierPosition
selectedNormalModifier.localToppingName = modifierGroupModel!!.itemModifierGroups[selectedModifierPosition].itemLocalTitle.toString()
val itemToEdit = modifierGroupModel!!.itemModifierGroups[selectedModifierPosition]
for (i in itemToEdit.modifierGroups.modifiers.indices) {
val mod = itemToEdit.modifierGroups.modifiers[i]
if (mod.title == selectedNormalModifier.toppingName) {
modIndex = i
}
}
itemToEdit.modifierGroups.modifiers[modIndex].isItemSelected = true
mSelectedNormalModifiers.add(selectedNormalModifier)
Log.e(TAG, "how many times did we get here $modifierGroupModel")
}
As you can see I am being very specific on the item that I want to edit. Regardless of this, the item at index 2 also gets edited and vice versa.
This is how I duplicate the items
for (i in modifierGroupModel!!.itemModifierGroups.indices) {
val item = modifierGroupModel!!.itemModifierGroups[i]
// only do this if the display count is greater than one
if (item.modifierGroups.displayCount.toInt() > 1) {
for(i in 0 until item.modifierGroups.displayCount.toInt()){
val localIndex = i + 1
item.itemIndex = localIndex
item.itemLocalTitle = getNumberOfName(localIndex) + " " + item.modifierGroups.modifierGroupTitle
tempItemModifierGroupModel.add(if (i > 0) item.copy() else item)
}
} else {
item.itemIndex = i
tempItemModifierGroupModel.add(item)
}
}
val newModidiferGroupModel = ModifierGroupsModel(
itemID = modifierGroupModel!!.itemID,
itemName = modifierGroupModel!!.itemName,
itemModifierGroups = ArrayList(tempItemModifierGroupModel.toMutableList())
)
modifierGroupModel = newModidiferGroupModel
The JSON object looks like this
"item" {
"nested list"[
"isSelected": "false"
]
},
"item" {
"nested list"[
"isSelected": "false" // when i change this to true
]
},
"item" {
"nested list"[
"isSelected": "false" // this one changes as well
]
}
]```
I'm guessing because you didn't show your Item data class but it looks like you are not editing the item in your list, but rather some indirectly referenced object. See this line:
itemToEdit.modifierGroups.modifiers[modIndex].isItemSelected = true
itemToEdit is not getting modified. Some indirectly referenced object in a collection called modifiers is what you're modifying.
When you copy an Item, it only copies all the property values. For a non-primitive property, the value is a reference to specific instance of a class. It does not perform a "deep copy". So your items at index 1 and 2 are different objects, but they reference the same instance of whatever is in the modifierGroups property.
I found the answer. ---> this other Stack Overflow question answered it. dataclass copy with field ArrayList - change the ArrayList of the copied class changes the original
The user #Andrey_yog

Is Android java getResource.getIdentfier exist in IOS Swift?

My application has so many data. So There are so many textfield. Therefore I want to manage textView in iOS swift in the same way.
area1Layer = new TextView[25];
for(int k = 0; k < layer1; k++){// 층수 SET
area1Layer[k] = (TextView)findViewById(getResources().getIdentifier("layer"+(k+1),"id","kr.soen.areacard"));
area1Layer[k].setText(Integer.toString(k + 1) + "0" +ho1);
}
I assume that you want to identify the respective UITextField/UITextView seperately. This can be done by assigning different tags to the respective textfields/textviews.
let textField1: UITextField = UITextField()
textField1.tag = 1
let textField2: UITextField = UITextField()
textField2.tag = 2
and in the UITextFieldDelegate method,
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField.tag == 1 {
//Type your code here
}
if textField.tag == 2 {
//Type your code here
}
}
Also you could assign outlets to each textfield/textview, and use the outlets to check.
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
and in the UITextFieldDelegate method,
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == textField1 {
//Type your code here
}
if textField == textField2 {
//Type your code here
}
}
The same can be done in the case of UITextView as well.
I believe that you want to identify each UITextField or UITextView separately and accordingly manipulate them. You can do it in the following way:
let textView1: UITextView = UITextView()
textView1.tag = 1
let textView2: UITextView = UITextView()
textView2.tag = 2
self.view.addSubview(textView1)
self.view.addSubview(textView2)
For identifying between different view objects, you can use .tag property in iOS by setting .tag in the above way.
To get different UITextView added to the self.view as a subView in swift, you can do the following:
if let textViewObject: AnyObject = self.view.viewWithTag(2) {
// first check is to identify if there is a given view with the tag
if let textView: UITextView = textViewObject as? UITextView {
}
}
The main difference is iOS uses an number based tag while Android uses a text key. You can accomplish the same thing with both. In iOS store all your labels in a collection and modify per tag. The collection type and syntax specifics for setting the tag depend on the way you wright your views.
After setting the tag via interface builder or view.tag = myTag; you can do something like:
for (int x=0; x<strings.count; x++){
UITextView *view = [self.view viewWithTag:x];
view.text = strings[x];
}

Categories

Resources