如何在没有项目构建器的情况下使用索引

时间:2020-10-18 03:09:05

标签: flutter dart flutter-layout

我正在尝试在页面上显示来自Firestore的卡片列表。此列表是从另一个页面调用的。如果我手动设置一个整数值,产品将根据该值显示卡,但如果我未设置一个整数值,则会出现错误。我如何不使用itembuilder来获得卡的索引。这是代码。

child: Center(
                                    child: InkWell(
                                  onTap: () async {
                                    await productProvider
                                        .loadProductsByCategory(
                                            categoryName: categoryProvider
                                                .categories[0].category);
                                    changeScreen(
                                        context,
                                        CategoryScreen(
                                          categoryModel:
                                              categoryProvider.categories[0],
                                        ));
                                  },
                                  child: Text(widget.product.category),
                                )),

这是我遇到的问题。只需使用[0]或任何整数即可。但是我想调用索引,以便一旦我单击类别,它就会加载特定的一种及其所有产品。我已经附上了完整的代码。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class NewProductScreen extends StatefulWidget {
  final ProductModel product;

  const NewProductScreen({Key key, this.product}) : super(key: key);

  @override
  _NewProductScreenState createState() => _NewProductScreenState();
}

class _NewProductScreenState extends State<NewProductScreen> {
  @override
  Widget build(BuildContext context) {
    final productProvider = Provider.of<ProductProvider>(context);
    final categoryProvider = Provider.of<CategoryProvider>(context);

    return Scaffold(
        body: CustomScrollView(slivers: <Widget>[
          SliverToBoxAdapter(
            child: Column(
              children: <Widget>[
                Container(
                  margin:
                  EdgeInsets.only(top: 5, bottom: 5, right: 2),
                  width: MediaQuery
                      .of(context)
                      .size
                      .width / 3,
                  height: MediaQuery
                      .of(context)
                      .size
                      .height / 30,
                  child: Center(
                      child: InkWell(
                        onTap: () async {
                          await productProvider.loadProductsByCategory(
                              categoryName: categoryProvider
                                  .categories[0].category);
                          Navigator.push(
                              context,
                              MaterialPageRoute(
                                  builder: (context) =>
                                      CategoryScreen(
                                        categoryModel: categoryProvider
                                            .categories[0],
                                      )));
                        },
                        child: Text(widget.product.category),
                      )),
                ),
              ],
            ),
          )
        ]));
  }
}

class CategoryScreen extends StatefulWidget {
  final CategoryModel categoryModel;

  const CategoryScreen({Key key, this.categoryModel}) : super(key: key);

  @override
  _CategoryScreenState createState() => _CategoryScreenState();
}

class _CategoryScreenState extends State<CategoryScreen> {
  @override
  Widget build(BuildContext context) {
    final productProvider = Provider.of<ProductProvider>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text("Category Filter"),
      ),
      body: SafeArea(
          child: ListView(
            children: <Widget>[
              Container(
                height: MediaQuery
                    .of(context)
                    .size
                    .height / 10,
                decoration: BoxDecoration(
                    color: Colors.orange.withOpacity(0.5),
                    image: DecorationImage(
                        image: NetworkImage(widget.categoryModel.icon))),
                child: Center(
                  child: Text(
                    widget.categoryModel.category,
                    style: TextStyle(
                      fontWeight: FontWeight.w700,
                      fontSize: 50,
                    ),
                  ),
                ),
              ),
              Column(
                children: productProvider.productsByCategory
                    .map((e) =>
                    GestureDetector(
                      onTap: () {
                        Navigator
                            .push(context, MaterialPageRoute(builder: (context)
                        =>
                            NewProductScreen(
                              product: e,
                            )
                        );
                            
                      },
                      child: CategoryProductCard(
                        product: e,
                      ),
                    ))
                    .toList(),
              )
            ],
          )),
    );
  }
}

//Category ProductCard

class CategoryProductCard extends StatefulWidget {
  final ProductModel product;

  const CategoryProductCard({Key key, this.product}) : super(key: key);

  @override
  _CategoryProductCardState createState() => _CategoryProductCardState();
}

class _CategoryProductCardState extends State<CategoryProductCard> {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 4, right: 4, top: 4, bottom: 10),
      child: Container(
        height: 110,
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(20),
            boxShadow: [
              BoxShadow(
                  color: Colors.grey[300],
                  offset: Offset(-2, -1),
                  blurRadius: 5),
            ]),
