name27 / flutter

0 stars 0 forks source link

커스텀 위젯 - kakaotalk UI #34

Open name27 opened 1 year ago

name27 commented 1 year ago

image

main.dart

import 'package:flutter/material.dart';
import 'package:project_kakao_app/friendTile.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, //debug 배너 제거
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            '친구',
            style: TextStyle(fontSize: 25, fontWeight: FontWeight.w600),
          ),
          backgroundColor: Colors.transparent,
          foregroundColor: Colors.black,
          elevation: 0,
          actions: [
            Icon(Icons.search),
            SizedBox(
              width: 8,
            ),
            Icon(Icons.person_add_alt),
            SizedBox(
              width: 8,
            ),
            Icon(Icons.audiotrack),
            SizedBox(
              width: 8,
            ),
            Icon(Icons.settings),
            SizedBox(
              width: 8,
            ),
          ],
        ),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListView(
              children: [
                Image.asset('assets/event_1.png'),
                ListTile(
                  leading: ClipRRect(
                    borderRadius: BorderRadius.circular(15.0),
                    child: Image.network(
                      'https://picsum.photos/100/100',
                      width: 50,
                      height: 50,
                    ),
                  ),
                  title: Text('SFAC',
                      style:
                          TextStyle(fontSize: 18, fontWeight: FontWeight.w700)),
                  subtitle: Flexible(
                      child: Text(
                    '난 아무생각이 없다 왜냐하면 아무생각이 없기 때문이다.',
                    overflow: TextOverflow.ellipsis,
                  )),
                  trailing: OutlinedButton(
                    onPressed: () => print('play this.song'),
                    child: FittedBox(
                      fit: BoxFit.fitWidth,
                      child: Row(
                        children: [
                          Text(
                            'Love Dive - IVE',
                            style: TextStyle(
                              color: Colors.black,
                              fontWeight: FontWeight.bold,
                              fontSize: 12,
                            ),
                          ),
                          Icon(
                            Icons.play_arrow_outlined,
                            color: Colors.green,
                          )
                        ],
                      ),
                    ),
                    style: OutlinedButton.styleFrom(
                      side: BorderSide(color: Colors.green),
                      shape: const RoundedRectangleBorder(
                        borderRadius: BorderRadius.all(Radius.circular(20)),
                      ),
                    ),
                  ),
                ),
                Divider(thickness: 1.5),
                Text(
                  '친구 687',
                  style: TextStyle(color: Colors.black54),
                ),
                friendTile(
                    profile: 'https://picsum.photos/110/110',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                  profile: 'https://picsum.photos/80/80',
                  nickname: '우리형',
                  statusMessage: '40000/24000',
                ),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/243/50/50.jpg?hmac=yqEEo-K-aVG_0h4Bz7d775_o-eRTqfpS8D55WNmMQ_4',
                    nickname: '썸남',
                    statusMessage: '+3일',
                    song: '똥밟았네'),
                friendTile(
                  profile:
                      'https://fastly.picsum.photos/id/955/50/50.jpg?hmac=qcL3MYRm8WZFWrzVE2V1jFsJSp8vMvistLwdO5qjQAA',
                  nickname: '마이클',
                ),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/356/50/50.jpg?hmac=GUUZtoXz28FjLR1Y_Nmn1zNJC_th23hLMTjKfQfNLGU',
                    nickname: '친구1',
                    statusMessage: '열차예약-',
                    song: '똥밟았네'),
                friendTile(
                  profile:
                      'https://fastly.picsum.photos/id/991/50/50.jpg?hmac=yvggF-dCmadQxOCDujM-O6Ncy7DCBNozBxAc-A34GGg',
                  nickname: '민석이',
                ),
                friendTile(
                  profile:
                      'https://fastly.picsum.photos/id/156/50/50.jpg?hmac=rjjApEDoDhzR8aG3PD0JIiKAdpnMMv_xwyEJnDHH3o0',
                  nickname: '전여친',
                  statusMessage: '똥차다음벤츠라더니',
                ),
                friendTile(
                    profile: 'https://picsum.photos/55/55',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile: 'https://picsum.photos/50/50',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/452/50/50.jpg?hmac=RKlQKysWltcsb4t5ExZcj1B60X8NfQBBH5qc98y-SQQ',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/289/50/50.jpg?hmac=X6JopZHJh4AXVed4haCU68BNJDyj5my8SgV4c8BlIpw',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/930/50/50.jpg?hmac=Y7z7F4qxhCk8EUtHh9vtajxHO5l8_hlFSoT3hTxjY1Q',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
              ],
            ),
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          selectedItemColor: Colors.black,
          unselectedItemColor: Colors.grey,
          currentIndex: 0,
          showSelectedLabels: true,
          showUnselectedLabels: false,
          items: [
            BottomNavigationBarItem(icon: Icon(Icons.person), label: '친구'),
            BottomNavigationBarItem(
                icon: Icon(Icons.chat_bubble_outline), label: '채팅'),
            BottomNavigationBarItem(
                icon: Icon(Icons.remove_red_eye_outlined), label: '뷰'),
            BottomNavigationBarItem(
                icon: Icon(Icons.storefront_outlined), label: '상점'),
            BottomNavigationBarItem(icon: Icon(Icons.more_horiz), label: '더보기'),
          ],
        ),
      ),
    );
  }
}

