もっぺんプログラミング(´・ω・`)

もっぺん頑張って副業プログラマを目指してます。

Flutter動画やってみよ(eBook)3

以下のYoutubeの動画を、実際になぞっていきます。

前回は、こちら。

Flutter動画やってみよ(eBook)その2 - もっぺんプログラミング(´・ω・`)

本のタイトルを付ける

前の Positioned の次に、新たにPositionedを追加します。

), // Positioned 
Positioned(
  top: 160,
  child: Container(
    height: 85,
    width: 202,
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Padding(
          padding: EdgeInsets.only(left: 24),
          child: RichText(
            text: TextSpan(
              style: TextStyle(color: kBlackColor),
              children: [
                TextSpan(
                  text: "Crushing & Influence\n",
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                  ),
                ),
                TextSpan(
                  text: "Gery Venchuk",
                  style: TextStyle(
                    color: kLightBlackColor,
                  ),
                ),
              ],
            ),
          ),
        )
      ],
    ),
  ),
),

f:id:momoizo:20200525013042p:plain:w300

詳細表示用のボタンを追加する。

上記のPaddingの閉じタグから、以下を追加します。

), // Padding
Spacer(),
Row(
  children: <Widget>[
    Container(
      width: 101,
      padding: EdgeInsets.symmetric(vertical: 10),
      alignment: Alignment.center,
      child: Text("Details")
    ),
    Expanded(
      child: Container(
        alignment: Alignment.center,
        padding: EdgeInsets.symmetric(vertical: 10),
        decoration: BoxDecoration(
          color: kBlackColor,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(29),
            bottomRight: Radius.circular(29),
          ),
        ),
        child: Text(
          "Read",
          style: TextStyle(color: Colors.white),
        ),
      ),
    ),
  ],
)

f:id:momoizo:20200525013120p:plain:w300

こんな感じになりました。

書籍ごとに、再利用したいので Container 以下をWidgetとして切り出します。
切り出したWidgetで、マウス操作を補足したいので GestureDetector で囲みます。

また、textや、ボタンを押した際の動作を外部から指定できるように
コンストラクタの変数として追加します。

class TwoSideRoundedButton extends StatelessWidget {
  final String text;  // ← 追加
  final double radious;  // ← 追加
  final Function press;  // ← 追加
  const TwoSideRoundedButton({
    Key key,  // ← 追加
    this.text,  // ← 追加
    this.radious = 29,  // ← 追加
    this.press,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: press, // ← 変数を指定
      child: Container(
        alignment: Alignment.center,
        padding: EdgeInsets.symmetric(vertical: 10),
        decoration: BoxDecoration(
          color: kBlackColor,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(radious),  // ← 変数に置き換え
            bottomRight: Radius.circular(radious),
          ),
        ),
        child: Text(
          text,  // ← 変数に置き換え
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}

呼び出し側の引数は以下のように指定します。

Expanded(
  child: TwoSideRoundedButton( 
    text: "read", // ← 
    press: () {},
  ),
),

最後にTwoSideRoundedButton クラスを、 lib/widgets 以下に two_side_rounded_button.dart に切り出します。

本のカードをリスト化する

1つの本のカードが出来ました。 ここでは、本のカードをWidgetとして切り出して、複数の書籍のリストを作成します。

書籍カードを作成したContainerを、別Widgetに切り出します。 名前は、ReadingListCard とします。

            SizedBox(height: 30),
            ReadingListCard(    // ← ここ ReadingListCard Widgetに置き換えています。
              image: "assets/images/book-1.png",
              title: "Crushing & Influence",
              auth: "Gary Venchuk",
              rating: 4.9,
            )
          ],
        ),
      ),
    );
  }
}

class ReadingListCard extends StatelessWidget {
  final String image;
  final String title;
  final String auth;
  final double rating;
  final Function pressDetails;
  final Function pressRead;

  const ReadingListCard({
    Key key,
    this.image,
    this.title,
    this.auth,
    this.rating,
    this.pressDetails,
    this.pressRead,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(left: 24, bottom: 40),
      height: 245,
      width: 202,
      child: Stack(
        children: <Widget>[
        ....
        ],
      ),
    );
  }
}

本のカードを横に並べる

本のカードを横に並べたいので、Row を使って横に並べます。
さらに横スクロールで表示するために、SingleChildScrollView で囲みます。

以下のように修正します。

SizedBox(height: 30),
SingleChildScrollView(
  scrollDirection: Axis.horizontal,
  child: Row(
    children: <Widget>[
      ReadingListCard(
        image: "assets/images/book-1.png",
        title: "Crushing & Influence",
        auth: "Gary Venchuk",
        rating: 4.9,
      ),
      ReadingListCard(
        image: "assets/images/book-2.png",
        title: "Top Ten Business Hacks",
        auth: "Herman Joel",
        rating: 4.2,
      ),
    ],
  ),
),

こんな感じになりました。

f:id:momoizo:20200525031937p:plain:w300

つづきます。