
在此處獲取作業代碼示例
我有一個包含RxList和屬性。addOnProductsproductselected
我正在嘗試實作簡單的 multiSelectable 網格視圖,但是在單擊復選框時,選定的屬性會發生變化,但它不會反映回 ui,如果我重繪 它將被更新。
我試過 Obx()=> (); 小部件,它仍然沒有更新
我的產品控制器
class ProductsController extends GetxController {
late Worker worker;
static ProductsController instance = Get.find();
RxList<ProductModel> products = RxList<ProductModel>([]);
RxList<CheckProduct> addOnProducts = <CheckProduct>[].obs;
String collection = "products";
@override
void onReady() {
super.onReady();
products.bindStream(getAllProducts());
worker = once(products, (List<ProductModel> value) {
fillAddOnProducts(value);
}, condition: () => products.isNotEmpty);
}
Stream<List<ProductModel>> getAllProducts() => FirebaseFirestore.instance
.collection(collection)
.snapshots()
.map((query) => query.docs
.map((item) => ProductModel.fromMap(item.data(), item.id))
.toList());
void fillAddOnProducts(List<ProductModel> products) => {
products.forEach((element) {
addOnProducts.add(CheckProduct(product: element, selected: false));
})
};
}
class CheckProduct {
ProductModel product;
bool selected;
CheckProduct(
{required ProductModel this.product, required bool this.selected});
}
我的網格視圖
class AddOns extends StatelessWidget {
const AddOns({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [],
title: Text("Select Addons"),
),
body: Obx(() => GridView.count(
crossAxisCount: 2,
children: productsController.addOnProducts
.map((element) => ProductWidget(product: element))
.toList(),
)));
}
}
class ProductWidget extends StatelessWidget {
final CheckProduct product;
const ProductWidget({Key? key, required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
margin: EdgeInsets.all(10),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 4,
left: 4,
child: Checkbox(
value: product.selected,
onChanged: (value) {
print("value of the value is : $value");
print("value of product selected before is: "
product.selected.toString());
product.selected = value!;
print("value of product selected after is: "
product.selected.toString());
},
),
),
],
));
}
}
因此在控制臺中是:
I/flutter (20067): value of the value is : true
I/flutter (20067): value of product selected before is: false
I/flutter (20067): value of product selected after is: true
但是checkBox沒有更新,它只有在我重繪 時才會更新,如何克服這個?將 Obx() 添加到父級沒有幫助..
在此處找到下面代碼的 github 鏈接,其中包含問題和面臨的問題..
uj5u.com熱心網友回復:
看完你的代碼后。我已經實作了以下內容,無需熱多載即可更改狀態:
在您的主要飛鏢中,您不需要將產品控制器放在這里,因為您沒有使用它
主要.dart
import 'package:flutter/material.dart';
import 'grid.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: GridSelect(),
);
}
}
接下來,我更改了您的網格類以生成產品小部件串列作為 addProduct 串列長度的大小。在我看來,這是撰寫 GridView 計數子項的更好方法。在您使用 Getx 時,從您的 gridview 中洗掉 obx 并將您的有狀態小部件更改為無狀態。即使在無狀態小部件中,它也會管理您的狀態。在此處添加您的產品控制器,因為您將從控制器類訪問 addProduct 串列。
網格飛鏢
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:test_project/controllers/productController.dart';
import 'package:test_project/productWidget.dart';
class GridSelect extends StatelessWidget {
final _controller = Get.put(ProductController());
GridSelect({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
crossAxisCount: 2,
children: List.generate(_controller.addOnProducts.length, (index) => ProductWidget(index: index))
),
);
}
}
在您的產品控制器類中,洗掉該實體,因為它并不重要。這是這里唯一的變化:
產品控制器.dart
import 'package:get/get.dart';
import 'package:test_project/models/productModel.dart';
class ProductController extends GetxController {
RxList<CheckProduct> addOnProducts = <CheckProduct>[].obs;
@override
void onReady() {
super.onReady();
addOnProducts.add(CheckProduct(product: ProductModel('productOne', 20)));
addOnProducts.add(CheckProduct(product: ProductModel('productTwo', 25)));
addOnProducts.add(CheckProduct(product: ProductModel('productThree', 30)));
addOnProducts.add(CheckProduct(product: ProductModel('productFour', 40)));
}
}
class CheckProduct {
ProductModel product;
RxBool selected = false.obs;
CheckProduct({
required this.product,
});
}
最后,您的 productWidget 類需要一個必需的值索引。因此,小部件知道用戶正在單擊 gridview 中的哪個索引,并在此處的復選框中使用 Obx(),因為您在此處選擇了一個可觀察的值。當你有一個 obs 值時,請記住始終使用 Obx() 。這將在 obs 值更改時更新小部件。在這里,如果您注意到我們使用的是 Get.find() 而不是 Put,因為 Get.put 已經在范圍內,所以您需要做的就是找到您將使用的控制器。您可以根據需要查找或放置多個控制器并更新值。
productWidget.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:test_project/controllers/productController.dart';
class ProductWidget extends StatelessWidget {
final ProductController _controller = Get.find();
final int index;
ProductWidget({Key? key, required this.index}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
margin: EdgeInsets.all(20),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 4,
left: 4,
child: Obx(()=>Checkbox(
value: _controller.addOnProducts[index].selected.value,
onChanged: (value) {
print("value of the value is : $value");
print("value of product selected before is: "
_controller.addOnProducts[index].selected.toString());
_controller.addOnProducts[index].selected.value = value!;
print("value of product selected after is: "
_controller.addOnProducts[index].selected.toString());
},
)),
)
],
),
);
}
}
閱讀 GetX 檔案以正確使用 GetX。即使我在 Playstore 中有 2 個使用 GetX 的應用程式,我仍然會不時查看檔案。他們有關于如何管理狀態的清晰檔案。
uj5u.com熱心網友回復:
在 ProductWidget 添加一個額外的 Obx() 解決了我的問題
class ProductWidget extends StatelessWidget {
final CheckProduct product;
const ProductWidget({Key? key, required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
margin: EdgeInsets.all(10),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 4,
left: 4,
// Even the child needs Obx() ; The parent's Obx() is not reflected here
child: Obx(()=>(Checkbox(
value: product.selected,
onChanged: (value) {
print("value of the value is : $value");
print("value of product selected before is: "
product.selected.toString());
product.selected = value!;
print("value of product selected after is: "
product.selected.toString());
},
),))
),
],
));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/484330.html
