Page Slider Yapımı: Flutter ve PageView Kullanımı

Flutter tüm platformlarda mobil uygulama geliştirmeyi sağlayan yeni nesil bir araçtır. Alibaba, Google gibi büyük şirketlerin tercihi olan Flutter adından sıkça söz ettirmektedir. Öğrenmesi kolay yapısıyla birçok geliştiricinin tercihi olmaktadır. Bugün sizlerle birlikte yapacağımız Page Slider; otomatik ya da elle sayfalar arasında geçişi sağlayan bir özelliktir. Page Slider ile dinamik bir başlangıç sayfası yaratabilir, uygulamanız içinde birçok yerde kullanabilirsiniz.



Yapmaya geçmeden önce bilgisayarınızda:

Flutter ve Dart yüklü olmalı,

Android Studio SDK’sı yüklü olmalı. (Android Studio yüklemeniz de yeterli olacaktır.)

page slider yapımı

Page Slider Yapımı: Flutter Projesi Oluşturmak

İlk adımımız Flutter projesi oluşturmak.

Ardından projenin içinde “Images” adlı bir klasör oluşturuyoruz.

Uygulamada kullanacağımız resimleri Images adlı dosyaya ekliyoruz.

pubspec.yaml dosyasını açarak resimlerimizi Flutter uygulamasına ekleyeceğiz.

flutter başlığı altında assets: yazıyoruz ve ardından resimlerimizi tek tek yazıyoruz. Burada boşluklara dikkat etmeniz gerek yoksa hata ile karşılaşabilirsiniz.



flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.

  uses-material-design: true
  assets:
    - images/facebook.png
    - images/instagram.png
    - images/linkedin.png

Artık resimlerimizi uygulamaya eklemiş olduk, uygulamayı oluşturmaya geçebiliriz. Bunun için main.dart adlı dosyayı açıyoruz. Bu dosyada hali hazırda gelen bir kod bulunmakta. Flutter yeni başlayanlar için nasıl kullanacaklarına dair bir uygulama barındırıyor içinde. Bu kodun tamamını siliyoruz.

MyApp adlı sınıfımızı oluşturuyoruz. Burada StartScreen() fonksiyonu olmadığını fark ettiniz, birazdan bu dosyayı oluşturacağız.

import 'package:flutter/material.dart';
import './screens/start_screen.dart';

void main() => runApp(MyApp());

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

Page Slider Yapımı: Başlangıç Ekranı Oluşturmak

İlk başta screens adlı bir klasör oluşturuyoruz ve ardından içinde start_screen.dart adlı bir dosya yaratıyoruz.

Bu dosyanın içinde ilk başta Scaffold widget’ını kullanacağız.

Body içine yerleştiğimiz Container ile birlikte sırasıyla

Text, Flat Button oluşturduk.

Text kısmı Slide kısmının yer alacağı bölüm.

import 'package:flutter/material.dart';

class StartScreen extends StatelessWidget{
 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.white,
        child: Padding(
          padding: const EdgeInsets.all(50),
          child: Column(
            children:<Widget> [
              Text('Düzenlenecek Bölge'
                       ),

              SizedBox(height: 20,),

              Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget> [
                  FlatButton(
                      onPressed: () {},
                      child: Text('Hadi Başlayalım', style: TextStyle( fontSize: 18, color: Colors.white)
                        ,),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                  color: Theme.of(context).primaryColor,
                    padding: const EdgeInsets.all(15),

                  )
                ],
              ),
            ],
          ),
        ),
      )

    );

    throw UnimplementedError();
  }
}

Page Slider Yapımı: Slide Oluşturmak

Slide Sınıfı Oluşturmak

Bu adımda model adlı bir klasör oluşturuyoruz ve slide.dart adlı bir dosya yaratıyoruz.

Slide sınıfını oluşturma amacımız Flutter’ın nesne özelliğini kullanabilmemiz. Slide adlı sınıfta resim, konu başlığı ve açıklama özelliklerini tanımlıyoruz.

@required bu sınıftan bir nesne yaratırken bu özelliklerin önemli olduğunu, geçilmemesi gerektiğini bize hatırlatıyor.



Sınıfımızı yarattık şimdi dilediğimiz kadar Slide nesnesi yaratabiliriz.

SlideList adlı listede üç nesne yarattık. Siz dilerseniz ekleme ya da çıkarma yapabilirsiniz.

import 'package:flutter/material.dart';

class Slide {
  final String imageUrl;
  final String title;
  final String description;

  Slide(
      {
        @required this.imageUrl,
        @required this.title,
        @required this.description});
}

