iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
自我挑戰組

Kotlin & Flutter App 開發比較思考日誌系列 第 20

[鐵人賽 Day 20] Kotlin & Flutter 元件比較(四) - 一頁一頁滑動元件實例

  • 分享至 

  • xImage
  •  

目的

比較 Kotlin & Flutter 一頁一頁滑動元件實際使用方式差異

例子

需以水平滑動方式顯示頁面,共顯示三頁,每一頁顯示"這是第幾頁",ex: 第一頁就顯示這是第一頁。

以下為實際執行頁面截圖:
https://ithelp.ithome.com.tw/upload/images/20230924/20162686kNZL1zUxIL.jpg

Kotlin

使用 ViewPager2 元件

以下為檔案架構:

  1. layout 設定:
    • item_viewpager2.xml:設定每一頁顯示的layout
    • activity_main.xml:設定一頁一頁滑動元件擺放位置
  2. code :將資料設定到 view 上
    • MainActivity.kt:將 Adapter 設置到 ViewPager2
    • ViewPager2Adpter.kt:設定每一頁顯示的layout與資料
  3. viewModel:設定並儲存頁面資料
    • MyViewModel.kt:儲存所有 ViewPager2 所有需要的資料

以下為 item_viewpager2.xml 檔案內容:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

以下為 activity_main.xml 檔案內容:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    tools:context=".MainActivity">

  <androidx.viewpager2.widget.ViewPager2
      android:id = "@+id/viewPager2"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

以下為 MainActivity.kt 內容:

package com.example.kotlin_demo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.viewpager2.widget.ViewPager2

class MainActivity : AppCompatActivity() {
    private val viewModel = MyViewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val viewPager2 = findViewById<ViewPager2>(R.id.viewPager2)

        //由 viewModel 儲存 ViewPager 所需資料
        viewModel.viewPagerList.value = listOf("這是第一頁", "這是第二頁", "這是第三頁")

        //當 viewModel 接收到的 ViewPager 資料有變動時,重新設置 ViewPager Adpter 所接收到的資料
        viewModel.viewPagerList.observe(this,{
            viewPager2.adapter = ViewPager2Adapter(it)
        })

    }
}

以下為 ViewPager2Adpter.kt 檔案內容:

package com.example.kotlin_demo

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class ViewPager2Adapter(val textList: List<String>) : RecyclerView.Adapter<ViewPager2Adapter.MyViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val myView :View = LayoutInflater.from(parent.context).inflate(R.layout.item_viewpager2,parent,false)
        return MyViewHolder(myView)
    }

    //將接收到的資料設置在元件上
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.setTextContent(textList[position])
    }

    //設定頁面總數
    override fun getItemCount(): Int {
        return textList.size
    }
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    /*
    * 建立函式以設定每一頁的layout
    * */
    fun setTextContent(textContent:String){
        val textView =itemView.findViewById<TextView>(R.id.textView)
        textView.setText(textContent)
    }

}

}



以下為 MyViewModel.kt 檔案內容:

package com.example.kotlin_demo

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class MyViewModel: ViewModel() {
    val viewPagerList = MutableLiveData<List<String>>()
}

Flutter

使用 PageView 元件

檔案架構:
只修改 main.dart 檔案

以下為 main.dart 檔案內容:

import 'package:flutter/material.dart';

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

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

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

class _MyAppState extends State<StatefulWidget> {
  PageController _controller = PageController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        //SafeArea 元件用來確保元件顯示內容,會在不同系統上的裝置正常顯示位置
        body: SafeArea(child:Container(
          child: _wPageView(_controller),
        )),
      ),
    );
  }
}

///依頁面翻動元件
/// - [controller] 設置 PageView 起始頁面
Widget _wPageView(PageController controller) {
  return PageView(
    scrollDirection: Axis.horizontal, //橫向滑動
    controller: controller,
    //需要切換的頁面清單: 總共會切換三頁,每一頁都是一個 Text 元件
    children: [
      Text("這是第一頁"),
      Text("這是第二頁"),
      Text("這是第三頁"),
    ],
  );
}


上一篇
[鐵人賽 Day 19] Kotlin & Flutter 元件比較(四) - 常見的可滑動元件名稱統整
下一篇
[鐵人賽 Day 21] Kotlin & Flutter 頁面建立思考差異
系列文
Kotlin & Flutter App 開發比較思考日誌30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言