일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준
- BOF
- ARM
- BAEKJOON
- Kaggle
- Widget
- study book
- pytorch
- DART
- Algorithm
- ML
- system hacking
- Got
- BFS
- Stream
- llm을 활용 단어장 앱 개발일지
- Computer Architecture
- Image Processing
- rao
- MATLAB
- fastapi를 사용한 파이썬 웹 개발
- MDP
- FastAPI
- bloc
- 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
- Flutter
- PCA
- Dreamhack
- 영상처리
- C++
- Today
- Total
Bull
[Dev] LLM을 활용 단어장 앱 개발일지 006: 단어장 UI 변경 본문
서론
기존 단어장 UI는 임의의 Card
을 채워서 구성해놨다. UI는 감으로 했기 때문에 크게 어디를 설명해야 할지 모르겠지만 일단 되는대로 적어볼 것이다.
데이터
우선 단어로 들어갈 임의의 데이터를 추가했다. 코드가 길기 때문에 따로 적어보겠다.
final List<String> words = [
'contradictory',
'incongruent',
'paradoxical',
'ambivalent',
'discrepant',
'discordant',
'opposing',
'clashing',
'conflicting',
'polarizing',
'divergent',
'ambiguous',
'equivocal',
'uncertain',
'doubtful',
'indeterminate',
'indecisive',
'vacillating',
'wavering',
'irresolute',
];
final List<String> meanings = [
'상반되는',
'불일치하는',
'역설적인',
'양면적인',
'모순된',
'불협화음의',
'반대하는',
'충돌하는',
'모순된',
'분열시키는',
'다른',
'모호한',
'애매한',
'불확실한',
'의심스러운',
'불확정된',
'우유부단한',
'흔들리는',
'동요하는',
'결단력이 없는',
];
final List<List<String>> tags = [
['#모순', '#상반되는', '#논쟁', '#의견불일치', '#학문적논의'],
['#불일치', '#부조화', '#상반됨', '#모호함', '#이견'],
['#역설적', '#모순된', '#비논리적', '#논리적충돌', '#대조'],
['#양면성', '#모호함', '#상반된감정', '#이중성', '#불확실성'],
['#불일치', '#모순', '#충돌', '#대립', '#상반'],
['#조화롭지않은', '#모순', '#불협화음', '#갈등', '#대립'],
['#반대', '#모순', '#대립', '#의견차이', '#갈등'],
['#충돌', '#대립', '#모순', '#불화', '#논쟁'],
['#상충', '#모순', '#대립', '#충돌', '#갈등'],
['#분열', '#대립', '#모순', '#갈등', '#논쟁'],
['#분기', '#차이', '#대립', '#모순', '#갈등'],
['#모호한', '#불확실한', '#모순된', '#혼란', '#불분명'],
['#애매한', '#모호한', '#상반된', '#혼란스러운', '#모순된'],
['#불확실한', '#모호한', '#결정되지않은', '#애매한', '#변화하는'],
['#의심스러운', '#불확실한', '#모호한', '#결정되지않은', '#우유부단한'],
['#미정의', '#불확실한', '#모호한', '#애매한', '#결정되지않은'],
['#우유부단한', '#변화하는', '#모호한', '#상반된', '#불확실한'],
['#동요하는', '#흔들리는', '#모호한', '#결정되지않은', '#모순된'],
['#흔들리는', '#불확실한', '#모호한', '#우유부단한', '#결정되지않은'],
['#결정하지못한', '#흔들리는', '#모호한', '#불확실한', '#모순된'],
];
final List<List<String>> exampleSentences = [
[
"The scientist's new theory was met with contradictory evidence from other researchers, creating a heated debate in the academic community.",
"과학자의 새로운 이론은 다른 연구자들의 모순된 증거와 만나면서 학계에 뜨거운 논쟁을 불러일으켰습니다."
],
[
"The results were incongruent with our expectations, causing confusion.",
"결과가 우리의 기대와 일치하지 않아 혼란을 일으켰습니다."
],
[
"His paradoxical statement left everyone puzzled.",
"그의 역설적인 발언은 모두를 당황하게 만들었습니다."
],
[
"She felt ambivalent about the decision, unable to choose a side.",
"그녀는 결정을 내리지 못하고 양면성을 느꼈습니다."
],
[
"The reports were discrepant, leading to further investigation.",
"보고서가 서로 일치하지 않아 추가 조사가 필요했습니다."
],
[
"The discordant notes in the music created an unsettling atmosphere.",
"음악의 불협화음이 불안한 분위기를 조성했습니다."
],
[
"Their opposing views led to a heated debate.",
"그들의 반대되는 의견은 뜨거운 논쟁을 불러일으켰습니다."
],
[
"The clashing colors of the painting made it hard to look at.",
"그림의 상충하는 색상들이 보기 어렵게 만들었습니다."
],
[
"The conflicting reports made it difficult to know the truth.",
"모순된 보고서들이 진실을 알기 어렵게 만들었습니다."
],
[
"The polarizing issue split the community in two.",
"극단적인 문제로 인해 커뮤니티가 두 개로 분열되었습니다."
],
[
"Their divergent paths in life led them to different destinations.",
"그들의 갈라진 삶의 길은 그들을 다른 목적지로 이끌었습니다."
],
[
"The ambiguous instructions left the students confused.",
"모호한 지시로 학생들이 혼란스러워했습니다."
],
[
"His equivocal response made it hard to know his true feelings.",
"그의 애매한 대답은 그의 진심을 알기 어렵게 만들었습니다."
],
[
"The uncertain weather made planning difficult.",
"불확실한 날씨 때문에 계획을 세우기가 어려웠습니다."
],
["She was doubtful about the success of the plan.", "그녀는 계획의 성공을 의심했습니다."],
[
"The indeterminate outcome left everyone on edge.",
"불확실한 결과가 모두를 긴장하게 만들었습니다."
],
[
"He remained indecisive until the last moment.",
"그는 마지막 순간까지 우유부단하게 남아 있었습니다."
],
[
"The vacillating opinions made it hard to reach a consensus.",
"흔들리는 의견들로 합의에 도달하기 어려웠습니다."
],
[
"She was wavering between two choices, unable to commit.",
"그녀는 두 가지 선택 사이에서 흔들리며 결정을 내리지 못했습니다."
],
[
"His irresolute nature made him an unreliable leader.",
"그의 우유부단한 성격은 그를 신뢰할 수 없는 리더로 만들었습니다."
],
];
위젯 부분은 Padding
, Column
, Row
의 단순 감과 노가다이지만 여기서 특별한 부분은 ListView.builder
안에 ListView.builder
를 연속해서 사용했다. 그 부분을 한번 살펴 보겠다.
Scaffold(
backgroundColor: Colors.grey.shade100,
floatingActionButtonLocation:
FloatingActionButtonLocation.miniCenterFloat,
floatingActionButton: FloatingActionButton(
onPressed: () => showWordDialog(context),
child: Icon(Icons.add, color: Colors.white),
backgroundColor: Colors.lightGreen,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(40)),
side: BorderSide(
style: BorderStyle.solid,
width: 0.0,
color: Colors.transparent,
),
),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(5),
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: words.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 1),
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius:
const BorderRadius.all(Radius.circular(5)),
side: BorderSide(
style: BorderStyle.solid,
width: 1.5,
color: Colors.grey.shade100,
),
),
child: Column(
children: [
ListTile(
title: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
words[index],
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(
10, 10, 0, 0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: const [
Text(
'정답률: 53%',
style: TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
Text(
'★★★☆☆',
style: TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
],
),
),
IconButton(
icon: const Icon(
Icons.keyboard_arrow_right,
color:
Color.fromARGB(255, 38, 21, 21),
),
onPressed: () {},
),
],
),
],
),
subtitle: Text(
meanings[index],
style: TextStyle(
fontSize: 14,
),
),
leading: const Icon(
Icons.volume_up,
color: Colors.lightGreen,
),
tileColor: Colors.white,
contentPadding:
const EdgeInsets.fromLTRB(15, 0, 0, 5),
shape: RoundedRectangleBorder(
borderRadius:
const BorderRadius.all(Radius.circular(5)),
side: BorderSide(
style: BorderStyle.solid,
width: 1.5,
color: Colors.grey.shade100,
),
),
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(
15, 10, 0, 15),
child: Text(
tags[index].join(' '),
style: const TextStyle(
fontSize: 14,
),
),
),
),
],
),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: exampleSentences[index].length,
itemBuilder: (_, sentenceIndex) {
return Padding(
padding:
const EdgeInsets.fromLTRB(15, 0, 15, 15),
child: Text(
exampleSentences[index][sentenceIndex],
style: TextStyle(
fontSize: 12,
color: Colors.grey.shade600,
),
),
);
},
),
],
),
),
);
},
),
),
],
),
),
),
);
전체 코드에서 중복된 내부 ListView.builder
만 보자.
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: exampleSentences[index].length,
itemBuilder: (_, sentenceIndex) {
return Padding(
padding:
const EdgeInsets.fromLTRB(15, 0, 15, 15),
child: Text(
exampleSentences[index][sentenceIndex],
style: TextStyle(
fontSize: 12,
color: Colors.grey.shade600,
),
),
);
},
),
기존과 차이가 나는 점은 shrinkWrap
과 physics
프로퍼티가 쓰였다. 나도 간단하게 스택오버플로우에서 답변을 긁어왔지만 중복해서 리스트뷰를 추가하려면 저 프로퍼티를 저렇게 추가해야한다. 프로퍼티 내용은 다음과 같다.
- shrinkWrap: true: ListView가 필요한 만큼의 공간만 차지하게 하여 크기를 축소.
- physics: const NeverScrollableScrollPhysics(): ListView가 스크롤되지 않도록 함.
원본에는 이걸 사용하면 해결된다는 내용만 나와있지만, 개인적으로 해석해보겠다.
ListView는 기본적으로 스크롤뷰를 제공하는데 중복 스크롤뷰가 되지 않도록해준다. 그리고 리스트의 각 아이템에 맞게 크기를 fit 하도록한다. 스크롤이 두 번 사용되면 기본적으로 스크롤 뷰가 무한한 크기를 가져서 레이아웃이 충돌날 수도 있고 어떤 객체에 스크롤을 적용해야할 지 혼란이 생길 수 있기 때문이다.
https://stackoverflow.com/questions/53465394/flutter-listview-builder-inside-another-listview
Flutter - Listview.builder inside another Listview
I want my screen to be scrollable so I put everything in a Listview. Now I want to show another Listview inside to show details of a List. When I try this an error is thrown - " Expanded widgets m...
stackoverflow.com
나머지 Card
에 들어간 위젯들의 위치는 정말 감으로만 했고 코드가 직관적이기 때문에 설명을 생략한다.
결과
'일상 > 개발일지' 카테고리의 다른 글
[Dev] LLM을 활용 단어장 앱 개발일지 008: 단어 데이터 Bloc 처리, SQLite 통신, CRUD 작업 (1) | 2024.09.03 |
---|---|
[Dev] LLM을 활용 단어장 앱 개발일지 007: 핵심 - 파인튜닝, 응답 데이터 전처리, 단어 추가 UI 구성 (0) | 2024.08.27 |
[Dev] LLM을 활용 단어장 앱 개발일지 005: CRUD - 단어 DB 읽어서 표시하기 (0) | 2024.08.20 |
[Dev] LLM을 활용 단어장 앱 개발일지 004: Bloc 상태 관리(대화 내용) (0) | 2024.08.18 |
[Dev] LLM을 활용 단어장 앱 개발일지 003: Fast API로 Langchain 설정하기 (0) | 2024.08.17 |