friendTile.dart

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';

class friendTile extends StatelessWidget {
  const friendTile(
      {super.key,
      required this.profile,
      required this.nickname,
      this.statusMessage,
      this.song});
  final String profile;
  final String nickname;
  final String? statusMessage;
  final String? song;
  @override
  Widget build(BuildContext context) {
    Widget result = ListTile();
    if (statusMessage != null && song != null) {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
        subtitle: Text(statusMessage!),
        trailing: OutlinedButton(
          onPressed: () => print('play $song'),
          child: FittedBox(
            fit: BoxFit.fitWidth,
            child: Row(
              children: [
                Text(
                  song!,
                  style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontSize: 12,
                  ),
                ),
                Icon(
                  Icons.play_arrow_outlined,
                  color: Colors.green,
                )
              ],
            ),
          ),
          style: OutlinedButton.styleFrom(
            side: BorderSide(color: Colors.green),
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20)),
            ),
          ),
        ),
      );
    } else if (statusMessage == null && song != null) {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
        trailing: OutlinedButton(
          onPressed: () => print('play $song'),
          child: FittedBox(
            fit: BoxFit.fitWidth,
            child: Row(
              children: [
                Text(
                  song!,
                  style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontSize: 12,
                  ),
                ),
                Icon(
                  Icons.play_arrow_outlined,
                  color: Colors.green,
                )
              ],
            ),
          ),
          style: OutlinedButton.styleFrom(
            side: BorderSide(color: Colors.green),
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20)),
            ),
          ),
        ),
      );
    } else if (statusMessage != null && song == null) {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
        subtitle: Text(statusMessage!),
      );
    } else {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
      );
    }
    return Expanded(
      child: result,
    );
  }
}
name27 commented 1 year ago

bottom_navigation_bar_theme.dart 코드 중 이 부분 참고

Widget result = InkResponse(
      onTap: onTap,
      mouseCursor: mouseCursor,
      enableFeedback: enableFeedback,
      child: Padding(
        padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding),
        child: _Tile(
          layout: layout,
          icon: _TileIcon(
            colorTween: colorTween!,
            animation: animation,
            iconSize: iconSize,
            selected: selected,
            item: item,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
          ),
          label: _Label(
            colorTween: colorTween!,
            animation: animation,
            item: item,
            selectedLabelStyle: selectedLabelStyle,
            unselectedLabelStyle: unselectedLabelStyle,
            showSelectedLabels: showSelectedLabels,
            showUnselectedLabels: showUnselectedLabels,
          ),
        ),
      ),
    );

    if (effectiveTooltip != null) {
      result = Tooltip(
        message: effectiveTooltip,
        preferBelow: false,
        verticalOffset: selectedIconSize + selectedFontSize,
        excludeFromSemantics: true,
        child: result,
      );
    }

    result = Semantics(
      selected: selected,
      container: true,
      child: Stack(
        children: <Widget>[
          result,
          Semantics(
            label: indexLabel,
          ),
        ],
      ),
    );

    return Expanded(
      flex: size,
      child: result,
    );
