-
Notifications
You must be signed in to change notification settings - Fork 26.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PageView] Add/Remove page while staying on current page #58959
Comments
Hi @fralways code sampleimport 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const Widget _home = HomePage();
@override
Widget build(BuildContext context) => MaterialApp(
home: _home,
);
}
class HomePage extends StatefulWidget {
const HomePage();
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
PageController _controller;
List<int> _lenght = [0];
@override
void initState() {
super.initState();
_controller = PageController();
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
void _add() => setState(() {
_lenght.add(_lenght.length);
});
void _remove() => setState(() {
if(_lenght.length > 1) {
_lenght.removeLast();
}
});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: IconButton(
icon: const Icon(Icons.remove),
onPressed: _remove,
),
),
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: IconButton(
icon: const Icon(Icons.add),
onPressed: _add,
),
),
],
),
body: PageView(
controller: _controller,
children: <Widget>[
for(int i in _lenght) Center(
child: Container(
color: Colors.blueAccent[100],
height: 80,
width: 80,
child: Center(child:Text('$i'),),
),
),
],
),
);
}
|
@iapicca I have modified a bit your code:
What I want is if I have 3 pages - 0, 1 and 2, and Im at page 1, and I delete page 0, I want to still to see page 1 since it should not matter to the user if page 0 is removed since he is not looking at it. What happens is if I remove page 0, PageView jumps from page 1 to page 2 since it does not update its page index / offset. |
Hi @fralways |
Yes, after add/delete I would like PageView not to change displayed page. I have not found any solution to accomplish this, thus I suggested additional methods in PageController. As I said, after adding/deleting page I tried to say controller.jumpToPage so that I can set again the correct page, but this breaks user gesture if its currently active. |
Hi @fralways Making a parallel with list view, adding and removing items I'm not sure that it is desirable to bake this behaviour in the framework, Thank you |
@iapicca I understand that it was example to make a point but I did the same. I showed that it's not possible to change PageView pages without changing the page user is currently looking at. Currently using PageView it's not possible to remove pages which are not necessary anymore if those pages have index < current page index without changing current displayed page. I really struggle to find a use case where a developer wants to remove some old page and after removal, current displayed page should change. This is how PageView currently works. In parallel with iOS, there we have page view data source methods which are called only when pages are changing, where we can supply any page we want. That means if some page is not used anymore we just don't provide it and it's removed. This makes developer in control, while here we have no control over index once page list is rebuilt. Just imagine if we have 50 pages and the user is looking at 20th, and we need to remove first 10 because for some reason they expired / should not be displayed anymore, the widget will then jump to 30th page which breaks ux. The same thing happens if using PageView.builder. |
Hi, I am also kind of facing same issue, where I want to insert children at the beginning of the list rather than end of the list.
|
I had the same or at least similar needs. Interestingly, I started off with a Compare the original (more or less) to the builder version. If I had to summarise the difference: I can't manage to maintain the same page (by jumping after a remove) or it seems to remove the wrong element. |
@iapicca One use case for this behavior would be used in calendars as we don't know the size of the month list. Generally, we don't ask the user to provide the end and start date of calendars before showing them to the user, we add more months to the start if the user swipes left and more months to the right if the user swipes right . The right swipe scenario is easy right now as it doesn't affect the current page but adding more months at the start on the left swipe would cause jumps. |
Now, coming to the current solution suggested above was jumping back to the previous page after adding a new page but this would lead to an unnecessary rebuild which leads to more jank and glitches. |
Another alternate solution suggested by @goderbauer is using the center with a CustomScrollView described here #62209 (comment) which worked great but when I added a controller on it to identify user swipes and add more to the left or right I got a wired result as swiping left was getting scrolled back to the initial value. Runnable gist showcasing the issue - https://gist.github.com/chaudharydeepanshu/26217550b19def87966bde16ffe05cd1 Video of the issue - test2.mp4So, @goderbauer if you have any solution for this issue then I request you to please let me know as this functionality is very important to me. |
Somehow I did manage to fix this issue by using the ScrollController in place of PageController but that also has its own issues. The issue is that it auto scrolls on changing the size of the device or on changing the orientation of the device. Issue video: - Untitled.Project2.mp4test3.mp4The issue is that the scroll controller uses offsets for scroll position and changing device size leads to scrolling as the offset is still old. Maybe we can fix this by listening to changes in device size and adding to offset? But I think that will be too much for a such simple task. Also, I had to use global keys to get the width of the scroll view widgets to check if the user swiped was left or right and also how far left and how far right as it doesn't have the concept for getting the current page. Also, it lacks the functionality of setting the viewport. And that's why I think the scroll view is not a replacement for the pageview. So, all of the above resulted in tedious workarounds and still, each of them failed to solve the problems so I think it would be a massive help if page view supports a feature to Add/Remove page while staying on the current page. Code for the calendar view example in anyone wants to try - https://gist.github.com/chaudharydeepanshu/d12e8303f1d3920a8c8a6f4e8d0e3ba4 |
any ideas how to fix this? i want to insert a new item at the position 0 but i want to preserve the current view without use jump because it's bad ux |
Use case
Lets say I have an app which in first page of PageView shows list of suggestions based on location. If I select something I want to add a new page after first page which shows details about selected suggestion and to navigate user to the new page. This is fine and can be done. Now if I swipe more to the right and go back I would like for user to again see suggestions page and not details of selected suggestions. This is currently not possible because if I do any kind of modification of PageView pages which are before page user is currently looking at, user will see snap, and the page will automatically change. If I try to do something like controller.jumpToPage, after setting new page list, it will be okay but only if user has no gesture running at that point. If he is in middle of swiping, he will loose his gesture.
Proposal
We could have additional methods available via controller or something else where we can insert/delete pages without notifying user about it, meaning this insertion/deletion should be aware and update page and offset of PageView automatically when page list changes.
The text was updated successfully, but these errors were encountered: