Flutter Simple 그림판 (5) - 텍스트 컨테이너 줄바꿈 감지, 맞추기(word-character-breaking)(4)
- List를 사용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
Map myFunction() {
String myString = "Hello";
int myInt = 42;
return {"myString": myString, "myInt": myInt}; // Return both values in a map
}
void main() {
var result = myFunction();
String resultString = result["myString"];
int resultInt = result["myInt"];
print('String: $resultString, Int: $resultInt');
}
- Map을 사용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
Map myFunction() {
String myString = "Hello";
int myInt = 42;
return {"myString": myString, "myInt": myInt}; // Return both values in a map
}
void main() {
var result = myFunction();
String resultString = result["myString"];
int resultInt = result["myInt"];
print('String: $resultString, Int: $resultInt');
}
- Tuple을 사용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import 'package:tuple/tuple.dart';
Tuple2 myFunction() {
String myString = "Hello";
int myInt = 42;
return Tuple2(myString, myInt); // Return both values in a tuple
}
void main() {
var result = myFunction();
String resultString = result.item1;
int resultInt = result.item2;
print('String: $resultString, Int: $resultInt');
}
- 커스텀 Class를 사용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyResult {
String myString;
int myInt;
MyResult(this.myString, this.myInt);
}
MyResult myFunction() {
String myString = "Hello";
int myInt = 42;
return MyResult(myString, myInt); // Return both values in a custom class
}
void main() {
var result = myFunction();
print('String: ${result.myString}, Int: ${result.myInt}');
}
여기서 잦은 호출에 의한 계산 부하를 최소화할 수 있는 방법은 커스텀 Class를 사용하는 방법이라고 한다.
줄 바꿈 횟수(lineBreakCount)를 세어서 함께 리턴하는 클래스를 만들었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class BreakTextResult {
final String text;
final int lineBreakCount;
BreakTextResult(this.text, this.lineBreakCount);
}
class TextBreaker {
final String input;
final TextStyle textStyle;
final double containerWidth;
final double containerHeight;
final TextAlign textAlign;
TextBreaker({
required this.input,
required this.textStyle,
required this.containerWidth,
required this.containerHeight,
this.textAlign = TextAlign.left,
});
BreakTextResult breakCharacterWithMeasurement() {
List lines = [];
TextPainter textPainter = TextPainter(
textDirection: TextDirection.ltr,
textAlign: textAlign,
);
List words = input.split(' '); // Split the input into words.
String currentLine = '';
double textWidth;
double textWidthPadding = textStyle.fontSize! * 0.5;
int linesCount = calculateLinesCount(textStyle, containerHeight);
int currentLineCount = 0;
print("containerWidth: $containerWidth");
print("containerHeight: $containerHeight");
for (String word in words) {
// Handle each word
bool isFirstCharacterOfWord = true;
for (int i = 0; i containerWidth) {
if (!isFirstCharacterOfWord || currentLine.isNotEmpty) {
// If the line is not empty, or if it's not the first character of the word, add the current line to the lines list
lines.add(currentLine);
currentLineCount++;
if (currentLineCount >= linesCount) break; // Stop if the maximum number of lines is reached
currentLine = character; // Start a new line with the current character
} else {
// If it's the first character of the word and the line is empty
currentLine = character; // Add the character to the current line
}
isFirstCharacterOfWord = false;
} else {
// If the character fits, add it to the current line
currentLine = testLine;
isFirstCharacterOfWord = false;
}
}
// After processing a word, add a space if it's not the end of a line
if (currentLineCount = linesCount) break;
}
// Add any remaining text in the currentLine to lines, if there's space
if (!currentLine.isEmpty && currentLineCount styleHeight ? measuredHeight : styleHeight;
print("lineHeight: $lineHeight");
// Calculate the number of lines that can fit in the container.
int linesCount = containerHeight ~/ lineHeight;
return linesCount;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
class SquareDetailsScreen extends StatefulWidget {
final double width;
final double height;
SquareDetailsScreen({Key? key, required this.width, required this.height})
: super(key: key);
@override
_SquareDetailsScreenState createState() => _SquareDetailsScreenState();
}
class _SquareDetailsScreenState extends State {
final TextEditingController _textController = TextEditingController();
String formattedText = ""; // State variable for holding formatted text
int maxLength = 1; // State variable for holding the maximum length of the text
final double fontSizeDefault = 20;
final FontWeight fontWeightDefault = FontWeight.bold;
// Initialize textStyle using the default font size and weight
late TextStyle textStyle;
final TextAlign textAlignment = TextAlign.center;
@override
void initState() {
super.initState();
// Initialize textStyle here to use it in textChanged
textStyle = TextStyle(
fontSize: fontSizeDefault,
fontWeight: fontWeightDefault,
height: 1.0,
);
_textController.addListener(textChanged);
}
@override
void dispose() {
_textController.removeListener(textChanged);
_textController.dispose();
super.dispose();
}
void textChanged() {
final String currentText = _textController.text;
// Format the text to fit the container
TextBreaker textBreaker = TextBreaker(
input: currentText, // Specify the input text
textStyle: textStyle, // Specify the text style
containerWidth: widget.width, // Specify container width
containerHeight: widget.height, // Specify container height
textAlign: textAlignment, // Specify text alignment
);
BreakTextResult result = textBreaker.breakCharacterWithMeasurement();
formattedText = result.text;
// Update the state to display formatted text
setState(() {
this.maxLength = formattedText.length> 0 ? formattedText.length - result.lineBreakCount : maxLength;
this.formattedText = formattedText;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Square Details')),
body: SingleChildScrollView(
child: Column(
children: [
Divider(),
Text(
'Text Sticker',
style: TextStyle(fontWeight: FontWeight.bold),
),
// button to capture the green container as an image
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// Capture the green container as an image
print('Capture the green container as an image');
},
// Text to display in the button and width, height of the green container
child: Text('Capture Image, ${widget.width}x${widget.height}'),
),
],
),
Container(
width: widget.width,
height: widget.height,
color: Colors.green,
alignment: Alignment.center,
child: Text(
formattedText, // Display the formatted text here
style: textStyle,
textAlign: textAlignment,
),
),
Divider(),
Text(
'Formatted Text:',
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
width: double.infinity,
child: Text(formattedText, style: textStyle,textAlign: textAlignment),
),
Divider(),
Padding(
padding: EdgeInsets.all(16.0),
child: TextField(
controller: _textController,
maxLength: maxLength,
// To allow for unlimited lines, set maxLines to null.
// If you want to limit the number of lines, set maxLines to an integer value greater than 1.
maxLines: null,
keyboardType: TextInputType.multiline, // Set the keyboard type to multiline
textInputAction: TextInputAction.newline, // Set the input action to support newline for multiline input
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Enter your comments',
),
style: textStyle, // Apply the specified textStyle to the TextField
// Optional: Remove the maxLength restriction while typing (but still show the counter)
maxLengthEnforcement: MaxLengthEnforcement.none,
),
),
],
),
),
);
}
}
[영상]
그런데 inputfield에서 직접 enter(줄바꿈)하는 것에 대한 처리에 버그가 있음 ㅎㅎㅎㅎ
[영상]
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.
