Nothing is working to get multiline text to be wrapped with Right aligment
#override
Widget build(BuildContext context) {
var tt = "ومن رأى: أن إبرته التي يخيط بها انكسرت أو انتزعت منه، فإن شأنه يتفرق ويفسد أمره، وتدل الإبرة أيضاً على المرأة لإدخال الخيط فيها، وكذلك المسلة، فمن رأى أن بيده مسلة وكانت إمرأته حبلى ولدت له إبنة، وإن لم يكن هناك حمل دل ذلك على سفره.";
return new Scaffold(
appBar: new AppBar(
title: new Text(gettitle()) ,
),
body:
new Directionality(textDirection: TextDirection.rtl, child:
new Padding(
padding: const EdgeInsets.all(16.0),
child:
new SingleChildScrollView(
child:
new Text(
tt,
textAlign: TextAlign.right,
textDirection: TextDirection.rtl,
)
,)
),
)
);
}
Doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.3.2, on Mac OS X 10.13.4 17E202, locale en-JO)
[✓] Android toolchain - develop for Android devices (Android SDK 27.0.2)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.3)
[✓] Android Studio (version 3.0)
[✓] Connected devices (1 available)
• No issues found!
Process finished with exit code 0
I'm pretty sure this is a bug. As you say, it seems to only happen with multi-line text. With this minimal example:
#override
Widget build(BuildContext context) {
return new Directionality(
textDirection: TextDirection.rtl,
child: new Scaffold(
appBar: new AppBar(
title: new Text(ttrtl2),
),
body: new Padding(
padding: const EdgeInsets.only(right: 10.0),
child: new Text(
ttrtl,
style: new TextStyle(fontSize: 24.0),
),
),
),
);
}
the starting characters are not missing, but only because I have added padding on the right. It doesn't seem to be a problem with the SingleChildScrollView, because I can reproduce it with the code above. (Incidentally, SingleChildScrollView can take padding, so the same work around works.)
If you toggle Debug Paint you can see that the leading characters overlap the padding, which is why, when there is no padding, the leading characters are truncated.
You could switch to the dev channel, and try again. Or live with adding a few pixels of right padding. Or check for existing issues (I didn't see one, myself) and enter an issue.
Debug Paint Screenshot shows the text bleeding into the padding...
Related
How One UI looks on iPhone 14 Pro Max and other phones.
The code written in Flutter is as follows:
return SafeArea(
child: SmartRefresher(
controller: controller.balanceRefreshController,
onRefresh: () => controller.onRefreshBalance(),
child: Padding(
padding: EdgeInsets.all(AppPaddings.side),
child: Column(
children: [
// #Balance
_getBalanceWidget(controller),
// #choose amount
Expanded(child: _getChooseAmountWidget(controller)),
// #button
_getActivatedDefaultButton(controller),
],
),
),
));
With BalanceWidget, the remaining space allocated to the button should have been left to _getChooseAmountWidget.
But why didn't it happen?
(I know how to show button in UI. For example I can use Stack. I wonder why the code doesn't work properly, not show the button)
Some cases:
If _getChooseAmountWidget has 4 items:
If I remove Expanded:
// #Balance
_getBalanceWidget(controller),
// #choose amount
// Expanded(child: _getChooseAmountWidget(controller)),
// #button
ActivatedDefaultButton(
isActive: controller.selectedItem != null,...
So i'm emulating an old app I have where the UI looks like this
Currently i'm focused on creating the UI layout for the purple side bar, I did that by creating a Container with a purple background. Within the container I created a column with multiple children and just used an empty SizedBox to create distance between one widget from another.
import 'package:flutter/material.dart';
class SignInPage extends StatelessWidget {
const SignInPage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text('Sample Text'),
// elevation: 5.0,
// ),
body: _buildContent(),
);
}
Widget _buildContent() {
// private method
return Container(
color: Colors.deepPurpleAccent,
padding: EdgeInsets.all(16.0),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
color: Colors.orange,
child: SizedBox(
height: 100.0,
width: 80.0,
),
),
SizedBox(
height: 140.0,
),
Container(
color: Colors.red,
child: SizedBox(
height: 50.0,
width: 80.0,
),
),
SizedBox(
height: 8.0,
),
Container(
color: Colors.purple,
child: SizedBox(
height: 50.0,
width: 80.0,
),
),
],
),
);
}
}
I'm quite new to flutter so i'm wondering if there's a better way to structure my layout of the side bar? Also to think in the future, since the name "BagTrack" Is on the same level as "Analytic Overview" Should that just be one giant row"?
Actual answer
Method 1
#Mahfuzur Rahman answer is good, but to actually answer your question about other ways. Flex widgets (Column and Row extend the Flex widget), have both mainAxisAlignment and crossAxisAlignment, they can be used to align them more easily between different devices/screens sizes.
So maybe grouping your red and purple boxes in a Column with mainAxisSize set to MainAxisSize.min, and aligning the surrounding column with a specific size.
https://api.flutter.dev/flutter/widgets/Column-class.html
Method 2
Another way, if you would like some widget to occupy some percentage amount of space from it's parent, I suggest you look into Expanded widget, Flexible widget.
Method 3
Or even FractionallySizedBox could be a good widget for you, but then I would also look at this LayoutBuilder widget to solve the potential Unbounded Height/Width exception.
Second smaller question
It's entirely up to you to decide about your second question concerning the giant row. I wouldn't do it though. Probably would use a const SizedBox or const EdgeInsets (for Padding) and keep them at the same height this way.
Just complementing Flutter knowledge
PS: Since you are new to Flutter. As a suggestion for future performance: avoid the Container widget as much as you know, there are a lot of simpler widgets like SizedBox, ColoredBox, DecoratedBox and Padding that you can use in its place that could be marked as const sometimes and be less expensive.
For understanding final and const:
final is a variable that cannot be reassigned by accident inside your code. When you instantiate it you give it a value and that's it. (Using late changes that a bit but not much);
const is a variable assigned by the compiler, if you are familiar with C it's like #define but there is a little difference, every time you say const EdgeInsets.all(8) for example, the compiler will detect that and use the same variable, so you don't have to remember a specific constant variable name.
Yes there is. But using SizedBox also wont hurt.
I usually Prefer ListTile for each element in the drawer.
ListTile(
leading: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {},
child: Container(
width: 48,
height: 48,
padding: const EdgeInsets.symmetric(vertical: 4.0),
alignment: Alignment.center,
child: const CircleAvatar(),
),
),
title: const Text('title'),
dense: false,
)
After doing flutter upgrade yesterday the content of ListTile leading (especially the height) does not match parent anymore.
I have a overflow in height now. Width is working as expected.
As you can see in the picture there is still space below the leading widget.
Does anyone know how to fix this?
Or is there a way to downgrade the flutter version?
Widget _listTile(){
return ListTile(
contentPadding: EdgeInsets.fromLTRB(3.0, 1.0, 0.0, 1.0),
dense: true,
leading: Column(
children: <Widget>[
_leadingButton(),
_leadingProgress
],
),
title: _textSubtitle(subtitle),
subtitle: _textSubtitle(subtitle),
);
}
I believe the change that has caused this is [this one][1]: https://github.com/flutter/flutter/commit/0e2eeb5a485aaccdab7007ad9b90fd8120e77983#diff-53f33273ae4e7462729c5f4b7394428b. If you read the code, it says it was doing an update to adhere to the material spec which means a constraint on the size of the widget, so there's a very good chance it won't change back to how it was. How you were using it was technically against the material spec.
But rather than trying to downgrade flutter, you could simply create your own widget that does the same thing - you don't need to use a ListTile.
Something like this would probably do:
class MyListTile extends StatelessWidget {
final Widget leading;
final Widget title;
final Widget subtitle;
final EdgeInsets padding;
MyListTile({#required this.leading, #required this.title, #required this.subtitle, this.padding});
#override
void build(BuildContext context) {
return Padding(
padding: padding ?? EdgeInsets.zero,
child: Row(
children: [
leading,
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
title,
subtitle,
],
),
),
],
),
);
}
}
Full disclosure though - I haven't run that code or even put it in an IDE so it may have issues, but that should illustrate the basics of what you're trying to do there. You'd probably want to wrap things in padding (most likely at least the leading widget) as needed to get the spacing you currently have.
How do I position a FloatingActionButton on the left side inside a Scaffold?
Currently the only available options are centerFloat, centerDocked, endFloat and endDocked.
Maybe Material Design does not intend to position the FAB at startFloat or startDocked.
That would be fine if RTL changed endFloat and endDocked to appear on the left side, but that is not the case.
In April 2020, the available options have been expanded and startFloat as well as startDocked are included options now.
Here is the full list of available options (see the FloatingActionButtonLocation documentation):
centerDocked
centerFloat
centerTop
endDocked
endFloat
endTop
miniCenterDocked
miniCenterFloat
miniCenterTop
miniEndDocked
miniEndFloat
miniEndTop
miniStartDocked
miniStartFloat
miniStartTop
startDocked
startFloat
startTop
You can even easily define your own locations using StandardFabLocation.
As of 2020, you can use the following:
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat
A parameter that can be passed to the Scaffold Widget from material.dart
Source: PR 51465
There is also another solution to this problem. Fab button by default is always at the bottom end of the screen. So if we wrap our Scaffoldwith a Directionality and set its text direction to TextDirection.rtl, then the button goes left. but since now the body itself is mirrored, we can wrap the body with another Directionality and set its text direction to TextDirection.ltr
#override
Widget build(BuildContext context) {
return
Directionality(
textDirection: TextDirection.rtl,
child:Scaffold(
appBar: AppBar(
title: const Text('Something),
),
body: Directionality(
textDirection: TextDirection.ltr,
child: Center(child: const Text('Press the button below!'))),
floatingActionButton: FloatingActionButton(
onPressed: () {
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
)
);
}
I'm trying to hit an object behind the top most visible object. I was trying to achieve this by using the GestureDetector's behavior property.
The code for this is as follows:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: () => print("Bottom"),
child: new Container(
color: Colors.redAccent,
child: new Center(
child: new GestureDetector(
onTap: () => print("Top"),
behavior: HitTestBehavior.translucent,
child: new Container(
width: 200.0,
height: 200.0,
color: Colors.blue.withOpacity(0.3),
),
),
),
),
);
}
}
Unfortunately, this doesn't seem to work. Only Top gets printed to the console. The docs make it seem like this is the correct way of doing it, but perhaps I'm missing something here?
I want the bottom one or both to receive the onTap event tbh.
If just getting the Bottom event is fine, then simply removing:
onTap: () => print("Top"),
Works for me. After commenting out that line, it prints Bottom when I tap on the inner square.
Tested with this version:
Dannys-MacBook:flutter danny$ flutter --version
Flutter 0.4.5-pre.96 • channel master • https://github.com/DanTup/flutter.git
Framework • revision d79f2ee223 (12 hours ago) • 2018-05-26 12:29:53 -0700
Engine • revision 1ed25ca7b7
Tools • Dart 2.0.0-dev.58.0.flutter-f981f09760
That said, removing the inner GestureDetector does the same to, so I'm wondering if there's some reason you added it?