Flutter SKU选择器插件ff_sku_picker的使用

Flutter SKU选择器插件ff_sku_picker的使用

SKU选择器。

下图展示了该插件的效果,您可以下载代码并直接运行。

img.png

开始使用

如何使用

FFSkuPicker(
    // 条件列表
    conditions: conditions,
    // 选项列表
    options: options,
    // 默认选中第一个可选项
    selectedFirst: true,
    // 选项行间距
    spacing: 16,
    // 选项列间距
    runSpacing: 16,
    // 选中某个的条件回调
    onSelectItem: (FFOptionsModel? model) {
      // ...
    },
    padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
    // 分区
    titleBuilder: (index) {
      // ...
      return Text('');
    },
    // 条件
    itemBuilder: (FFIndexPath indexPath, bool available, bool selected) {
      // ...
      return Container(),
    },
  )

完整示例代码

以下是一个完整的示例代码,展示了如何在Flutter项目中使用ff_sku_picker插件。

import 'package:flutter/material.dart';
import 'package:ff_sku_picker/ff_sku_models.dart';
import 'package:ff_sku_picker/ff_sku_picker.dart';

void main() {
  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SkuTestPage(),
    ),
  );
}

// 示例页面
class SkuTestPage extends StatefulWidget {
  const SkuTestPage({super.key});

  [@override](/user/override)
  SkuTestPageState createState() => SkuTestPageState();
}

class SkuTestPageState extends State<SkuTestPage> {
  // 条件列表, 传入FFConditionModel类型对象,可以使用json数据
  List<FFConditionModel> conditions = [
    FFConditionModel('款式', [1, 2], ['男款', '女款']),
    FFConditionModel('颜色', [3, 4, 5], ['红色', '黄色', '蓝色']),
    FFConditionModel('尺寸', [6, 7, 8, 9, 10], ['XXL', 'XL', 'L', 'S', 'M']),
    FFConditionModel('其他', [11, 12, 13], ['A', 'B', 'C']),
  ];

  // 选项列表,数组中的对象必须继承自FFOptionsModel,更多属性使用可子类解析json
  List<TestOptionsModel> options = [
    // '男款,红色,XL,A'
    TestOptionsModel(167, [1, 3, 7, 11], price: '121', goodsId: '1'),
    // '男款,红色,M,B'
    TestOptionsModel(289, [1, 3, 10, 12], price: '102', goodsId: '2'),
    // '男款,黄色,L,A'
    TestOptionsModel(300, [1, 4, 8, 11], price: '123', goodsId: '3'),
    // '男款,黄色,M,B'
    TestOptionsModel(135, [1, 4, 10, 12], price: '134', goodsId: '4'),
    // '女款,红色,XL,A'
    TestOptionsModel(632, [2, 3, 7, 11], price: '105', goodsId: '5'),
    // '女款,蓝色,L,B'
    TestOptionsModel(21, [2, 5, 8, 12], price: '119', goodsId: '6'),
    // '女款,蓝色,XXL,C'
    TestOptionsModel(73, [2, 5, 6, 13], price: '118', goodsId: '7'),
    // '男款,蓝色,L,C'
    TestOptionsModel(235, [1, 5, 8, 13], price: '107', goodsId: '8'),
    // '女款,黄色,M,C'
    TestOptionsModel(5767, [2, 4, 10, 13], price: '116', goodsId: '9'),
    // '男款,蓝色,L,A'
    TestOptionsModel(12346, [2, 5, 8, 11], price: '115', goodsId: '10')
  ];

  TestOptionsModel? currentModel;

  [@override](/user/override)
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {});
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('电商项目SKU选择器'),
      ),
      body: FFSkuPicker(
        conditions: conditions,
        options: options,
        selectedFirst: true,
        spacing: 16,
        runSpacing: 16,
        onSelectItem: (FFOptionsModel? model) {
          if (model == null) {
            currentModel = null;
          } else {
            currentModel = model as TestOptionsModel;
            // print('当前选中: ffIndex = ${currentModel!.ffIndex}, goodId = ${currentModel!.goodsId}');
          }
          setState(() {});
        },
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
        titleBuilder: (index) {
          return Padding(
            padding: const EdgeInsets.symmetric(vertical: 16),
            child: Text(
              conditions[index].name,
              style: Theme.of(context).textTheme.titleMedium?.copyWith(
                    fontWeight: FontWeight.bold,
                  ),
            ),
          );
        },
        itemBuilder: (FFIndexPath indexPath, bool available, bool selected) {
          // 背景色, 选中时高亮
          Color bgColor =
              selected ? const Color(0xFFFFEEED) : const Color(0xFFF3F3F3);
          // 文字颜色, 选中时高亮, 不可用时置灰
          Color textColor = selected
              ? const Color(0xFFFF5A4C)
              : available
                  ? const Color(0xFF333333)
                  : const Color(0xFF999999);
          return Container(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 5),
            decoration: BoxDecoration(
              color: bgColor,
              borderRadius: BorderRadius.circular(15),
            ),
            child: Text(
              conditions[indexPath.section].contentList[indexPath.index],
              style: Theme.of(context).textTheme.titleSmall?.copyWith(
                    color: textColor,
                  ),
            ),
          );
        },
      ),
      bottomNavigationBar: SafeArea(
        child: Text(
          currentModel == null
              ? '当前未完成选中, 所有条件选择完成后可展示结果'
              : '选中: 第${currentModel!.ffIndex}个可选项, price = ${currentModel!.price}, 可自行添加图片',
          style: Theme.of(context).textTheme.titleMedium,
          maxLines: 3,
          textAlign: TextAlign.center,
        ),
      ),
    );
  }
}

