我有一個 Grid.View.builder 里面有按鈕。我希望一次只能選擇一個按鈕!
目前我可以選擇按鈕,但是當我選擇其他按鈕時,前一個按鈕保持選中狀態。
我怎樣才能做到這一點?在 my_card_grid.dart 或 my_card.dart 中?
這是 my_card_grid.dart
import 'package:flutter/material.dart';
import 'package:cards/widgets/my_card.dart';
import 'package:provider/provider.dart';
import 'package:cards/Models/card_data.dart';
class CardsGrid extends StatelessWidget {
const CardsGrid({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<MyCardData>(
builder: (context, cardData, child) {
return Padding(
padding: const EdgeInsets.all(10),
child: GridView.builder(
clipBehavior: Clip.none,
itemBuilder: (context, index) {
final card = cardData.cards[index];
return MyCard(
cardTitle: card.name,
pickerColor: card.cardColor,
deleteCallback: () {
cardData.deleteCallback(card);
},
);
},
itemCount: cardData.cardCount,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
childAspectRatio: 2.5 / 1,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
),
);
},
);
}
}
這是 my_card.dart
import 'package:cards/Models/card.dart';
import 'package:cards/Screens/add_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:cards/Models/card_data.dart';
import 'package:provider/provider.dart';
class MyCard extends StatefulWidget {
late String cardTitle;
Color pickerColor;
final VoidCallback deleteCallback;
MyCard(
{required this.cardTitle,
required this.pickerColor,
required this.deleteCallback});
@override
State<MyCard> createState() => _MyCardState();
}
class _MyCardState extends State<MyCard> {
bool selectedCard = false;
@override
Widget build(BuildContext context) {
return TextButton(
onLongPress: () => showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
actionsAlignment: MainAxisAlignment.spaceEvenly,
title: Center(
child: Text(
widget.cardTitle,
style: TextStyle(
color: widget.pickerColor,
fontWeight: FontWeight.bold,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.3),
offset: Offset(0, 0),
blurRadius: 15,
),
],
),
),
),
content: const Text(
'M?chtest du die Karte wirklich l?schen?',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
),
),
actions: <Widget>[
TextButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
)),
elevation: MaterialStateProperty.all(10),
backgroundColor: MaterialStateProperty.all(Colors.white)),
onPressed: () {
widget.deleteCallback();
Navigator.pop(context);
},
child: const Text(
'Karte l?schen',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
),
),
TextButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
elevation: MaterialStateProperty.all(10),
backgroundColor: MaterialStateProperty.all(Colors.white)),
onPressed: () => Navigator.pop(context),
child: const Text(
'Abbrechen',
style: TextStyle(color: Colors.black, fontSize: 16),
),
),
],
),
),
style: ButtonStyle(
side: MaterialStateProperty.all(BorderSide(
width: 5, color: selectedCard ? Colors.black : Colors.white)),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
backgroundColor: MaterialStateProperty.all(widget.pickerColor),
elevation: MaterialStateProperty.all(10)),
onPressed: () {
print(selectedCard);
setState(() {
selectedCard = !selectedCard;
});
},
child: FittedBox(
fit: BoxFit.fitHeight,
child: Text(
widget.cardTitle,
style: TextStyle(
fontSize: 17,
color: useWhiteForeground(widget.pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
),
),
),
);
}
}

uj5u.com熱心網友回復:
只是一個快速的想法,我認為我們可以通過進行以下修改來實作這一點,這基本上將選擇資訊傳播給父級:
- 更改
MyCard為StatelessWidget,isSelected用于渲染目的 - 修改
CardsGrid并StatefulWidget添加一個 stateint selectedIdx。 - 將組件包裹
MyCard在里面GestureDector進行調整selected可能是這樣的:
GestureDetector(
onTap() => setState(() => selected = index),
child: MyCard(selected == index),
)
根據要求,對于第 2 步,
class CardsGrid extends StatefulWidget {
CardsGrid({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _CardsGridState();
}
class _CardsGridState extends State<CardsGrid> {
int selectedIdx = -1; // or mark as late and initialize in initState() if u prefer
@override
Widget build(BuildContext context) {
return Consumer<MyCardData>(
builder: (context, cardData, child) {
return Padding(
padding: const EdgeInsets.all(10),
child: GridView.builder(
clipBehavior: Clip.none,
itemBuilder: (context, index) {
final card = cardData.cards[index];
return GestureDetector( // ADD
onTap: () => setState(() => selectedIdx = index), // ADD
child: MyCard(
selected: index == selectedIdx, // ADD
cardTitle: card.name,
pickerColor: card.cardColor,
deleteCallback: () {
cardData.deleteCallback(card);
},
), // ADD
);
},
itemCount: cardData.cardCount,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
childAspectRatio: 2.5 / 1,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
),
);
},
);
}
}
2022 年 10 月 10 日更新:根據要求,這是示例代碼,可以將其粘貼到您的 dartpad 在線試用
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: CardsHolderWidget(),
),
),
);
}
}
class CardsHolderWidget extends StatefulWidget {
const CardsHolderWidget({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _CardsHolderWidgetState();
}
class _CardsHolderWidgetState extends State<CardsHolderWidget> {
int selected = -1;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemBuilder: (context, index) => GestureDetector(
onTap: () => setState(() => selected = index),
child: CardWidget(selected == index, '$index'),
),
);
}
}
class CardWidget extends StatelessWidget {
final bool selected;
final String index;
const CardWidget(this.selected, this.index, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: selected ? Colors.red : Colors.blue,
child: Text(index),
);
}
}
uj5u.com熱心網友回復:
如果你想要一個單選按鈕的邏輯,它應該看起來像一個單選按鈕。在https://material.io/components/radio-buttons了解更多資訊。那里也有用于實作的示例 Flutter 代碼。
uj5u.com熱心網友回復:
因此,我找到了另一篇文章并嘗試在我的文章中實作它。
有用!
但是,我無法取消選擇專案。任何人的想法?
這是代碼
class MyCard extends StatefulWidget {
late String cardTitle;
Color pickerColor;
final VoidCallback deleteCallback;
bool isSelected = false;
Function(int) selectedCard;
final int index;
MyCard(
this.selectedCard, {
Key? key,
required this.isSelected,
required this.cardTitle,
required this.pickerColor,
required this.deleteCallback,
required this.index})
: super(key: key);
@override
State<MyCard> createState() => _MyCardState();
}
class _MyCardState extends State<MyCard> {
@override
Widget build(BuildContext context) {
return TextButton(
onLongPress: () => showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
actionsAlignment: MainAxisAlignment.spaceEvenly,
title: Center(
child: Text(
widget.cardTitle,
style: TextStyle(
color: widget.pickerColor,
fontWeight: FontWeight.bold,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.3),
offset: Offset(0, 0),
blurRadius: 15,
),
],
),
),
),
content: const Text(
'M?chtest du die Karte wirklich l?schen?',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
),
),
actions: <Widget>[
TextButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
)),
elevation: MaterialStateProperty.all(10),
backgroundColor: MaterialStateProperty.all(Colors.white)),
onPressed: () {
widget.deleteCallback();
Navigator.pop(context);
},
child: const Text(
'Karte l?schen',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16),
),
),
TextButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
elevation: MaterialStateProperty.all(10),
backgroundColor: MaterialStateProperty.all(Colors.white)),
onPressed: () => Navigator.pop(context),
child: const Text(
'Abbrechen',
style: TextStyle(color: Colors.black, fontSize: 16),
),
),
],
),
),
style: ButtonStyle(
side: MaterialStateProperty.all(BorderSide(
width: 5, color: widget.isSelected ? Colors.black : Colors.white)),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
backgroundColor: MaterialStateProperty.all(widget.pickerColor),
elevation: MaterialStateProperty.all(10)),
onPressed: () {
widget.selectedCard(widget.index);
},
child: FittedBox(
fit: BoxFit.fitHeight,
child: Text(
widget.cardTitle,
style: TextStyle(
fontSize: 17,
color: useWhiteForeground(widget.pickerColor)
? const Color(0xffffffff)
: const Color(0xff000000),
),
),
),
);
}
}
class CardsGrid extends StatefulWidget {
CardsGrid({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _CardsGridState();
}
class _CardsGridState extends State<CardsGrid> {
int _selectedCard = -1;
selectedCard(index) {
setState(() {
_selectedCard = index;
});
}
@override
Widget build(BuildContext context) {
return Consumer<MyCardData>(
builder: (context, cardData, child) {
return Padding(
padding: const EdgeInsets.all(10),
child: GridView.builder(
clipBehavior: Clip.none,
itemBuilder: (context, index) {
final card = cardData.cards[index];
return MyCard(
selectedCard,
index: index,
isSelected: _selectedCard == index,
cardTitle: card.name,
pickerColor: card.cardColor,
deleteCallback: () {
cardData.deleteCallback(card);
},
);
},
itemCount: cardData.cardCount,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
childAspectRatio: 2.5 / 1,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
),
);
},
);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/513947.html
標籤:扑按钮主题颤动状态扑扑的
上一篇:動態庫的運行時與鏈接時鏈接
