Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In flutter, how do we create a text widget, which will show just one line of a text , but it will expand to show all the contents of the text when clicked?
Welcome to the flutter world.
The widget you are looking for is ExpansionTile:
A simple code example:
ExpansionTile(
title: Text('My Expansion Tile'),
children: <Widget>[
Text('Item 1'),
Text('Item 2')],
),
Personally though, I use the Expandable package, which is an expansion tile on steroids.
If offers improved control and customisability. Check out their docs that have some really good examples.
Just try your code with Flexible class.
You can find the reference here, here. Or, read the docs here.
Hope it will help.
If i understand well you want only a part of the text to be show initially and when tapped on it expands or contracts back.
Try this custom stateful widget i implemented bellow..hope it helps
class ExpandableText extends StatefulWidget {
ExpandableText({this.text = ""});
//text is the total text of our expandable widget
final String text;
#override
_ExpandableTextState createState() => _ExpandableTextState();
}
class _ExpandableTextState extends State<ExpandableText> {
String textToDisplay;
#override
void initState() {
//if the text has more than a certain number of characters, the text we display will consist of that number of characters;
//if it's not longer we display all the text
print(widget.text.length);
//we arbitrarily chose 25 as the length
textToDisplay =
widget.text.length > 25 ? widget.text.substring(0,25)+"..." : widget.text;
super.initState();
}
#override
Widget build(BuildContext context) {
return InkWell(
child: Text(textToDisplay),
onTap: () {
//if the text is not expanded we show it all
if (widget.text.length > 25 && textToDisplay.length <= 25) {
setState(() {
textToDisplay = widget.text;
});
}
//else if the text is already expanded we contract it back
else if (widget.text.length > 25 && textToDisplay.length > 25) {
setState(() {
textToDisplay = widget.text.substring(0,25)+"...";
});
}
},
);
}
}
Related
I have added a rive ❤️ heart animation to a iconButton in flutter. when I tap on it, it animates from Unlike > Like and when I tapped again it animates backwards. Which is perfectly working. But the thing is, when I close the page and reopen the same page, Rive animation animates again from the very beginning (the default state of the animation is outline bordered heart icon, which I have to tap on it to make ❤️ filled heart icon). So the problem is if I like an item, close the page and then reopened the page I have to tap on it again, in order to make the item favorite or not. I also created a isFavorite bool to tack the icon button state, the thing is I don't know how to sync the bool with rive animation.
So this is what I want: I need the riveAnimation to stay liked or unliked according to the state of isFavourite bool + Unlike, Dislike transition animation. This may be hard to understand. Please leave a comment what part is that you do not understand.
Rive Animation I Used (go to rive)
class Place with ChangeNotifier {
bool isFavourite;
Place(
{this.isFavourite = false});
void toggleFavouriteStatus() {
isFavourite = !isFavourite;
notifyListeners();
}
}
.
.
.
.
.
.
.
SMIInput<bool>? _heartButtonInput;
Artboard? _heartButtonArtboard;
#override
void initState() {
super.initState();
rootBundle.load('assets/rive/heart.riv').then(
(data) {
final file = RiveFile.import(data);
final artboard = file.mainArtboard;
var controller = StateMachineController.fromArtboard(
artboard,
'state',
);
if (controller != null) {
artboard.addController(controller);
_heartButtonInput = controller.findInput('Like');
}
setState(() => _heartButtonArtboard = artboard);
},
);
}
#override
Widget build(BuildContext context) {
final Fav = Provider.of<Place>(context); // I used provider package to retrieve bool data
void _heartButtonAnimation() {
if (_heartButtonInput?.value == false &&
_heartButtonInput?.controller.isActive == false) {
_heartButtonInput?.value = true;
} else if (_heartButtonInput?.value == true &&
_heartButtonInput?.controller.isActive == false) {
_heartButtonInput?.value = false;
}
}
return Stack(
alignment: Alignment.bottomCenter,
children: [
Positioned(
right: 8,
top: 8,
child: Container(
child: Center(
child: Material(
color: Colors.transparent,
child: _heartButtonArtboard == null
? const SizedBox()
: IconButton(
onPressed: () {
Fav.toggleFavouriteStatus();
_heartButtonAnimation();
},
icon: Rive(
artboard: _heartButtonArtboard!,
fit: BoxFit.cover,
),
),
),
),
),
)
],
);
}
}
I'm not sure if I understood correctly. When your record is already given a heart, then after revisiting it, you want the heart to be displayed in "liked" state without running animating it. Is that it?
If so, IMO the problem is within your state machine not allowing the animation to be started in the desired state of "liked". For the heart to get to the liked state, it needs to pass through the liking animation. This is how your state machine looks now:
You should define two paths from Entry state depending on the value of your Like input. Take a look at a state machine from a checkbox I've imported to Flutter lately. Each of the "idle" timelines have only one keyframe for being checked or unchecked. On entry, there's an intersection where a decision is made based on the initial value of checked input.
This way you can display your heart in the desired state without any animation happening when the widget is built.
this is Antika. I have started learning to code since a few days back, and am only familiar with HTML/CSS/JS, and basics of dart/flutter
Developer Level: Beginner
Project type & language: I'm developing a Simple Notepad App, using flutter.
In my Project,
I want to dynamically add new TextField widgets on the screen, once the user hits enter or clicks the next button ('➡️'), in mobile devices, Just after the TextField in focus, and not to the end of the List.
Outline
User types text >> Clicks Submit >> Keeping in mind TextField in focus >> Add another TextField just after this one. >> The User feels like entering a new line.
For e.g., as is shown in the image below.
You could use a list with initially one TextField widget and onSubmitted adds another TextField to the list.
class MyWidget
extends StatefulWidget {
MyWidget({Key? key}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
List<TextField> textFields = [];
#override
void initState(){
super.initState();
textFields.add(_buildTextField());
}
#override
Widget build(BuildContext context) {
return ListView(
children: textFields
);
}
TextField _buildTextField(){
return TextField(
autofocus: true,
onSubmitted: (_){
setState((){
textFields.add(_buildTextField());
});
}
);
}
}
I'm Developing Flutter Mobile Application. I want to Navigate another Page(With the Bottom Tab bar as display in the Picture) and I want to select a dropdown within the navigation's page. I think My problem is clear to you.
I Don't want to push that page.
And I don't want to duplicate My global Key
I added some screenshots of my app and numbers to understand you.
By Using a provider you can easily navigate between Navigation Tabs
Create a Provider for TabBar:
class MainTabProvider extends ChangeNotifier {
int _currentIndex = 0;
int get currentIndex {
return _currentIndex;
}
void setIndex(int index) {
_currentIndex = index;
notifyListeners();
}
}
Wrap you Tabbar with the Consumer
#override
Widget build(BuildContext context) {
return Consumer<MainTabProvider>(
builder: (context, data, child) => Scaffold(
backgroundColor: Colors.white,
body: _children[data.currentIndex],
......
Change Index from anywhere:
Provider.of<MainTabProvider>(context, listen: false).setIndex(2)
I'm receiving a list of images that I want to display dynamically in rows of 4 items each row. If there are 5 itens the row should wrap. The thing is, I need the images to allow for a longpress click that opens edit buttons in the appBar. Besides the edit button when longing pressing, it should allow for multiple selecting the other images.
Could this code be adapted for that:
class cardy extends StatefulWidget {
#override
_cardyState createState() => new _cardyState();
}
class _cardyState extends State<cardy> {
var isSelected = false;
var mycolor=Colors.white;
#override
Widget build(BuildContext context) {
return new Card(
color: mycolor,
child: new Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
new ListTile(
selected: isSelected,
leading: const Icon(Icons.info),
title: new Text("Test"),
subtitle: new Text("Test Desc"),
trailing: new Text("3"),
onLongPress: toggleSelection // what should I put here,
)
]),
);
}
void toggleSelection() {
setState(() {
if (isSelected) {
mycolor=Colors.white;
isSelected = false;
} else {
mycolor=Colors.grey[300];
isSelected = true;
}
});
}
}
Yes, this code can be adapted for that ;)
To start, check out SliverGrid class.
https://api.flutter.dev/flutter/widgets/SliverGrid-class.html
Here is a (not complete) snippet to get you started, but you'll have to specify what options you want to use because this will not copy and paste solve your problem:
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 5,
crossAxisSpacing: 3,
crossAxisCount,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container()})),
I'll note that if you want to use the information you're gathering, namely which images you're selecting, do take care to store that information somewhere. That is, your example toggles selection for a single item, but how will you get that information later? That is, if you click 3 items then hit edit, you need a way to record which 3 items have been selected. One option is maintaining a list and .removing / .adding it as part of your toggle.
I'm building a Workout Tracker app using Flutter and Dart. On the tracking page are lists of exercises and a done Icon, when clicked, changes its color(To show that you're done with the set). Icon state changes locally in the file.
So the problem is when I scroll down, the upper items revert back to their original state. Long story short, I don't want the icons to Rerender on demand and save their state until I want to.
Tried AutomaticKeepAliveStateMixin but it doesn't seem to be working. I'm a newbie in coding so maybe I am implementing it wrong.
class _ExerciseInputState extends State<ExerciseInput>
with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
var deviceSize = MediaQuery.of(context).size;
return ListView.builder(
itemCount: widget.loadedRoutine.exercises.length,
itemBuilder: (BuildContext context, int i) {
return buildExerciseContainer(
widget.loadedRoutine.exercises[i].title,
widget.loadedRoutine.exercises[i].sets,
widget.loadedRoutine.exercises[i].reps,
deviceSize,
context);
},
);
}
}
No error messages.