name27 commented 1 year ago

friendTile.dart에서 text overflow 코드 subtitle에 추가

main.dart에서 마이클 song 추가

image

Main.dart

import 'package:flutter/material.dart';
import 'package:project_kakao_app/friendTile.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, //debug 배너 제거
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            '친구',
            style: TextStyle(fontSize: 25, fontWeight: FontWeight.w600),
          ),
          backgroundColor: Colors.transparent,
          foregroundColor: Colors.black,
          elevation: 0,
          actions: [
            Icon(Icons.search),
            SizedBox(
              width: 8,
            ),
            Icon(Icons.person_add_alt),
            SizedBox(
              width: 8,
            ),
            Icon(Icons.audiotrack),
            SizedBox(
              width: 8,
            ),
            Icon(Icons.settings),
            SizedBox(
              width: 8,
            ),
          ],
        ),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListView(
              children: [
                Image.asset('assets/event_1.png'),
                ListTile(
                  leading: ClipRRect(
                    borderRadius: BorderRadius.circular(15.0),
                    child: Image.network(
                      'https://picsum.photos/100/100',
                      width: 50,
                      height: 50,
                    ),
                  ),
                  title: Text('SFAC',
                      style:
                          TextStyle(fontSize: 18, fontWeight: FontWeight.w700)),
                  subtitle: Flexible(
                      child: Text(
                    '난 아무생각이 없다 왜냐하면 아무생각이 없기 때문이다.',
                    overflow: TextOverflow.ellipsis,
                  )),
                  trailing: OutlinedButton(
                    onPressed: () => print('play this.song'),
                    child: FittedBox(
                      fit: BoxFit.fitWidth,
                      child: Row(
                        children: [
                          Text(
                            'Love Dive - IVE',
                            style: TextStyle(
                              color: Colors.black,
                              fontWeight: FontWeight.bold,
                              fontSize: 12,
                            ),
                          ),
                          Icon(
                            Icons.play_arrow_outlined,
                            color: Colors.green,
                          )
                        ],
                      ),
                    ),
                    style: OutlinedButton.styleFrom(
                      side: BorderSide(color: Colors.green),
                      shape: const RoundedRectangleBorder(
                        borderRadius: BorderRadius.all(Radius.circular(20)),
                      ),
                    ),
                  ),
                ),
                Divider(thickness: 1.5),
                Text(
                  '친구 687',
                  style: TextStyle(color: Colors.black54),
                ),
                friendTile(
                    profile: 'https://picsum.photos/110/110',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                  profile: 'https://picsum.photos/80/80',
                  nickname: '우리형',
                  statusMessage: '40000/24000',
                ),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/243/50/50.jpg?hmac=yqEEo-K-aVG_0h4Bz7d775_o-eRTqfpS8D55WNmMQ_4',
                    nickname: '썸남',
                    statusMessage: '+3일',
                    song: '똥밟았네'),
                friendTile(
                  profile:
                      'https://fastly.picsum.photos/id/955/50/50.jpg?hmac=qcL3MYRm8WZFWrzVE2V1jFsJSp8vMvistLwdO5qjQAA',
                  nickname: '마이클',
                  song: '똥밟았네',
                ),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/356/50/50.jpg?hmac=GUUZtoXz28FjLR1Y_Nmn1zNJC_th23hLMTjKfQfNLGU',
                    nickname: '친구1',
                    statusMessage: '열차예약-',
                    song: '똥밟았네'),
                friendTile(
                  profile:
                      'https://fastly.picsum.photos/id/991/50/50.jpg?hmac=yvggF-dCmadQxOCDujM-O6Ncy7DCBNozBxAc-A34GGg',
                  nickname: '민석이',
                ),
                friendTile(
                  profile:
                      'https://fastly.picsum.photos/id/156/50/50.jpg?hmac=rjjApEDoDhzR8aG3PD0JIiKAdpnMMv_xwyEJnDHH3o0',
                  nickname: '전여친',
                  statusMessage: '똥차다음벤츠라더니',
                ),
                friendTile(
                    profile: 'https://picsum.photos/55/55',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile: 'https://picsum.photos/50/50',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/452/50/50.jpg?hmac=RKlQKysWltcsb4t5ExZcj1B60X8NfQBBH5qc98y-SQQ',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/289/50/50.jpg?hmac=X6JopZHJh4AXVed4haCU68BNJDyj5my8SgV4c8BlIpw',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
                friendTile(
                    profile:
                        'https://fastly.picsum.photos/id/930/50/50.jpg?hmac=Y7z7F4qxhCk8EUtHh9vtajxHO5l8_hlFSoT3hTxjY1Q',
                    nickname: '전여친',
                    statusMessage: '똥차다음벤츠라더니',
                    song: '똥밟았네'),
              ],
            ),
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          selectedItemColor: Colors.black,
          unselectedItemColor: Colors.grey,
          currentIndex: 0,
          showSelectedLabels: true,
          showUnselectedLabels: false,
          items: [
            BottomNavigationBarItem(icon: Icon(Icons.person), label: '친구'),
            BottomNavigationBarItem(
                icon: Icon(Icons.chat_bubble_outline), label: '채팅'),
            BottomNavigationBarItem(
                icon: Icon(Icons.remove_red_eye_outlined), label: '뷰'),
            BottomNavigationBarItem(
                icon: Icon(Icons.storefront_outlined), label: '상점'),
            BottomNavigationBarItem(icon: Icon(Icons.more_horiz), label: '더보기'),
          ],
        ),
      ),
    );
  }
}

