آموزش نرم افزار DB Browser SQLite
آموزش نرم افزار DB Browser SQLite
1398-06-15
ساختارهای کنترلی در کاتلین : if ، when ، for و while
ساختارهای کنترلی در کاتلین : if ، when ، for و while
1398-06-16
سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin

سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin ، در این پست از تجاری اپ میخوایم کمی پروژه محور تر به کاتلین نگاه کنیم و نمایش لیست با recyclerview در کاتلین (پروژه نمایش لیست کتابها در کاتلین) را آموزش بدیم .بهتون پیشنهاد میکنم که اگر پست های قبلی آموزش کاتلین تجاری اپ رو مطالعه نکردید حتما مطالعه کنید و بعد این پست رو مطالعه و تمرین کنید.

سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

ساخت پروژه نمایش لیست کتابها در کاتلین

در این پروژه میخوایم دیتا یک سری کتاب که درون دیتابیس sqlite درون اپلیکیشن ذخیره شده رو واکشی و درون یک recyclerView ( نمایش لیست با recyclerview در کاتلین ) نمایش بدیم.

پس قبل از هرچیز یک پروژه کاتلین ایجاد میکنیم ، با کلیک برروی

start a new Android studio project

یک پروژه جدید ایجاد میکنیم.مرحله بعد گزینه Empty Activity رو انتخاب میکنیم و در مرحله آخر مطابق تصویر زیر گزینه language رو حتما kotlin انتخاب میکنیم

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

حالا خواهیم دید که درون فایل Gradle پروژه وابستگی های مربوط به کاتلین ایجاد شده و میتونیم خیلی راحت کدهای کاتلین رو بزنیم.
پس شروع میکنیم به کدنویسی 🙂

سورس کد پروژه نمایش لیست کتابها در کاتلین

اولین دستوری که باید بنویسیم اضافه کردن وابستگی های sqlite هستش برای اینکه بتونیم از دیتابیس sqlite درون اپلیکیشن استفاده کنیم پس دستورات زیر رو به گردل برنامه اضافه میکنیم

    implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:2.0.1'

خب حالا باید با استفاده از نرم افزار DB Browser for SQLite یک دیتابیس ایجاد کنیم و بعد فایل دیتابیس sqlite ایجاد شده رو درون پروژه اندروید ایمپورت کنیم

من یک دیتابیس با نام BooksDB و درون آن یک جدول با نام tbl_books ایجاد کردم و جدول رو بدین صورت طراحی کردم

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

حالا میتونیم فایل دیتابیس sqlite رو به پروژه ایمپورت کنیم

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

خب الان فایل دیتابیس sqlite که حاوی اطلاعات یک سری کتاب هست رو درون پروژه اندروید خود داریم و میتونیم از دیتاهای داخلش استفاده کنیم
پس قبل از هرکار باید کلاس های مورد نیاز برای دسترسی به دیتابیس رو ایجاد کنیم

پس بریم سراغ کدنویسی 🙂 !

درون دایرکتوری جاوا یک پکیج با عنوان db ایجاد میکنیم و کلاس های مربوط به دیتابیس رو درون این پکیج ایجاد میکنیم ، پکیج رو با کلیک راست برروی فولدر اصلی کلاس های جاوا یعنی:

java / com.tejaripp.kotlinprac

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

و سپس New / package ایجاد میکنیم

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

حالا درون پکیج db یک کلاس جاوا با عنوان DataBaseOpenHelper برای ایجاد بستر دسترسی به دیتابیس ایجاد میکنیم و درون آن دستورات زیر را مینویسیم

package com.tejariapp.kotlinprac.db

import android.content.Context
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper

class DataBaseOpenHelper(context: Context) : SQLiteAssetHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
    companion object {
        private val DATABASE_NAME = "BooksDB.db"
        private val DATABASE_VERSION = 1
    }
}

کلاس ایجاد شده از کلاس SQLiteAssetHelper مربوط به کتابخانه sqliteassethelper ارث بری میکند و همونطور که مشخصه دو متغیر companion داریم نام فایل دیتابیس و ورژن دیتابیس رو مشخص کردیم (توجه کنید که نام دیتابیس دقیقا نام همان فایلی که درون مسیر زیر قرار دادیم باشد)

src / main / assets / databases /

و یک ورژن برای دیتابیس که درواقع بیشتر زمانی کاربرد دارد که میخواهیم آپدیت هایی برروی دیتابیس بزنیم و ورژن بندی کنیم
و در ادامه هم مقادیر مورد نیاز سازنده کلاس پدر را برایش ارسال کردیم

