پیاده سازی SwipeRefreshLayout با کاتلین

توی این مطلب قصد داریم با استفاده از ListView و SwipeRefreshLayout لیستی رو ایجاد کنیم که با کشدن اون به سمت پایین آپدیت بشه.



یه مثال کوچیک از کاری که قرار هست انجام بدیم رو می‌تونید پایین ببینید. البته ما از یه سری دیتای ساده برای پر کردن لیست خودمون استفاده می کنیم. پروژه‌ای که قراره انجامش بدیم فقط از یه اکتیویتی تشکیل شده.

من وقت ساختن پروژه تیک استفاده از androidx رو زدم. صرفا برای آشنایی بیشتر با این پروژه اندروید، می تونید دیپندنسی های پروژه رو ببینید. توجه داشته باشید که حتما کتابخونه‌ی com.android.support:design رو اضافه کرده باشید به اپ خودتون:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.1'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}


حالا به سراغ activity_main.xml خودمون میریم و اون رو مطابق کد زیر عوض می‌کنیم:

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

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:id="@+id/mSwipeLayout"
        android:layout_height="match_parent">

        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/mListView"/>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

خب تغییرات لازم رو توی MainActivity هم میدیم:

private var sampleList = mutableListOf<String>()
private lateinit var adapter: ArrayAdapter<String>
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    actionBar?.title = "SwipeRefreshLayout Example"
    mSwipeLayout.setColorSchemeColors(Color.parseColor("#27ae60"))
    handleListView()
    mSwipeLayout.setOnRefreshListener {
        handleRefresh()
    }
}

private fun handleListView() {
    for (i in 0..5)
        sampleList.add(i, "Current Element: $i")
    adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, sampleList)
    mListView.adapter = adapter
}

private fun handleRefresh() {
    mSwipeLayout.isRefreshing = true
    sampleList.shuffle(Random(System.currentTimeMillis()))
    adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, sampleList)
    mListView.adapter = adapter
    mSwipeLayout.isRefreshing = false
}

من توی کد بالا:

  • توی خط ۷ رنگ پراگرس باری که برای رفرش هست رو تغییر دادم
  • از خط ۱۴ تا ۱۸ من ۵ المان ساختم، آداپتور رو ایجاد کردم و به لیست ویو اضافش کردم
  • توی متد handleRefresh من اول isRefreshing رو برابر true قرار دادم تا پروگرس بار نمایش داده بشه و بعد از پر کردن مجدد آداپتور، به mSwipeLayout گفتم که مقدار isRefreshing رو false کنه.

هیچ چیز خاصی در مورد پیاده سازی SwipeRefreshLayout وجود نداره. فقط این که گوگل پیشنهاد داده عملیات ریفرش رو به اکشن بار/تولبار خودمون هم اضافه کنیم تا اپ ما برای کسایی که ناتوانی‌های حرکتی هم دارن مناسب باشه. پیاده سازی اون قسمت هم خیلی سادست. ابتدا یه منو می سازیم:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_refresh"
        android:title="@string/string_refresh"
        app:showAsAction="always" />
</menu>

و در مرحله‌ی بعد متد onOptionsItemSelected رو توی MainActivity خودمون به این صورت ایجاد می کنیم:

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.manu_main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    when (item?.itemId) {
        R.id.menu_refresh -> {
            Log.d("p4yam", "clicked")

            handleRefresh()
            return true
        }
    }

    return super.onOptionsItemSelected(item)
}

پیاده سازی SwipeRefreshLayout با هر View دیگه ای به همین سادگیه. امیدوارم از این مطلب خوشتون اومده باشه.