Flutter: How can I keep my last last ..shuffle order in a new state? - flutter

Is there a way to keep an aspect of the page from updating when the State updates? Or to keep an instance of the ..shuffle so that I can re-use that shuffle order in the new state?
I have a GridView that fills up with items from a Map. These items are shuffled first to make them come in a different order each time people open that page.
Once they click on one of the items in the GridView I want to update the State so that I can change parts of the page...but I don't want to re-shuffle the map.
Is there any way to do this?
The Map and shuffle part of the code is like this:
final Map choices = {
'apple': selectSuccess,
'orange': selectFailure,
'cherry': selectFailure,
'banana': selectFailure,
};
choices.forEach((k, v) => choiceSet.add(SelectCardActivity(k, v)));
choiceSet..shuffle();

Related

ListView start from bottom of list

I'm building a chat app and I want to achieve a ListView() that loads up like its reverse property is set to true i.e showing the end of the ListView on build. The reason I don't want to set the reverse property to true is because, if the items in the ListView do not fill up the screen, they are aligned to the bottom (cannot use shrinkWrap because of performance), and also because it reverses the order of the items and to show new elements at the bottom of the list, I'd need to use a spread operator and I'm worried about performance since the Map from which I render from can grow significantly.
I have also tried using the ScrollController's jumpTo method inside a SchedulerBinding.instance!.addPostFrameCallback but the user can see the scrolling and
it also causes it to jump like it's attempting to scroll beyond what is contained in the ListView. I have also used ScrollablePositionedList and set the index to which I want to scroll, but this jumps also.
Is there any way I can achieve my aim without any drawbacks visually or performance-wise?
You have the correct idea: in the initState, jump to the end. The end of the list can be obtained from position.maxScrollExtent. When done correctly, this does not create any visual or performance drawbacks. For example:
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
_controller.jumpTo(_controller.position.maxScrollExtent);
});
}
The _controller should be the ScrollController passed to the list.

Keep UI after emit state change Cubit Flutter

My Question: Can you keep built UI that was built by a state when another state is called?
Please correct me if I'm using the cubit pattern wrong. I have a unique example I'm trying to solve. I have the cubit set up and it's working as per documentation.
I have a screen where I have a horizontal list that is returned through cubit. Then based on the horizontal list returned if you click one of the items the cubit fetches a second list to display vertically underneath the horizontal list.
var _responseCategories = await _repository.postGetRootCategories();
emit(ShowCategories(state, _responseCategories));
var _responseCategoryItems = await _repository.postGetCategoryItems(_responseCategories[0].id);
emit(ShowCategoriesItems(state, _responseCategoryItems));
The ui has a bloc builder and processes the two states but when the one state is changed the UI for the first built state is then not there I understand why this happens but is there a way to stop it until I emit the state again. The UI decodes the states in a builder as follows:
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (state is ShowCategories) buildCategories(context, state),
state is ShowCategoriesItems
? Expanded(child: buildMenuItems(context, state))
: SizedBox.shrink(), //getMenuList(_activeSelection)),
],
);
If I'm using this wrong that's understandable I just want to know if there is a better solution to this to solve the problem as the category items are different per category and I don't need to fetch the categories every time the state changes.
The app is essentially a menu. The horizontal section is the categories of the menu 'I only need to load them once' and the vertical section is the items 'I need to load them when the user selects a category'. The items are different per category but the categories never change unless set by the server.
It seems like you have a master-detail view and your detail state is just a superset of the master-no-detail state.
You could derive your detail state from the master state and add more information to it (master-list, adding selected, details-list to the derived class) or you could just go with one state for both (master-list, selected, details-list) where some things aren't set when nothing is selected yet.
If your details view is really complicated, you could also create a whole new BLoC for it, with it's own logic and builder in the widget tree, then you can have totally different states.
But states from the same BLoC, you cannot opt to only rebuild a part of the tree below the builder.
(well, technically you can do anything, but there is no point in working around a pattern. If it does not fit, use a different one. And I think you can easily make it fit as described above)

