seong

8. 리뷰 작성 페이지 (별점 주기) 본문

Flutter/중계 플랫폼 프로젝트

8. 리뷰 작성 페이지 (별점 주기)

hyeonseong 2022. 12. 4. 20:23

리뷰 작성 페이지는 생각보다 간단하지만 

보통 앱을 사용해보면 리뷰 별점 주기는 색깔 없는 별 에서 사용자가 직접 별 아이콘을 눌러 색깔을 채워지는 형식으로 진행된다.

이 부분은 pub.dev에 있는 라이브러리를 활용할것이다.

 

그리고 아래 리뷰 작성 부분에 글을 작성 할 경우 키보드 버튼이 올라오는데 이부분은 이전에 사용했던 scrollAnimate를 사용해서 

키보드가 올라오면 해당 작성 부분이 함께 올라오게 만든다.

 

별점으로 리뷰 주기 

https://seong9566.tistory.com/254

 

실행 화면

전체 코드

import 'package:finalproject_front/constants.dart';
import 'package:finalproject_front/pages/components/custom_text_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';

class LessonReviewInsertPage extends StatefulWidget {
  const LessonReviewInsertPage({super.key});

  @override
  State<LessonReviewInsertPage> createState() => _LessonReviewInsertPageState();
}

class _LessonReviewInsertPageState extends State<LessonReviewInsertPage> {
  late ScrollController scrollController; // ScrollerController은 non-null이다, late를 선언해 나중에 초기화.

  @override
  void initState() {
    super.initState();
    scrollController = new ScrollController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppbar(context),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Column(
            children: [
              _buildLessonCard(
                "assets/background1.gif",
                "깔끔하고 감각적인 최고의 홈페이지를 제작해드립니다.",
                "유리아",
                "50000원",
                "2022.12.08",
              ),
              SizedBox(height: 20),
              Align(
                alignment: Alignment.topCenter,
                child: Text(
                  "수업은 만족하셨나요?",
                  style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                ),
              ),
              _buildReviewRatingBar(),
              SizedBox(height: 20),
              CustomTextField(scrollAnimate, fieldTitle: "리뷰작성", hint: "악플은 안대요><", lines: 6),
              SizedBox(height: 20),
              _buildReviewInsertButton(context),
            ],
          ),
        ),
      ),
    );
  }

  InkWell _buildReviewInsertButton(BuildContext context) {
    return InkWell(
      onTap: () {
        Navigator.pushNamed(context, "/loginMyPage");
      },
      child: Container(
        height: 50,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5),
          color: gButtonOffColor,
        ),
        child: Align(
          alignment: Alignment.center,
          child: Text(
            "저장하고 완료",
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.white,
            ),
          ),
        ),
      ),
    );
  }

  RatingBar _buildReviewRatingBar() {
    return RatingBar.builder(
      initialRating: 3,
      minRating: 0,
      direction: Axis.horizontal,
      allowHalfRating: true,
      itemCount: 5,
      itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
      itemBuilder: (context, _) => Icon(
        Icons.star,
        color: Colors.amber,
      ),
      onRatingUpdate: (rating) {
        // save 동작 필요함
      },
    );
  }

  AppBar _buildAppbar(BuildContext context) {
    return AppBar(
      elevation: 1,
      centerTitle: true,
      title: Text(
        "리뷰 작성",
        style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
      ),
      leading: IconButton(
          icon: Icon(
            CupertinoIcons.back,
            color: Colors.black,
            size: 30,
          ),
          onPressed: () {
            Navigator.pop(context);
          }),
    );
  }

  void scrollAnimate() {
    Future.delayed(Duration(milliseconds: 600), () {
      scrollController.animateTo(MediaQuery.of(context).viewInsets.bottom, duration: Duration(microseconds: 100), curve: Curves.easeIn);
    });
  }

  Container _buildLessonCard(String lessongImage, String lessonTitle, String expertName, String lessonPrice, String lessongEndDate) {
    return Container(
      child: Column(
        children: [
          SizedBox(height: 15),
          Container(
            decoration: BoxDecoration(
              border: Border.all(color: gBorderColor, width: 3),
              borderRadius: BorderRadius.circular(10),
            ),
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: Column(
                children: [
                  Row(
                    children: [
                      ClipRRect(
                        borderRadius: BorderRadius.circular(10),
                        child: Container(
                          height: 90,
                          width: 110,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(10),
                            image: DecorationImage(image: AssetImage("${lessongImage}"), fit: BoxFit.cover),
                          ),
                        ),
                      ),
                      SizedBox(
                        width: 10,
                      ),
                      Container(
                        width: 150,
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              "${lessonTitle}",
                              style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                            ),
                            SizedBox(
                              height: 5,
                            ),
                            Text(
                              "전문가 : ${expertName}",
                              style: TextStyle(fontSize: 12),
                            ),
                            SizedBox(
                              height: 5,
                            ),
                            Text(
                              "${lessonPrice}",
                              style: TextStyle(fontSize: 12),
                            ),
                            SizedBox(
                              height: 5,
                            ),
                            Text(
                              "마감일자 :${lessongEndDate}",
                              style: TextStyle(fontSize: 12),
                            )
                          ],
                        ),
                      )
                    ],
                  ),
                  SizedBox(height: 10),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}