Flutterラボの

プレミアム会員になる

【Flutter】YouTubeっぽいUIをFlutterでつくってみた

これから週に一回程度の頻度で、有名アプリのUIをFlutterでつくっていく記事を投稿したいと思います。

その第一弾として、YouTubeのUIを参考につくってみました。

画像1

UIの基本的なウィジェットである、Container、Row、ColumnやListViewの使い方の参考になればうれしいです。

もし、要望があれば細かいコードの解説もしていきたいと思います。

ハッチアウトスクール ハッチアウトスクールの公式サイトです hatchout.net
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     debugShowCheckedModeBanner: false,
     title: 'Flutter Demo',
     theme: ThemeData(
       primarySwatch: Colors.blue,
       primaryColor: Colors.black,
     ),
     home: MyHomePage(),
   );
 }
}

class MyHomePage extends StatefulWidget {
 MyHomePage({Key key}) : super(key: key);

 @override
 _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
       backgroundColor: Colors.black54,
       appBar: PreferredSize(
         preferredSize: Size.fromHeight(40),
         child: AppBar(
           title: Text('YouTube'),
           actions: [
             Padding(
               padding: const EdgeInsets.all(8.0),
               child: Icon(Icons.search_outlined),
             ),
             Padding(
               padding: const EdgeInsets.all(8.0),
               child: Icon(Icons.account_circle),
             )
           ],
         ),
       ),
       body: ListView.builder(
         itemBuilder: (context, index) {
           return Column(
             children: [
               AspectRatio(
                   aspectRatio: 16 / 9,
                   child: Container(
                     alignment: Alignment.center,
                     color: Colors.orange,
                     child: Text(
                       '$index',
                       style: TextStyle(fontSize: 50, color: Colors.white),
                     ),
                   )),
               Padding(
                 padding: const EdgeInsets.symmetric(vertical: 8),
                 child: Row(
                   children: [
                     Padding(
                       padding: const EdgeInsets.all(8.0),
                       child: CircleAvatar(
                         backgroundColor: Colors.blue,
                       ),
                     ),
                     Expanded(
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
                           Text(
                             '動画のタイトル',
                             style: TextStyle(
                                 color: Colors.white,
                                 fontWeight: FontWeight.w400),
                           ),
                           Row(
                             children: [
                               Text('チャンネル名', style: buildTextStyle()),
                               Text('・', style: buildTextStyle()),
                               Text('3000回視聴', style: buildTextStyle()),
                               Text('・', style: buildTextStyle()),
                               Text('1ヶ月前', style: buildTextStyle()),
                             ],
                           ),
                         ],
                       ),
                     ),
                   ],
                 ),
               )
             ],
           );
         },
       ));
 }

 TextStyle buildTextStyle() => TextStyle(
     color: Colors.white.withOpacity(0.7),
     fontWeight: FontWeight.w200,
     fontSize: 12);
}