How to make a List that contains another list, in flutter

I was trying to make an app in flutter, I now have an app that adds a new element into a list upon pressing a FAB. Kindly let me know how can I map another ListViewBuilder to each element. I am not sure if I am being clear enough, but I am trying to be clearer. I want an app that lets you create lists inside of lists, in flutter. So for each List element, there lies a corresponding list in which the contents of the list can be added. I am a beginner, and I am struggling to figure it out. plzzz, help me out..thanks in advance...
To create a list in a list you can use:
List<List<int>> numbers = new List<List<int>>();
And then you can add a new list to this by doing:
numbers.add([0,1,2]);
This adds the list [0,1,2] to the list called numbers.
From here you can access an element in this case the second element in the first list:
x = numbers[0][1]

Dismissive list view: When a widget in a list is dismissed, how do I remove a corresponding entry to an array

Currently, I have a list view that allows items within the list view to be dismissable. I want each item within that list view to correspond to an element within another list that contains text. And when that widget in the listview is dismissed, then the corresponding element in the other list also gets deleted. Does anyone know hot
What I suggest is that if there is any common thing in both list that are related to each other such as id or any else say text in your case ,After dismissible widget get triggered iterate via the second list just check if there's any common based on the 1st list item, and delete the item rebuild the state. Maybe adding some code might be better but so far this is the best way you can do. let me know if it work.

Xamarin Forms SearchBar + ListView slow to update

I would like some help into speeding up the process of filtering a long list of list items and viewing them on a ListView.
My app has a search bar, a ListView and a very long list of strings to choose from.
When the user enter a search term, the ListView is updated with every key stroke and filter out the irrelevant items.
Sorting itself takes a few milliseconds, but updating the ListView afterwards with the new filter-event takes a long time (20 seconds easy, if only a single character has been entered as search criteria)
I believe the time is spent on inflating a large number of ViewCells every time the filtered list updates.
Do any of you know how to speed up the process? I thought the way it could work was to have a very limited number of ViewCells (like 10 or 20) and then have them update and just show a selection of the filtered list. Scrolling would to be reusing the top/bottom one, update the content and put it back on the bottom/top - but I have not been able to wrap my head around how to do this.
Maybe it is the wrong approach and you know a better way?
I just had a similar problem that my list with just 20 elements would search extremely slow. Maybe your problem is similar. Sadly you didn't post any code. I had something like this:
List l = originalItems.Where((i) => i.Name.Contains(filterText));
listView.ItemsSource = l;
And I could not understand why this would be so slow. I found a different approach with more overhead that for some reason is faster and more responsive and overall feels better for the user. My ListView always has an ObservableCollection as ItemsSource. When I filter I calculate the difference to this ObservableCollection (the extra items and the removed items) and then remove or add accordingly. This avoids replacing the ItemsSource property which seems to be too harsh on the ListView.
//property of the class
ObservableCollection<FlightListItem> listViewItems;
// ....
//somewhere at initialization
listView.ItemsSoure = listViewItems;
// ....
//in the filter method:
List l = originalItems.Where((i) => i.Name.Contains(filterText));
IEnumerable itemsToAdd = l.Except(listViewItems).ToList();
IEnumerable itemsToRemove = listViewItems.Except(l).ToList();
listView.BeginRefresh();
foreach (FlightListItem item in removes)
listViewItems.Remove(item);
foreach (FlightListItem item in added)
listViewItems.Add(item);
listView.EndRefresh();
Notes:
removing the listView.BeginRefresh() and EndRefresh() did not seem to impact performance, but it seems the right thing to call them here.
We need to call ToList() on the itemsToAdd and itemsToRemove even though we only need IEnumerables! This is because Except is a lazy operation and will otherwise only be evaluated during the for loop. However during the for loop one of the parameters to Except changes which leads to an IllegalArgumentException due to modifying an IEnumerable while going over it.
If anyone knows a good filterable observable collection that would probably be a nicer solution.