이제 마지막으로 카드 안에 뉴스카드 하나하나를 만드는 작업을 해볼 것이다
큰 순서로는 전체 큰 카드 -> 뉴스 넣을 공간 만들 -> 뉴스 컬럼 -> 클릭하면 동작 될 함수 등으로 진행 될 것이다.
[ buildNewsCard ]
전체적으로 큰 뉴스 카드를 만들고 그 안에 뉴스컬럼들을 넣어 준다. 나는 웹화면과 모바일 화면에 따라 뉴스 카드의 갯수가 다르게 보여지게 하기 위해 isBigScreen 을 넣어 웹 일 때와 아닐때를 구별해 화면을 그려주었다.
Card buildNewsCard(bool isDarkMode, BuildContext context, double deviceWidth,
List<News> newsList) {
var showCard = deviceWidth / 3;
return Card(
margin: isBigScreen
? EdgeInsets.symmetric(horizontal: 150)
: EdgeInsets.symmetric(horizontal: 5),
color: isDarkMode ? LightColors.gray5 : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(23.0),
),
child: Padding(
padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
child: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildNewsColumn(isDarkMode, context, deviceWidth, newsList, 0),
if (isBigScreen && deviceWidth >= 1350)
buildNewsColumn(isDarkMode, context, deviceWidth, newsList, 2),
],
),
isBigScreen ? SizedBox(height: 30) : SizedBox(height: 15),
Center(
child: TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => NewsDetailPage()));
},
child: Text("더보기",
style: TextStyle(
fontSize: textSizeSmall2,
color: isDarkMode ? Colors.white : Colors.black)),
),
)
]),
),
);
}
[ buildNewsColumn ]
Column buildNewsColumn(bool isDarkMode, BuildContext context,
double deviceWidth, List<News> newsList, int startingIndex) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (int index = startingIndex; index < startingIndex + 2; index++)
buildNewsContainer(isDarkMode, context, deviceWidth, newsList, index),
],
);
}
[ buildNewsContainer ]
Container buildNewsContainer(bool isDarkMode, BuildContext context,
double deviceWidth, List<News> newsList, int index) {
return Container(
width: isBigScreen ? deviceWidth * 0.35 : deviceWidth * 0.8,
margin: EdgeInsets.fromLTRB(0, 5, 0, 5),
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color:
isDarkMode ? Theme.of(context).colorScheme.surface : Colors.black12,
),
child: buildNewsInkWell(context, index, newsList),
);
}
[ buildNewsInkWell ]
InkWell buildNewsInkWell(
BuildContext context, int index, List<News> newsList) {
return InkWell(
child: Row(
children: [
Container(
margin: EdgeInsets.only(left: 15, right: 15),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: (() {
if (newsList[index].urlToImage != null &&
newsList[index].urlToImage!.isNotEmpty) {
if (newsList[index].urlToImage!.startsWith('http') ||
newsList[index].urlToImage!.startsWith('https')) {
return Image.network(
newsList[index].urlToImage!,
width: 90,
height: 90,
errorBuilder: (context, error, stackTrace) {
return Image.asset(
'lib/assets/images/News.png',
width: 90,
height: 90,
fit: BoxFit.cover,
);
},
);
} else {
return Image.asset(
'lib/assets/images/News.png',
width: 90,
height: 90,
fit: BoxFit.cover,
);
}
}
// URL이 없는 경우
return Image.asset(
'lib/assets/images/News.png',
width: 90,
height: 90,
fit: BoxFit.cover,
);
})(),
),
),
SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
newsList[index].title,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
SizedBox(height: 10),
Text(
_formatPublishedDate(newsList[index].publishedAt),
style: TextStyle(fontSize: textSizeSmall),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
],
),
),
],
),
onTap: () async {
await launchUrl(Uri.parse(newsList[index].url));
},
);
}
[ 날짜 변환 ]
String _formatPublishedDate(String dateTimeString) {
DateTime dateTime = DateTime.parse(dateTimeString);
return '${dateTime.year}-${_twoDigits(dateTime.month)}-${_twoDigits(dateTime.day)}';
}
String _twoDigits(int n) => n.toString().padLeft(2, '0');
'Flutter' 카테고리의 다른 글
Table Class 의 Cell 각각의 너비 및 높이 지정하기 (0) | 2024.02.26 |
---|---|
Flutter 뉴스 API 연동하기(4) - 뉴스디테일 페이지 (0) | 2024.02.23 |
Flutter 뉴스 API 연동하기(2) - 통신하기 (0) | 2024.01.31 |
Flutter 뉴스 API 연동하기(1) - 기초 세팅 (0) | 2024.01.28 |
Flutter 정규식 표현(RegExp) - dart 정규표현식 (1) | 2024.01.24 |