I want to update the list items' values in the onTap method to true and false and vice versa to change some widgets according to the item's value if it is true or false,
so, is it okay to do something like this?
I mean, is it okay to copy a list inside onTap or it is not a good practice for the memory.
onTap: () {
List<bool> copyItems = [...items];
copyItems[ind] = !copyItems[ind];
ref.read(openFaqAnsRef.notifier).newList = copyItems;
},
I am not entirely sure what you mean, but:
Would it not be simpler to add a parameter to the copyItems that switches that value?
Besides, copying all of the items of a list can be devastating to the performance of your app. Imagine You have thousands/hundreds of items and someone presses that button 2/3/4 times in a row.
Related
I wonder if someone can help me with something that’s driving me up the wall.
I’m very new to flutter and the dart language. Working on a basic personal project as I progress through a Udemy course.
It’s called ‘Bushy Bingo’ – The below is the UI (set aside the layout issues for now)
What I want is for the order of the animals to shuffle when the user clicks the shuffle button. So you get a randomized game each time.
The animals are all custom widgets I’ve created which sit within a ‘Table’ widget, 4 Table Rows, 4 children a piece to create the 4 x 4 grid.
My thinking is that I need to
Assign a ‘positionNumber’ value as an into to each cell of the
grid
Create an ‘animalIndex’ map containing my 16 animals
Write a for loop function, which creates a tableOrder from
scratch on the following logic..
A - For 16 times...
B - Generate a random number between zero and the length of my animalIndex
C - Take the corresponding entry from my animalIndex and add it as a new entry to my tableOrder list
D - Remove the entry from the animalIndex
Assuming that's reasonable logic, i cannot get it to work with dart. Please see the below screenshot to see the issue
If anyone could let me know where I'm going wrong it would be massively appreciated. Maybe my whole approach is wrong. (I've been wrong before ;))
EDIT: I'm really sorry, I didnt mean to step on any toes. You probably put alot of work into what you have already. Your approach could be used obviously, but its a bit over the top for what you wanted to achieve. That's how I came to my answer. If that is not what you are looking for then I hope someone else can help you with the generation of your numbers etc..
I dont have enough reputation yet to comment, so I'm doing it like this. The best way would be to make an animal class and build a list from there.
import 'package:flutter/material.dart';
class Animal {
String name;
Image animalImage;
Animal({this.name, this.animalImage});
}
Then use that to make a list:
List getAnimals() {
return [
Animal(
name: "duck",
animalImage: Image.network('https://picsum.photos/250?image=9'),
),
Animal(
name: "elephant",
animalImage: Image.network('https://picsum.photos/250?image=9'),
),
];
}
Once you have that you can put that in your listviewBuilder. After they press the button you can make a function that takes that list and shuffles it:
example: shuffle docs
example: other shuffle stuff
This way you can always add or remove animals. With the class you can add or remove extra data. And since it's a list it will have its own index id's so you can order it, shuffle it, do whatever you want.
ListviewBuilder example. There are ways to make a gridviewbuilder so that's covered too. You can style the widget anyway you want. Gridview example
ListView.builder(
itemCount: getAnimals().length,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
var _data = getAnimals()[index];
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.red,
child: ListTile(
title: Text(_data.name),
),
),
);
})
struct ContentView: View {
#State private var favoriteColor = 0
var body: some View {
VStack {
Picker(selection: $favoriteColor, label: Text("What is your favorite color?")) {
Text("Red").tag(0)
Text("Green").tag(1)
Text("Blue").tag(2)
}.pickerStyle(SegmentedPickerStyle())
Text("Value: \(favoriteColor)")
}
}
}
You are already nearly there!
First, you make a variable called favoriteColor. You intend to use this variable to get the value from the Picker, aren't you?
Then, you pass that variable to the Picker. Not just as a variable, but as a Binding, with the $ sign in front of it. This will make sure that your variable always stays in sync with the Picker. Briefly said, what Binding does, is that there's actually only one variable, which is shared by your View and the Picker. If you want to know more about this, I believe that there are hundreds of tutorials on this on the internet, so it would not really make sense if I would explain it here yet another time!
So what will happen, is that the Picker updates your variable when a selection is made. But what value will it give your variable for which option?
Well, that's the value you specified in those .tag(...)s. So when the user selects "Red", favoriteColor gets a value of 0, for "Green" it gets 1, for "Blue" it gets 2.
What about updating the UI when the selection changes? Well, SwiftUI manages this automatically -- this is one of the best things of SwiftUI!
But one more thing. When you use the value in a Text like you are doing, you will see something like "Value: 1" at runtime. It would be nice if we could display the name of the color, isn't it?
There's a lot of ways to do this, but one would be to replace Text("Value: \(favoriteColor)") with:
Text("Favorite Color: \(["Red", "Green, "Blue"][favoriteColor])")
What this does, is that it creates an array and takes the value out of it that corresponds with the index of the selected color. So when favoriteColor is 0, the first element of the array is taken , which is "Red".
Hope this is helpful for you!!
Let's say there is a function to determine if a button should be visible.
fun isButtonVisible(fitlers: List<Filters>, results: List<Shop>, isLoading: Boolean) {
return fitlers.isNotEmpty() && results.isEmpty() && !isLoading
}
Now I would like to test this function using PBT like:
"the button should be visible if filters is not empty and results is empty and is not loading" {
forAll { filters: List<Filters>, results: List<Shop>, isLoading: Boolean ->
val actual = isButtonVisible(filters, results, isLoading)
// Here reimplement the logic
val expected = filters.isNotEmpty() && results.isEmpty() && !isLoading
assertThat(actual).isEqual(expected)
}
}
It seems that I just reimplement the logic again in my test, is this correct? If not, how can I come up with another properties if the logic is just simple combinations of several flags?
that is not right.
you should not have to calculate what the expected value should be during the test, you should know what the result should be, set it as such and compare it against the actual result.
Tests work by calling the method you want to test and comparing the result against an already known, expected value.
"the button should be visible when filters are not empty, results is empty, isLoading is false " {
forAll { filters: List<Filters>, results: List<Shop>, isLoading: Boolean ->
val actualVisibleFlag = isButtonVisible(filters, results, isLoading)
val expectedVisibleFlag = true
assertThat(actualVisibleFlag ).isEqual(expectedVisibleFlag )
}
}
Your expected value is known, this is the point I am trying to make.
For each combination of inputs, you create a new test.
The idea here is that when you have a bug you can easily see which existing test fails or you can add a new one which highlights the bug.
If you call a method, to give you the result of what you think you should get, well, how do you know that method is correct anyway? How do you know it works correctly for every combination?
You might get away with less tests if you reduce your number of flags maybe, do you really need 4 of them?
Now, each language / framework has ( or should have ) support for a matrix kind of thing so you can easily write the values of every combination
If I want to change the focus item in the ListView control I do the following:
BOOL setListFocusItem(CListCtrl* pList, int nIndex)
{
return !!pList->SetItemState(nInd, LVIS_FOCUSED, LVIS_FOCUSED);
}
Is this the way you do it?
Because the focus itself changes but there's one issue that this creates. For instance, if the list had 100 items and the focus was on item 1. If I then call my method as such setListFocusItem(99); the focus changes to item 99, but then if I shift-click on item 90, I would expect the list to have items 90 through 99 to be selected. But instead the list selects items 1 through 90. So obviously my setListFocusItem() method does not change the shift-click "first" location. So question is how to make it do it?
Short answer : use the LVM_SETSELECTIONMARK message.
(In MFC-ese, CListCtrl::SetSelectionMark).
I have a list within my application, but was wondering if it is possible to have each list displayed show a different background colour, rather than the same one through out each item?
I have created a template but would be nice to have the background of each change colour.
Thanks
EDIT: I have also created the same list via a 'Ext.dataview.component.DataItem' / 'DataView' so if this is easier to control separately then great, as I am looking at interfering in te process of creating each and setting its background, if that is at all possible.
You could try to do that with simply XTemplate:
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>',
'<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
'<p>Kids: ',
'<tpl for="kids">',
'<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
'{name}',
'</div>',
'</tpl></p>'
);
take a look at their explanations, might find something interesting:
http://docs.sencha.com/touch/2-0/#!/api/Ext.XTemplate
I have seen many variants on the Ext.query('class').up().addCls('backgroundClass'); hack, which makes perfect sense to me, but my question is WHEN are people calling this? I can't put it in 'painted', since DOM doesn't seem to exist yet.. where/when are you guys executing the Ext.get(..) call?
I have been looking for this also, and I had a hard time finding out how to access the individual items of a xlist...
This is the way I finally did it:
in your itemTpl, add a class to your < div >, using the property 'id' of your model:
itemTpl:'< div class="my_list_item_{id}"> ... content ... < /div>'
the tricky part is that if you want to set the background color of the whole item area, you have to access to < div > with class 'x-item-label' that is wrapping your itemTpl < div >.
Here is how I did it (for the first item as an example):
Ext.select('.my_list_item_1').first().up('div.x-list-item-label').addCls('background_item');
where 'background_item' is a CSS style, defining your background color.
(Since there is no way (at least that I know of) to get the index count of your items in the 'itemTpl' config, I had to use to automatic 'id' property of my model/store.
Note that if you apply filtering/sorting/... on your store, this property will not be sorted anymore. So if you want to link the order displayed in your list to the 'id' property, you have to do something like 'Ext.StoreManager.get('MyStore').getAt(indexInList).get('id') )
Hope this helps...
Since Sencha Touch 2.2.1 it's also possible to use striped parameter (more info here). It will add x-list-item-odd class to odd items of your list.