حالا یک کلاس کاتلین درون پکیج db بصورت زیر ایجاد میکنیم

New / Kotlin FileClass

و یک کلاس با عنوان Books ایجاد میکنیم سپس دستورات زیر را درون کلاس کاتلین Books قرار میدهیم:

package com.tejariapp.kotlinprac.db

data class Books(val  id:Int,val name: String , val img: String , val date:String , val writer: String)

کلاس Books درواقع برای گرفتن دیتاها از دیتابیس کاربرد دارد که درادامه از آن استفاده خواهیم کرد.همونطور که میبینید ما از data class استفاده کردیم چون میخواهیم یک سری دیتا به این کلاس بدهیم و از آن استفاده کنیم به علاوه فیلدهایی که برای این کلاس کاتلین مشخص کردیم دقیقا همان فیلدهای جدولی ست که درون دیتابیس ایجاد کردیم و همه بصورت val تعریف شدند چرا که مقادیری که از دیتابیس درون این فیلدها قرار گرفت هیچوقت نیاز به تغییر نخواهند داشت و فقط قرار است درون اپلیکیشن نمایش داده شود

خب حالا یک کلاس دیگر درون پکیج db با عنوان DatabaseAccess ایجاد میکنیم برای گرفتن داده ها از دیتابیس

package com.tejariapp.kotlinprac.db

import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import java.util.*

class DatabaseAccess private constructor(context: Context) {

    private val openHelper: SQLiteOpenHelper
    private lateinit var db: SQLiteDatabase
    lateinit var c: Cursor

    init {
        this.openHelper = DataBaseOpenHelper(context)
    }


    // open database connection
  private  fun open() {
        this.db = openHelper.writableDatabase
    }

    // close database connection
   private fun close() {
        this.db.close()
    }

    companion object {
        private var instance: DatabaseAccess? = null

        fun getInstance(context: Context): DatabaseAccess {
            if (instance == null)
                instance = DatabaseAccess(context)
            return instance as DatabaseAccess
        }
    }

   fun getBooks(): ArrayList<Books> {
        open()
        val data = ArrayList<Books>()
        c = db.query("tbl_books", arrayOf("id", "name", "img", "date", "writer"), null, null, null, null, null)
        while (c.moveToNext()) {
            data.add(Books(c.getInt(0), c.getString(1), c.getString(2)
                , c.getString(3), c.getString(4)))
        }
        close()
        return data
    }
}

کلاس DatabaseAccess همانطور که مشخصه یک سازنده اصلی و البته private دارد که تنها یک پارامتر context میگیرد که از این کانستراکتور یا سازنده در متد getInstance که بصورت comopanion تعریف شده استفاده میشود.
در بدنه کلاس هم نمونه هایی از کلاس های SqliteOpenHelper ، SqliteDatabase و Cursor ایجاد شده که درادامه کدهای کلاس از تمامی آنها استفاده شده.
در بلاک init که اولین بلاک پس از ساخت یک نمونه از کلاس اجرا میشه فیلد db مقداردهی شده برای استفاده از آن به عنوان باز و بسته کردن دریچه ی دسترسی به دیتابیس در متدهای open و close وهمچنین اجرای کوئری های دریافت اطلاعات از دیتابیس.
یک متد getBooks هم داریم که خروجی آن از نوع ArrayList است و با اجرای کوئری select از جدول tbl_books که درون فایل دیتابیس ایجاد کردیم تمامی رکوردها با تمامی فیلدها را انتخاب و دریافت میکند سپس با استفاده از فیلد cursor یکی یکی رکورد هارو به یک شی از کلاس Books که در بالا ایجاد کردیم تبدیل میکنیم و در نهایت همه را درون یک لیست به عنوان خروجی متد برمیگردانیم.

خب حالا باید یک recyclerView درون MainActivity پیاده و اداپتر آن را کانفیگ کنیم پس درون لایه activity_main یک recyclerView بصورت زیر پیاده میکنیم

<android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