final slideList = [
  Slide(
      imageUrl: 'images/facebook.png',
      title: 'Hoş geldin!',
      description: 'Teknoloji.org dünyasına hoş geldin. Teknoloji ile ilgili her konuyu bulabilirsin.'
  ),
  Slide(
      imageUrl: 'images/instagram.png',
      title: 'Takipte Kal',
      description: 'Güncel haberler, teknolojik gelişmeler ve daha fazlası için takip et!'
  ),
  Slide(
      imageUrl: 'images/linkedin.png',
      title: 'Sosyal Medyada Takip Et',
      description: 'Tüm sosyal mecralarda varız, bizi takip edebilirsin.'
  ),
];

Slide Item Oluşturmak

Bu adımda widgets adlı bir klasör oluşturuyoruz ve slide_item.dart adlı bir dosya yaratıyoruz.

Bu adımı yaratırken resim – başlık – açıklama sırasını takip ediyoruz.

import ‘../model/slide.dart’ ile model klasöründe ekli olan slide.dart adlı dosyayı eklemiş oluyoruz.

Kısaca mantığından söz edersek:

slide_item yapımızı, iskeleti oluşturmaktadır. Slide’ın nasıl görüneceğini burada tasarlıyoruz. Tüm slide nesneleri tarafından ortak kullanılmaktadır.

Slide nesneleri ise bilgiyi tutmaktadır.

SlideList nesnelerini çağırmak adına

slideList[index].imageUrl, slideList[index].title, slideList[index].description



yazıyoruz.

import 'package:flutter/material.dart';
import '../model/slide.dart';

class SlideItem extends StatelessWidget {
  final int index;
  SlideItem(this.index);
  @override
  Widget build(BuildContext context) {
    return  Column(
      children: <Widget> [
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget> [
            Container(
              width: 200,
              height: 200,
              decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  image: DecorationImage(image: AssetImage(slideList[index].imageUrl),
                      fit: BoxFit.cover)

              ),
            ),
            SizedBox(height: 15,),
            Text(
              slideList[index].title,
              style: TextStyle(
                  color: Theme.of(context).primaryColor,
                  fontSize: 22
              ),
            ),
            Text(
              slideList[index].description,
              textAlign: TextAlign.center,
              style: TextStyle(
                  color: Theme.of(context).primaryColor,
                  fontSize: 18
              ),
            )
          ],
        )
      ],
    );
    throw UnimplementedError();
  }

}

Slide Dots Oluşturmak

Bu aşamada slide nesnelerimiz kayarken onlarla eş zamanlı kayan slide noktaları oluşturuyoruz.

Bu adımda widgets adlı klasörün içinde slide_dots.dart adlı bir dosya yaratıyoruz.

page slider da slide dots oluşturmak

Hangi slide sayfada görünürse o slide dot’ının renginin diğerlerine göre daha belirgin olmasını isteriz. Bu nedenle isActive adında bir bool tanımlıyoruz. Eğer sayfa aktifse bool ifadesi doğru olacak, değilse yanlış.

height: isActive ? 12 : 8
width: isActive ? 12 :8

Burada yazdığımızı açarsak; isActive eğer doğru ise 12, değilse 8 ifadesini gerçekleştir.

if/else fonksiyonun kısa hali diyebiliriz.

import 'package:flutter/material.dart';

class SlideDots extends StatelessWidget {
  bool isActive;
  SlideDots(this.isActive);
  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: Duration(milliseconds: 150),
      margin: const EdgeInsets.symmetric(horizontal: 10),
      height: isActive ? 12 : 8,
      width: isActive ? 12 : 8,
      decoration: BoxDecoration(
          color: isActive ? Theme.of(context).primaryColor : Colors.grey,
          borderRadius: BorderRadius.all(Radius.circular(12))
      ),
    );
    throw UnimplementedError();
  }

}

Page Slider Yapımı: Başlangıç Ekranlarına Yaptıklarımızı Eklemek

Artık sıra tüm yaptıklarımızı birleştirmeye geldi.

Öncelikle slide_dots, slide_item ve slide dosyalarını import ediyoruz.

Zamanlayıcıyı tanımlarken kullanacağımız Dart kütüphanesinde tanımlı async da import ediyoruz.



StartScreen adlı sınıfımız Stataless bir widget’dı. Çünkü kullanıcıyla herhangi bir etkileşime girmiyordu. Şimdi ise kullanıcı slide’lar arasında gezineceğinden, sınıf interaktif bir hale büründü. Bu nedenle Stateful hale getireceğiz.

Stateless Widget’ın üzerine tıklayıp Stateful Widget hale getir dediğimizde, kullandığımız IDE bizim için otomatik bir hale getirilecektir.

Slide ve Slide Dotları yerleştirmek için Column’ın altında onun için ayırdığımız yere gidiyoruz.

İlk başta Expanded Widget’ını tanımladık. Bu sayede kullanabileceğimiz tüm boşluğu kullanma imkanına sahibiz.