friendTile.dart

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';

class friendTile extends StatelessWidget {
  const friendTile(
      {super.key,
      required this.profile,
      required this.nickname,
      this.statusMessage,
      this.song});
  final String profile;
  final String nickname;
  final String? statusMessage;
  final String? song;
  @override
  Widget build(BuildContext context) {
    Widget result = ListTile();
    if (statusMessage != null && song != null) {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
        subtitle: Flexible(child: Text(statusMessage!, overflow: TextOverflow.ellipsis,),),
        trailing: OutlinedButton(
          onPressed: () => print('play $song'),
          child: FittedBox(
            fit: BoxFit.fitWidth,
            child: Row(
              children: [
                Text(
                  song!,
                  style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontSize: 12,
                  ),
                ),
                Icon(
                  Icons.play_arrow_outlined,
                  color: Colors.green,
                )
              ],
            ),
          ),
          style: OutlinedButton.styleFrom(
            side: BorderSide(color: Colors.green),
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20)),
            ),
          ),
        ),
      );
    } else if (statusMessage == null && song != null) {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
        trailing: OutlinedButton(
          onPressed: () => print('play $song'),
          child: FittedBox(
            fit: BoxFit.fitWidth,
            child: Row(
              children: [
                Text(
                  song!,
                  style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontSize: 12,
                  ),
                ),
                Icon(
                  Icons.play_arrow_outlined,
                  color: Colors.green,
                )
              ],
            ),
          ),
          style: OutlinedButton.styleFrom(
            side: BorderSide(color: Colors.green),
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20)),
            ),
          ),
        ),
      );
    } else if (statusMessage != null && song == null) {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
        subtitle: Flexible(child: Text(statusMessage!, overflow: TextOverflow.ellipsis,),),
      );
    } else {
      result = ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(15.0),
          child: Image.network(
            profile,
            width: 45,
            height: 45,
          ),
        ),
        title: Flexible(
          child: Text(
            nickname,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
        ),
      );
    }
    return Expanded(
      child: result,
    );
  }
}