//            height: 160,
        child: Row(
          children: <Widget>[
            Container(
              width: 140,
              height: 120,
              child: ClipRRect(
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(20),
                  topLeft: Radius.circular(20),
                ),
                child: Image.network(
                  widget.product.images[0],
                  fit: BoxFit.fill,
                ),
              ),
            ),
            Expanded(
              child: Column(
                children: <Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text(widget.product.title)),
                      Padding(
                        padding: EdgeInsets.all(8),
                        child: Container(
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20),
                              color: Colors.white,
                              boxShadow: [
                                BoxShadow(
                                    color: Colors.grey[300],
                                    offset: Offset(1, 1),
                                    blurRadius: 4),
                              ]),
                        ),
                      )
                    ],
                  ),
                  SizedBox(
                    height: 25,
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(right: 8.0),
                        child: Text(
                          "\N${widget.product.price}",
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

//Category Model

class CategoryModel {
  static const ID = "id";
  static const CATEGORY = "category";
  static const ICON = "icon";

  int _id;
  String _category;
  String _icon;
  bool isSelected;

  int get id => _id;

  String get category => _category;

  String get icon => _icon;

  CategoryModel.fromSnapshot(DocumentSnapshot snapshot) {
    _id = snapshot.data[ID];
    _category = snapshot.data[CATEGORY];
    _icon = snapshot.data[ICON];
  }
}

// Category Provider

class CategoryProvider with ChangeNotifier {
  CategoryServices _categoryServices = CategoryServices();
  List<CategoryModel> categories = [];

  CategoryModel categoryModel;

  CategoryProvider.initialize() {
    loadCategories();
  }

  loadCategories() async {
    categories = await _categoryServices.getCategories();
    notifyListeners();
  }

  loadSingleCategory({String singleCat}) async {
    categoryModel =
    await _categoryServices.getCategoryByName(category: singleCat);
    notifyListeners();
  }
}

// Category Service

class CategoryServices {
  String collection = "categories";
  Firestore _firestore = Firestore.instance;

  Future<List<CategoryModel>> getCategories() async =>
      _firestore.collection(collection).getDocuments().then((result) {
        List<CategoryModel> categories = [];
        for (DocumentSnapshot category in result.documents) {
          categories.add(CategoryModel.fromSnapshot(category));
        }
        return categories;
      });

  Future<CategoryModel> getCategoryByName({String category}) =>
      _firestore
          .collection(collection)
          .document(category.toString())
          .get()
          .then((doc) {
        return CategoryModel.fromSnapshot(doc);
      });
}

// Product Model


class ProductModel {
  static const ID = "id";
  static const TITLE = "Product Title";
  static const Images = "Product Images";
  static const PRICE = "Product Price";
  static const CATEGORY = "Product Category";

  // static const QUANTITY = "Product Quantity";
  static const BRAND = "Product Brand";


  String _id;
  String _title;
  List _images;

  String _category;
  String _brand;


// int _quantity;
  double _price;


  String get id => _id;

  String get title => _title;

  List get images => _images;

  String get brand => _brand;

  String get category => _category;


// int get quantity => _quantity;

  double get price => _price.floorToDouble();
  

  ProductModel.fromSnapshot(DocumentSnapshot snapshot) {
    _id = snapshot.data[ID];
    _brand = snapshot.data[BRAND];
    _price = snapshot.data[PRICE];
    _category = snapshot.data[CATEGORY];
    _title = snapshot.data[TITLE];
    _images = snapshot.data[Images];

  }
}

class ProductProvider with ChangeNotifier {
  ProductServices _productServices = ProductServices();
  List<ProductModel> products = [];
  List<ProductModel> productsByVendor = [];
  List<ProductModel> productsByCategory = [];

  ProductProvider.initialize() {
    loadProducts();
  }

  loadProducts() async {
    products = await _productServices.getProducts();
    notifyListeners();
  }

  Future loadProductsByCategory({String categoryName}) async {
    productsByCategory =
    await _productServices.getProductsByCategory(category: categoryName);
    notifyListeners();
  }
}

class ProductServices {
  String collection = "appProducts";
  Firestore _firestore = Firestore.instance;

  Future<List<ProductModel>> getProducts() async =>
      _firestore.collection(collection).getDocuments().then((result) {
        List<ProductModel> products = [];
        for (DocumentSnapshot product in result.documents) {
          products.add(ProductModel.fromSnapshot(product));
        }
        return products;
      });

  Future<List<ProductModel>> getProductsByCategory({String category}) async =>
      _firestore
          .collection(collection)
          .where("Product Category", isEqualTo: category)
          .getDocuments()
          .then((result) {
        List<ProductModel> products = [];
        for (DocumentSnapshot product in result.documents) {
          products.add(ProductModel.fromSnapshot(product));
        }
        return products;
      });
}

1 个答案:

答案 0 :(得分:0)

您可以尝试以下方式

final List uniqueList = Set.from(myList).toList();


uniqueList.map((val) {
    String idx = uniqueList.indexOf(val);

    return something;
}

例如:

 @override
  Widget build(BuildContext context) {
    var  uniqueList = Set.from(['A','B','C','D','E']).toList();

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
                children: uniqueList
                    .map((e) =>
                    GestureDetector(
                      onTap: () {
                        print("--index--${uniqueList.indexOf(e)}");
//                         Navigator
//                             .push(context, MaterialPageRoute(builder: (context)
//                         =>
//                             NewProductScreen(
//                               product: e,
//                             )
//                         );
                            
                      },
                      child: Text('value :$e - index:${uniqueList.indexOf(e)}'),
                      
                    ))
                    .toList(),
              )
      ),
    
    );
  }

在这里,您应该将 ['A','B','C','D','E'] 列表替换为您 productProvider.productsByCategory < / p>

输出

output