Ardından Stack tanımladık. Stack; birbiriyle ilişkili widget’ları bir arada tutan bir widget. Böylece düzenli ve istediğimiz bir şekilde ekranda görünüyorlar.

Bu Stack içinde PageView ve Stack oluşturuyoruz.

Kısaca Expanded (Stack (PageView(), Stack() ) ) yapısına sahip olduk.

_currentPage’in ilk sayfa olduğunu tanımladık.

PageController yaratıp, ilk sayfanın index numarasını verdik.

initState adlı fonksiyonda kısaca sayfalar arasındaki geçiş düzenini ve de hangi geçiş animasyonunu kullanacağımızı belirledik. Burada dikkat etmeniz gereken durum eklediğiniz Slide Item’a göre if fonksiyonunu düzenlemek. Bizim 3 adet Slide Item’ımız bulunmakta. Bu nedenle listemiz 0 1 2 indekslerine sahip, yani 3 olduğu an sınır oluyor. Bu sayıyı ekleme/çıkarma yapmanız doğrultusunda değiştirmelisiniz.



dispose adlı fonksiyon bir slide’dan diğerine geçerken diğer slide’ı atmaya yaramaktadır.

itemBuilder: (ctx, i) => SlideItem(i),

itemCount: slideList.length,

scrollDirection: Axis.horizontal,

controller: _pageController,

onPageChanged: _onPageChanged,

eklentileriyle slide’ların yatay düzlemde kaydırılacağını, sayfa kontrolünü, slideList listesinin eleman sayısı kadar elemana sahip olduğumuzu ve de SlideItem nesneleri tanımladık.

Bir altındaki Stack içerisinde de Slide Dots’larımız yer almakta. Burada bir for döngüsüyle birlikte if döngüsü kullanmaktayız. Tanımladığımız _currentPage hangi sayfanın aktif olduğunu söylemekte ve bu sayede Slide Dot’larla birlikte Slide Item’lar senkronizasyon olmuş bir şekilde çalışmakta.

import 'package:flutter/material.dart';
import '../model/slide.dart';
import '../widgets/slide_dots.dart';
import '../widgets/slide_item.dart';
import 'dart:async';
class StartScreen extends StatefulWidget {
  @override
  _StartScreenState createState() => _StartScreenState();
}


class _StartScreenState extends State<StartScreen> {
  int _currentPage = 0;

  final PageController _pageController = PageController(
    initialPage: 0
  );

  @override
  void initState() {
    super.initState();
    Timer.periodic(Duration(seconds: 5), (Timer timer) {

      if (_currentPage < 2) {
        _currentPage++;
      }
      else {
        _currentPage = 0;
      }
      _pageController.animateToPage(_currentPage, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
    });

  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _pageController.dispose();
  }

  _onPageChanged(int index) {
    setState(() {
      _currentPage = index;
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.white,
        child: Padding(
          padding: const EdgeInsets.all(50),
          child: Column(
            children:<Widget> [
              Expanded(
              child: Stack(
                alignment: AlignmentDirectional.bottomCenter,

                children: <Widget> [
                  PageView.builder(
                    itemBuilder: (ctx, i) => SlideItem(i),
                    itemCount: slideList.length,
                    scrollDirection: Axis.horizontal,
                    controller: _pageController,
                    onPageChanged: _onPageChanged,

                  ),
                  Stack(
                    children: <Widget> [
                      Container(
                        margin: const EdgeInsets.only(bottom: 40),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget> [
                            for (int i = 0 ; i < slideList.length; i++)
                              if (i == _currentPage)
                                SlideDots(true)
                            else
                              SlideDots(false)

                          ],
                        ),
                      ),
                    ],
                  ),
                ],
              ),
              ),




              SizedBox(height: 20,),

              Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget> [
                  FlatButton(
                      onPressed: () {},
                      child: Text('Hadi Başlayalım', style: TextStyle( fontSize: 18, color: Colors.white)
                        ,),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                  color: Theme.of(context).primaryColor,
                    padding: const EdgeInsets.all(15),

                  )
                ],
              ),
            ],
          ),
        ),
      )

    );

    throw UnimplementedError();
  }
}
page slider yapımı sonuç

Uygulamayı çalıştırdığımızda sonuç bu şekilde olacaktır.

Kodların olduğu github repo‘suna da bakabilirsiniz.



Kaynakça

https://youtu.be/oS7iK5ivgD0

https://api.flutter.dev/flutter/widgets/PageView/PageView.builder.html

Teknoloji'den geri kalmamak için e-posta listemize abone olun!

teknoloji, hayal gücü ve sanat dünyalarını seven, üçünü bir araya getirmeye hevesli bir bilgisayar mühendisliği öğrencisi.