[英]How to wrap large text inside a row in flutter
我已經檢查了有關該問題的大部分 StackOverflow QA,但無法確定正確的實現:
請建議我在_getItemRow
中實施正確的修改。 下面是代碼:
Widget _getItemRow(String item1, String item2, {bool linkify = false}) {
return Wrap(
children: <Widget>[
Wrap(
children: <Widget>[
Text(
item1,
style: Theme.of(context).textTheme.body1.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
Wrap(
children: <Widget>[
linkify
? Wrap(
children: [
RichText(
text: TextSpan(
text: item2,
style: Theme.of(context)
.textTheme
.body1
.copyWith(fontSize: 16),
recognizer: TapGestureRecognizer()
..onTap = () async {
if (await canLaunch(item2)) {
await launch(item2);
} else {
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("Could not open url"),
duration: Duration(seconds: 3),
));
}
},
),
),
],
)
: Wrap(
children: <Widget>[
Text(
item2,
style: Theme.of(context).textTheme.body1,
),
],
),
],
),
],
);
}
ExpansionTile _getExpansionTile(String title, List<Widget> itemWidgetsList) {
return ExpansionTile(
title: Text(
title,
style: Theme.of(context).textTheme.subhead,
),
initiallyExpanded: true,
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: itemWidgetsList),
),
],
),
],
);
Widget _productGeneralWidget() {
Widget productGeneralWidget = SizedBox.shrink();
if (isProductDataReady &&
((productDetails.containsKey("sku")) ||
productDetails.containsKey("slug") ||
productDetails.containsKey("status") ||
productDetails.containsKey("type") ||
productDetails.containsKey("featured") ||
productDetails.containsKey("total_sales"))) {
List<Widget> productGeneralWidgetData = [];
if (productDetails.containsKey("id") && productDetails["id"] is int) {
productGeneralWidgetData.add(
_getItemRow("Id: ", "${productDetails["id"]}"),
);
}
if (productDetails.containsKey("slug") &&
productDetails["slug"] is String &&
productDetails["slug"].isNotEmpty) {
productGeneralWidgetData.add(
_getItemRow("Slug: ", "${productDetails["slug"]}"),
);
}
if (productDetails.containsKey("permalink") &&
productDetails["permalink"] is String &&
productDetails["permalink"].isNotEmpty) {
productGeneralWidgetData.add(
_getItemRow("Permalink: ", "${productDetails["permalink"]}"),
);
}
if (productDetails.containsKey("type") &&
productDetails["type"] is String &&
productDetails["type"].isNotEmpty) {
productGeneralWidgetData.add(
_getItemRow("Type: ", "${productDetails["type"]}"),
);
}
if (productDetails.containsKey("sku") &&
productDetails["sku"] is String &&
productDetails["sku"].isNotEmpty) {
productGeneralWidgetData.add(
_getItemRow("Sku: ", "${productDetails["sku"]}"),
);
}
if (productDetails.containsKey("status") &&
productDetails["status"] is String &&
productDetails["status"].isNotEmpty) {
productGeneralWidgetData.add(_getItemRow(
"Status: ", productDetails["status"].toString().titleCase));
}
if (productDetails.containsKey("catalog_visibility") &&
productDetails["catalog_visibility"] is String &&
productDetails["catalog_visibility"].isNotEmpty) {
productGeneralWidgetData.add(_getItemRow("Catalog visibility: ",
productDetails["catalog_visibility"].toString().titleCase));
}
if (productDetails.containsKey("purchasable") &&
productDetails["purchasable"] is bool) {
productGeneralWidgetData.add(_getItemRow(
"Purchasable: ", productDetails["purchasable"] ? "Yes" : "No"));
}
if (productDetails.containsKey("featured") &&
productDetails["featured"] is bool) {
productGeneralWidgetData.add(
_getItemRow("Featured: ", productDetails["featured"] ? "Yes" : "No"),
);
}
if (productDetails.containsKey("on_sale") &&
productDetails["on_sale"] is bool) {
productGeneralWidgetData.add(
_getItemRow("On Sale: ", productDetails["on_sale"] ? "Yes" : "No"),
);
}
if (productDetails.containsKey("virtual") &&
productDetails["virtual"] is bool) {
productGeneralWidgetData.add(
_getItemRow("Virtual: ", productDetails["virtual"] ? "Yes" : "No"),
);
}
if (productDetails.containsKey("downloadable") &&
productDetails["downloadable"] is bool) {
productGeneralWidgetData.add(
_getItemRow(
"Downloadable: ", productDetails["downloadable"] ? "Yes" : "No"),
);
}
if (productDetails.containsKey("total_sales") &&
productDetails["total_sales"] is String &&
productDetails["total_sales"].isNotEmpty) {
productGeneralWidgetData.add(
_getItemRow("Total ordered: ", "${productDetails["total_sales"]}"),
);
}
if (productDetails.containsKey("backordered") &&
productDetails["backordered"] is bool) {
productGeneralWidgetData.add(
_getItemRow(
"Backordered: ", productDetails["backordered"] ? "Yes" : "No"),
);
}
productGeneralWidget =
_getExpansionTile("General", productGeneralWidgetData);
}
return productGeneralWidget;
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text("Product Details"),
),
body: !isProductDataReady
? !isError ? _mainLoadingWidget() : Text("Error Fetching Data")
: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: fetchProductDetails,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
padding: const EdgeInsets.all(0.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_productHeadlineWidget(),
_productImagesWidget(),
_productGeneralWidget(),
_productPriceWidget(),
_productInventoryWidget(),
_productShippingWidget(),
_productReviewsWidget(),
]),
),
),
floatingActionButton: isProductDataReady
? UnicornDialer(
backgroundColor: Color.fromRGBO(100, 100, 100, 0.7),
parentButtonBackground:
Theme.of(context).floatingActionButtonTheme.backgroundColor,
orientation: UnicornOrientation.VERTICAL,
parentButton: Icon(Icons.add),
childButtons: <UnicornButton>[
UnicornButton(
hasLabel: true,
labelText: "Edit",
currentButton: FloatingActionButton(
heroTag: "edit",
backgroundColor: Colors.purple,
mini: true,
child: Icon(Icons.edit),
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditProductPage(
baseurl: widget.baseurl,
username: widget.username,
password: widget.password,
id: widget.id,
)),
);
if (result is String) {
fetchProductDetails();
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(result.toString()),
duration: Duration(seconds: 3),
));
}
},
)),
UnicornButton(
hasLabel: true,
labelText: "Delete",
currentButton: FloatingActionButton(
heroTag: "delete",
backgroundColor: Colors.redAccent,
mini: true,
child: Icon(Icons.delete),
onPressed: () {},
)),
],
)
: SizedBox.shrink(),
);
}
使用此溢出時引發以下異常
Reloaded 0 of 968 libraries in 1,252ms.
D/FlutterView( 8322): Detaching from a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@c104134
D/FlutterView( 8322): Attaching to a FlutterEngine: io.flutter.embedding.engine.FlutterEngine@c104134
Performing hot reload...
(This is taking an unexpectedly long time.) -I/flutter ( 8322): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 8322): The following assertion was thrown during layout:
I/flutter ( 8322): A RenderFlex overflowed by 187 pixels on the right.
I/flutter ( 8322):
I/flutter ( 8322): The relevant error-causing widget was:
I/flutter ( 8322): Row
I/flutter ( 8322): file:///C:/Users/itsga/Desktop/flutter/woocommerceadmin/lib/src/products/widgets/ProductDetailsPage.dart:339:9
I/flutter ( 8322):
I/flutter ( 8322): The overflowing RenderFlex has an orientation of Axis.horizontal.
I/flutter ( 8322): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter ( 8322): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
I/flutter ( 8322): Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
I/flutter ( 8322): RenderFlex to fit within the available space instead of being sized to their natural size.
I/flutter ( 8322): This is considered an error condition because it indicates that there is content that cannot be
I/flutter ( 8322): seen. If the content is legitimately bigger than the available space, consider clipping it with a
I/flutter ( 8322): ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
I/flutter ( 8322): like a ListView.
I/flutter ( 8322): The specific RenderFlex in question is: RenderFlex#d8b1b relayoutBoundary=up19 OVERFLOWING:
I/flutter ( 8322): creator: Row ← Column ← Align ← ClipRect ← Column ← Padding ← DecoratedBox ← Container ←
I/flutter ( 8322): AnimatedBuilder ← ExpansionTile ← Column ← Padding ← ⋯
I/flutter ( 8322): parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
I/flutter ( 8322): constraints: BoxConstraints(0.0<=w<=360.0, 0.0<=h<=Infinity)
I/flutter ( 8322): size: Size(360.0, 257.0)
I/flutter ( 8322): direction: horizontal
I/flutter ( 8322): mainAxisAlignment: start
I/flutter ( 8322): mainAxisSize: max
I/flutter ( 8322): crossAxisAlignment: center
I/flutter ( 8322): textDirection: ltr
I/flutter ( 8322): verticalDirection: down
I/flutter ( 8322): ◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
I/flutter ( 8322): ════════════════════════════════════════════════════════════════════════════════════════════════════
Reloaded 0 of 968 libraries in 2,420ms.
據我所知,這是因為RichText
小部件未包裝在Wrap
Widget 中,因此很容易修復。
Wrap(
child: RichText(
text: TextSpan(
text: item2,
style: Theme.of(context)
.textTheme
.body1
.copyWith(fontSize: 16),
recognizer: TapGestureRecognizer()
..onTap = () async {
if (await canLaunch(item2)) {
await launch(item2);
} else {
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("Could not open url"),
duration: Duration(seconds: 3),
));
}
},
),
),
)
: Wrap(
child: Text(
item2,
style: Theme.of(context).textTheme.body1,
),
),
好吧,經過一番嘗試和嘗試,在一些幫助下,我可以解決問題。 我必須在我的_getExpansionTile
function 中使用Wrap
更改Row
,它是wrap
小部件之上的頂級小部件,並且不能很好地與其中的 wrap 小部件配合使用。
修改后的代碼:
Widget _getItemRow(String item1, String item2, {bool linkify = false}) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
item1,
style: Theme.of(context).textTheme.body1.copyWith(
fontWeight: FontWeight.bold,
),
),
Flexible(
child: linkify
? RichText(
text: TextSpan(
text: item2,
style: Theme.of(context)
.textTheme
.body1
.copyWith(fontSize: 16),
recognizer: TapGestureRecognizer()
..onTap = () async {
if (await canLaunch(item2)) {
await launch(item2);
} else {
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("Could not open url"),
duration: Duration(seconds: 3),
));
}
},
),
)
: Text(
item2,
style: Theme.of(context).textTheme.body1,
),
),
],
);
}
ExpansionTile _getExpansionTile(String title, List<Widget> itemWidgetsList) {
return ExpansionTile(
title: Text(
title,
style: Theme.of(context).textTheme.subhead,
),
initiallyExpanded: true,
children: <Widget>[
Wrap(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: itemWidgetsList),
),
],
),
],
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.