// 非必要
// json格式, 如果没有附加字段,则直接使用FFOptionsModel即可,否则在字类中自由添加
// {
//   "stock": "121",
//   "idList": [1, 5, 8, 13],
//   "price": "888",
//   "goodsId": "8",
//   // "image": "https://"
//   // "detail": "男款,蓝色,L,C",
// }
class TestOptionsModel extends FFOptionsModel {
  TestOptionsModel(
    super.stock,
    super.idList, {
    required this.price,
    required this.goodsId,
  });

  factory TestOptionsModel.fromJson(Map<String, dynamic> json) {
    final List<int>? list = json['idList'] is List ? <int>[] : null;
    if (list != null) {
      for (final dynamic item in json['idList']!) {
        if (item != null) {
          list.add(asT<int>(item)!);
        }
      }
    }
    return TestOptionsModel(
      asT<int>(json['stock']) ?? 0,
      list ?? [],
      price: asT<String>(json['price']) ?? '',
      goodsId: asT<String>(json['goodsId']) ?? '',
    );
  }

  String price;
  String goodsId;

  Map<String, dynamic> toJson() => {
        'stock': stock,
        'idList': idList,
        'price': price,
        'goodsId': goodsId,
      };
}

T? asT<T>(dynamic value) {
  if (value is T) {
    return value;
  }
  return null;
}

更多关于Flutter SKU选择器插件ff_sku_picker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter SKU选择器插件ff_sku_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用ff_sku_picker插件的示例代码。这个插件通常用于在应用中实现SKU(Stock Keeping Unit)选择器,特别是在处理订阅或内购时非常有用。

首先,确保你已经在pubspec.yaml文件中添加了ff_sku_picker依赖:

dependencies:
  flutter:
    sdk: flutter
  ff_sku_picker: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用ff_sku_picker

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:ff_sku_picker/ff_sku_picker.dart';
  1. 创建SKU选择器
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter SKU Picker Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SkuPickerScreen(),
    );
  }
}

class SkuPickerScreen extends StatefulWidget {
  @override
  _SkuPickerScreenState createState() => _SkuPickerScreenState();
}

class _SkuPickerScreenState extends State<SkuPickerScreen> {
  List<Sku> skus = [
    Sku(
      sku: 'sku_monthly',
      title: 'Monthly Subscription',
      price: '9.99',
      currencyCode: 'USD',
      description: 'Subscribe for one month',
    ),
    Sku(
      sku: 'sku_yearly',
      title: 'Yearly Subscription',
      price: '99.99',
      currencyCode: 'USD',
      description: 'Subscribe for one year',
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SKU Picker Demo'),
      ),
      body: Center(
        child: SkuPicker(
          skus: skus,
          onSkuSelected: (Sku selectedSku) {
            // 处理用户选择的SKU
            showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  title: Text('SKU Selected'),
                  content: Text('You selected: ${selectedSku.title}'),
                  actions: <Widget>[
                    TextButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text('OK'),
                    ),
                  ],
                );
              },
            );
          },
        ),
      ),
    );
  }
}

// 定义SKU类
class Sku {
  final String sku;
  final String title;
  final String price;
  final String currencyCode;
  final String description;

  Sku({
    required this.sku,
    required this.title,
    required this.price,
    required this.currencyCode,
    required this.description,
  });
}

在这个示例中,我们定义了一个简单的SKU类,其中包含SKU的各种属性,如skutitlepricecurrencyCodedescription。然后,在SkuPickerScreen中,我们创建了一个SKU列表,并使用SkuPicker小部件来显示这些SKU供用户选择。当用户选择一个SKU时,我们会显示一个对话框来通知用户他们的选择。

请注意,ff_sku_picker插件的实际使用可能会涉及到更多的配置和错误处理,特别是在处理实际支付和订阅逻辑时。这个示例代码主要是为了展示如何在Flutter应用中使用该插件的基本功能。在实际开发中,你可能需要根据插件的文档和API参考来调整代码以适应你的具体需求。

回到顶部