شريط التبويبات
تبويبات في كبسولة زجاجية واحدة، بلا حاجة إلى هيكل.
LiquidGlassTabBar هو الشريط وحده: أنت تضعه، وأنت تحفظ الفهرس، وأنت تقرّر ما تفعله الصفحة به. وهو كالشريط العلوي عدسةٌ واحدة، فيريد على Skia LiquidGlassView أباً خلفيته هي الصفحة التي ينبغي أن يكسرها.
LiquidGlassTabBar(
items: const [
LiquidGlassTabBarItem(
icon: Icons.today_outlined,
selectedIcon: Icons.today_rounded,
label: 'Today',
),
LiquidGlassTabBarItem(icon: Icons.bar_chart_rounded, label: 'Charts'),
],
selectedIndex: index,
onChanged: (i) => setState(() => index = i),
width: 330,
)ليس شرطاً أن تكون تلك الخلفية هي الصفحة. فعرض الشريط داخل بطاقة يتوسّط بالشريط بطاقةً ويسلّمه سطحَ البطاقة نفسه، فيقف الزجاج عند حافتها — أما الصفحة حولها فلا تُلتقط ولا تنكسر، وليس خلف الشريط سوى مادة البطاقة. والقرار الوحيد هو أيّ مسار يحتاجه الشريط، وresolveGlassPill() يجيب عنه على المُصيِّر الحالي: صحيح فتريد الحبةُ الزجاجية آلةَ الشريط ذات العرضين عبر buildGlassPillBar(body: …)، وخطأ فالمستوى المسطّح عدسةٌ واحدة، ويكفيه LiquidGlassView واحد فوق البطاقة.
final bar = LiquidGlassTabBar(
items: _items,
selectedIndex: index,
onChanged: (i) => setState(() => index = i),
width: cardWidth - 26,
// The card is the whole world the bar sits in: dead centre, no gap.
alignment: Alignment.center,
margin: EdgeInsets.zero,
);
SizedBox(
width: cardWidth,
height: 112,
child: ClipRRect(
borderRadius: BorderRadius.circular(26),
child: bar.resolveGlassPill()
? bar.buildGlassPillBar(body: cardSurface)
: LiquidGlassView(
backgroundWidget: cardSurface,
child: Center(child: bar),
),
),
)| المعامل | الافتراضي | ما يفعله |
|---|---|---|
items | — | عناصر LiquidGlassTabBarItem: أيقونة وأيقونة محدَّدة ونص. |
selectedIndex / onChanged | — | الفهرس ملكك. |
width / height | 320 / 64 | الكبسولة. |
margin / itemPadding / alignment | — | أين يجلس الشريط وكيف تتباعد العناصر بداخله. |
itemStyle | LiquidGlassTabItemStyle() | ألوان الأيقونات والنصوص ومقاساتها وأوزانها — انظر أدناه. |
pillStyle | LiquidGlassTabPillStyle() | كل ما يخصّ علامة التحديد — انظر أدناه. |
style / visibility | null / true | زجاج كبسولة الشريط نفسه، والمفتاح الذي يطفئه. |
تنسيق العناصر#
الألوان والمقاسات مجمَّعة لا مسطّحة، فينتقل مظهر الشريط كقيمة واحدة. وunderGlassIconSize وunderGlassLabelFontSize هما الزوج اللافت: فالشريط ذو الحبة الزجاجية يرسم كل تبويب مرتين — مرة عادية ومرة تحت الحبة — ويتيح هذان أن تكون النسخة التي تحت الزجاج بمقاس مختلف، وبهذا يُلغى أثر التكبير.
itemStyle: const LiquidGlassTabItemStyle(
selectedColor: Colors.white,
unselectedColor: Colors.white70,
iconSize: 24,
underGlassIconSize: 21, // cancels the pill's magnification
labelFontSize: 10.5,
selectedFontWeight: FontWeight.w600,
)رموز مخصصة#
التبويبات ليست محصورة في IconData. مرّر iconBuilder — أو labelBuilder — فتعمل SvgPicture وImage وCustomPaint جميعها.
LiquidGlassTabBarItem(
label: 'Home',
iconBuilder: (context, i) => SvgPicture.asset(
i.selected ? 'assets/home_fill.svg' : 'assets/home.svg',
width: i.size,
height: i.size,
colorFilter: ColorFilter.mode(i.color, BlendMode.srcIn),
),
)يُسلَّم البنّاء LiquidGlassGlyph: اللون الذي حسمه الشريط للطبقة المرسومة، ومقاس صندوق الرمز، وهل هذه الطبقة هي المحدَّدة، وهل هي النسخة التي تحت الزجاج. لوّن بـ i.color فيتبع رسمُك اللوحةَ وكشفَ الحبة المتحولة. أما الرسم متعدد الألوان فيمكنه تجاهل اللون تماماً.
المستويان#
| `pillStyle.mode` | ما هو التحديد |
|---|---|
none | إبراز شفاف داخل عدسة الشريط الواحدة. فوري، أو انزلاق ناعم مع animated: true. ورخيص في كل مكان. |
impellerOnly | الحبة المتحولة الزجاجية حيث تكون مجانية، والإبراز على Skia. |
both (الافتراضي) | الحبة المتحولة على المحركين — سطح كاسر ثانٍ يثني الشريط نفسه. وعلى Skia تحت الزجاج الخفيف فقط — انظر الملاحظة أدناه. |
بقية الحبة#
يحمل LiquidGlassTabPillStyle التحديد كله: هل يظهر أصلاً، ولونه وضبابيته، وشكله، والزجاج الذي يلبسه مرفوعاً والأسلوب البسيط الذي يلبسه ساكناً، وسرعة سفره، وكيف يتشوّه في الطريق.
| الحقل | الافتراضي | ما يفعله |
|---|---|---|
show | true | رسم علامة تحديد من الأساس. |
animated | false | في وضع none، انزلاق الإبراز بدل قفزه. |
color / blur | 0x2EAEAEB2 / — | تعبئة العلامة وضبابية خلفيتها. |
growHeight | 9 | كم يزيد ارتفاع الحبة عن صف العناصر. |
distortion / distortionWidth / magnification | 0.04 / 12 / 1 | انكسار الحبة نفسها، فوق الشريط تحتها. |
travelStiffness / travelDamping | 280 / 31.4 | النابض الذي يحملها بين التبويبات. |
glassStyle / rest / shape | null | تجاوزات كاملة لمظهر الرفع ومظهر السكون والمحيط. |
تتشوّه الحبة المتحركة أثناء سفرها، بالنموذج نفسه الذي يستخدمه مقبض المزلاج: فـpillStyle.motion هو LiquidGlassLensMotionSpec، مضبوط هنا بسقف أرفق لمسافة التبويبات. انظر الحركة.
شريط مستقل على Impeller#
Stack(
children: [
MyPage(),
LiquidGlassTabBar.withImpeller(
items: items,
selectedIndex: index,
onChanged: (i) => setState(() => index = i),
),
],
).withImpeller هو الشريط بلا جسم: بلا هيكل وبلا صفحة تُسلَّم إليه. وهو يتمدّد ليملأ، فضعه آخر ابن في Stack. وعلى Skia يتراجع إلى شريط مصنفر يظل يُظهر المحتوى عبره.
التعليقات
التعليقات هي مناقشات GitHub — يمكنك الرد من أيٍّ من المكانين.