به علاوه یک لایه دیگر برای آیتم های درون لیست با نام view_book_item ایجاد میکنیم با محتویات زیر:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    app:cardCornerRadius="5dp"
    app:cardElevation="5dp">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <ImageView
            android:id="@+id/iv_profile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@mipmap/ic_launcher" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="نام کتاب :"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/tv_name"
            app:layout_constraintTop_toBottomOf="@+id/iv_profile" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:gravity="right"
            android:text="TextView"
            app:layout_constraintEnd_toStartOf="@+id/textView"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/textView" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="نام نویسنده کتاب :"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/tv_writer"
            app:layout_constraintTop_toBottomOf="@+id/tv_name" />

        <TextView
            android:id="@+id/tv_writer"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:gravity="right"
            android:text="TextView"
            app:layout_constraintEnd_toStartOf="@+id/textView3"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/textView3" />

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="سال انتشار کتاب :"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/tv_date"
            app:layout_constraintTop_toBottomOf="@+id/tv_writer" />

        <TextView
            android:id="@+id/tv_date"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:gravity="right"
            android:text="TextView"
            app:layout_constraintEnd_toStartOf="@+id/textView5"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/textView5" />
    </android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>

حالا یک کلاس کاتلین BooksAdapter درون پکیج اصلی کلاس ها کنار MainActivity ایجاد میکنیم

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

درون این کلاس دستورات اداپتر RecyclerView رو مطابق زیر مینویسیم

package com.tejariapp.kotlinprac

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
import com.tejariapp.kotlinprac.db.Books
import kotlinx.android.synthetic.main.view_book_item.view.*

class BooksAdapter(private val mContext: Context, private val mList: ArrayList<Books>) : RecyclerView.Adapter<BooksAdapter.MyViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, pos: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.view_book_item, parent, false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int = mList.size

    override fun onBindViewHolder(holder: MyViewHolder, pos: Int) {
        val book = mList[pos]
        holder.setItems(mContext,book)
    }

    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun setItems(mContext: Context,book: Books) {
            itemView.tv_name.text = book.name
            itemView.tv_date.text = book.date
            itemView.tv_writer.text = book.writer

            Glide
                .with(mContext)
                .load(book.img)
                .centerCrop()
                .placeholder(R.mipmap.ic_launcher)
                .into(itemView.iv_profile)
        }
    }
}

ما از کتابخونه Glide برای لود کردن تصاویر استفاده کردیم پس وابستگی یا dependency زیر رو به گردل پروژه اضافه میکنیم

https://github.com/bumptech/glide

build.gradle (app)
    implementation 'com.github.bumptech.glide:glide:4.9.0'


build.gradle (project)

repositories {
  mavenCentral()
  google()
}

اداپتر ریسایکلر ویو مانند اداپتر های جاواست اما با کمی تفاوت سینتکسی.درابتدا ما در سازنده اصلی کلاس اداپتر دو مقدار context و mlist گرفتیم که درواقع mlist همان لیست کتاب هایی ست که از دیتابیس دریافت کردیم و باید درون recyclerView نمایش دهیم.

در متد onBindViewHolder برای هر آیتم لیست متدی که درون ViewHolder اداپتر تعریف شده رو برای مقدار دهی به ویو های درون لایه آیتم لیست فراخوانی میکنیم.

یک نکته جالب درباره کاتلین کوتاه کننده متدهای بازگشتی ست . همانطور که متد getItemCount رو میبینید چون یک مقدار int رو برمیگردونه و بدنه این متدهم تک خطی ست و همان خط هم مقدار مورد نظر رو برمیگردونه میتونیم بجای نوشتن این متد بصورت زیر

 override fun getItemCount(): Int {
        return mList.size
    }

از کوتاه کننده های کاتلین استفاده کنیم و بصورت زیر این متد رو پیاده کنیم

   override fun getItemCount(): Int = mList.size

حالا دستورات نهایی رو درون کلاس MainActivity بدین صورت مینویسیم

package com.tejariapp.kotlinprac

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.widget.Toast
import com.tejariapp.kotlinprac.db.Books
import com.tejariapp.kotlinprac.db.DatabaseAccess
import kotlinx.android.synthetic.main.activity_main.*

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

        recycler.layoutManager = LinearLayoutManager(this)

        getData()
    }

    private fun getData(){
        var list: ArrayList<Books>
        val access = DatabaseAccess.getInstance(this)

        list = access.getBooks()

        recycler.adapter = BooksAdapter(this,list)
    }
}

در نهایت پروژه رو اجرا کنید و نتیجه رو بدین صورت ببینید

سورس کد نمایش لیست در کاتلین - آموزش برنامه نویسی kotlin
سورس کد نمایش لیست در کاتلین – آموزش برنامه نویسی kotlin

سرفصل های آموزش زبان کاتلین (Kotlin):

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *