#flutter #dart
#flutter #dart
Вопрос:
У меня есть контейнер для показа отзывов пользователей. Контейнер имеет некоторые свойства, такие как изображение профиля, рейтинг и т.д. В нижней части контейнера я хочу поместить текст обзора, и если он слишком длинный, сделайте надпись «читать больше» / «читать меньше» и отрегулируйте размер контейнера. Это код, который я использую:
Container(
height: 500.0,
width: double.infinity,
child: ReviewListWidget(userProfile: userProfile),
)
Some constrais...
class ReviewListWidget extends StatefulWidget {
final UserProfile userProfile;
const ReviewListWidget({
@required this.userProfile,
});
@override
_ReviewListWidgetState createState() => _ReviewListWidgetState();
}
class _ReviewListWidgetState extends State<ReviewListWidget> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return _buildView(context);
}
void onTapReadMore(bool _flag) {
setState(() => _flag = !_flag);
}
Widget _buildView(BuildContext context) {
final Size size = MediaQuery.of(context).size;
String firstHalf;
String secondHalf;
bool _flag = true;
return ListView.builder(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
controller: ScrollController(),
itemCount: widget.userProfile.reviews.length,
itemBuilder: (_, i) {
final review = widget.userProfile.reviews[i];
//Logic to make the body review expandable
if (review.bodyReview.length > 150) {
firstHalf = review.bodyReview.substring(0, 150);
secondHalf =
review.bodyReview.substring(150, review.bodyReview.length);
} else {
firstHalf = review.bodyReview;
secondHalf = "";
}
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(...Here Goes the profile picture, etc.),
SizedBox(height: 12),
secondHalf.isEmpty
? Text(firstHalf)
: Column(
children: <Widget>[
new Text(_flag
? (firstHalf "...")
: (firstHalf secondHalf)),
new InkWell(
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Text(
_flag ? "Read more" : "Read less",
style: new TextStyle(color: Colors.blue),
),
],
),
onTap: () => onTapReadMore(_flag),
),
],
),
);
},
);
}
}
Проблема с этой реализацией заключается в том, что когда я нажимаю кнопку, значение _flag не обновляется.
Ответ №1:
Вы должны поместить _flag
переменную в класс, иначе _buildView
метод создаст новую переменную со true
значением при каждой сборке. Итак, код должен выглядеть следующим образом:
class _ReviewListWidgetState extends State<ReviewListWidget> {
bool _flag = true;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return _buildView(context);
}
void onTapReadMore() {
setState(() => _flag = !_flag);
}
Widget _buildView(BuildContext context) {
final Size size = MediaQuery.of(context).size;
String firstHalf;
String secondHalf;
return ListView.builder(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
controller: ScrollController(),
itemCount: widget.userProfile.reviews.length,
itemBuilder: (_, i) {
final review = widget.userProfile.reviews[i];
//Logic to make the body review expandable
if (review.bodyReview.length > 150) {
firstHalf = review.bodyReview.substring(0, 150);
secondHalf =
review.bodyReview.substring(150, review.bodyReview.length);
} else {
firstHalf = review.bodyReview;
secondHalf = "";
}
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(...Here Goes the profile picture, etc.),
SizedBox(height: 12),
secondHalf.isEmpty
? Text(firstHalf)
: Column(
children: <Widget>[
new Text(_flag
? (firstHalf "...")
: (firstHalf secondHalf)),
new InkWell(
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Text(
_flag ? "Read more" : "Read less",
style: new TextStyle(color: Colors.blue),
),
],
),
onTap: () => onTapReadMore(),
),
],
),
);
},
);
}
}
Комментарии:
1. Помещение _flag туда, где вы сказали, не устраняет проблему. Происходит то же самое, каждый раз, когда я нажимаю кнопку, переменная инициализируется как true : (
2. @Jsancs вам также необходимо удалить определение переменной из buildView, как я это сделал
3. О, это правда, теперь это работает 🙂 Есть идея сделать высоту контейнера такой же высокой, как и текст? Большое вам спасибо
4. @jsancs на самом деле нет. Я думаю, вам нужно покопаться в MediaQuery.