در فلاتر برای نمایش لیست در حال معمول از SingleChildScrollView
یا Listview
و Gridview
استفاده می کنیم. این به هیچ وجه مشکلی نداره و همه چیز اوکیه، اما تا چه زمانی؟ تا زمانی که بخوایم توی اون صفحه از ویجت های دیگه ای بجز لیست ها استفاده کنیم. چند مثال میزنم واستون و بعد در مورد راه حل صحبت می کنم.
مثال اول: مثلا شما لیست پست های اینستاگرام رو در صفحه اصلی اون در نظر بگیرید. ابتدا AppBar، بعد لیست استوری ها و در نهایت لیست پست ها قرار داره که با اسکرول کردن پست ها و به انتها رسیدن، مجددا درخواست به سرور ارسال میشه و پست های صفحه بعد به انتهای لیست اضافه میشه.
در این صفحه اینستاگرام، ما نمیتونیم از Listview استفاده کنیم. چرا؟ چون
۱- در این طراحی اگر بخوایم از Listview استفاده کنیم، بخاطر وجود لیست استوری ها که وابسطه به رفتار اسکرول صفحه به سمت بالا میره یا برمیگرده، نیاز به مدیریت اون هست.
۲- بخاطر وجود ویجت لیست استوری ها Listview ما برای پست ها به درستی کار نمیکنه و پشت سر هم به سرور درخواست ارسال میکنه و لیست جدید پست ها رو میگیره و این تا بی نهایت میره که واقعا چیز سمیه
مثال دوم: صفحه پروفایل اینستاگرام رو در نظر بگیرید که ابتدا Appbar، بعد چند ویجت متن و عکس برای پروفایل و بیو، سپس ویجت های دکمه ویرایش و بعد از اون دکمه های Tabbar که برای مدیریت tab ها قرار دارند. در نهای هم ویجت Tabview رو می بینید که برای لیست پست های شما و تگ شده ها قرار داره.
در این طراحی که عمرا بتونید از Listview استفاده کنید. هم بخاطر دلایل مشابه مثال قبلی و هم مخصوصا وجود Tabbar اون وسط.
برای طراحی صفحاتی مشابه صفحات مثال زده شده، میتونید ار NestedScrollView استفاده کنید. باید بدونید که NestedScrollView صفحه ما رو به دو بخش تقسیم می کنه و در نهایت اونها رو به یک ویجت تبدیل می کنه که باعث میشه بتونیم روی اونها اسکرول انجام بدیم و مدیریت پیشرفته تری روی اجزای اون داشته باشیم.
بخش اول headerSliverBuilder هست که خروجی اون یک لیستی از ویجت ها است. ما میتونیم در مثال اول ویجت Appbar و لیست استوری ها و در مثال دوم ویجت های Text و Image و Button و Tabbar رو در این بخش قرار بدیدم و در بخش دوم اون که body هستش یک Listview برای لیست پست ها یا Tabview قرار بدیم.
کد نهایی ما برای مثال اول چیزی شبیه کد زیر می شود.
Scaffold( body: NestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) => [ SliverAppBar( // appbar content ), SliverToBoxAdapter( child: // stories box ), ], body: Listview.builder( // posts content ), ), );
کد نهایی ما برای مثال دوم هم شبیه کد زیر می شود.
DefaultTabController( length: 2, child: Scaffold( appBar: AppBar( //content appbar ), body: NestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) => [ SliverToBoxAdapter( // top box for avatar and bio or buttons ), SliverAppBar( // fix when scroll top pinned: true, automaticallyImplyLeading: false, flexibleSpace: SizedBox( child: TabBar( tabs: [ Tab(), // post tab Tab(), // tags tab ], ), ), ), ], body: TabBarView( children: [ Gridview.builder(), // my posts Gridview.builder() // my tags ], ), ), ), );
در نظر داشته باشید که می تونید از CustomScrollview هم استفاده کنید که در حالتی که tab در طراحی شما وجود ندارد مشکلی نیست، مثل مثال اول. اما زمانی که در طراحی از tabbar استفاده می کنید مشکل در اسکرول کردن دارید. چطور؟ ببینید در این حالت وقتی روی لیست پست ها اسکرول می کنید appbar به سمت بالا حرکت نمیکنه. همینطور تمام ویجت های دیگه که استفاده شدند.
امیدوارم که از این مقاله استفاده کرده باشید. خوشحال میشم با نظراتتون به بهتر شدن مقالاتم کمک کنید.