cara memuat di Kotlin

MainActivity saya berisi ViewPager yang memuat 4 fragmen, setiap fragmen harus memuat banyak data dari server.

jadi ketika aplikasi saya ingin dijalankan untuk pertama kalinya, hampir memakan waktu lebih dari 3 detik dan di waktu lain (misalnya, jika Anda keluar dari aplikasi tetapi tidak membersihkannya dari jendela 'aplikasi terbaru' dan membukanya kembali) diperlukan waktu hampir 1 detik.

saat sedang memuat, ini menampilkan layar putih.

apakah ada cara selain menampilkan layar putih sampai data siap, saya menampilkan gambar saya sendiri? sesuatu seperti halaman pembuka?


person Mohammad    schedule 27.01.2020    source sumber
comment
Tata letak Anda harus memiliki tampilan alternatif untuk ditampilkan saat sedang dimuat. Tampilan daftar harus disembunyikan. Kemudian tukar visibilitas saat data siap ditampilkan. Anda perlu memuat data dalam tugas asinkron di latar belakang sehingga Anda tidak berisiko terkena ANR. Hal ini dapat dilakukan paling mudah dengan menggunakan coroutine dalam ViewModel untuk datanya. Terlalu banyak yang perlu dijelaskan di sini tetapi ada banyak tutorial yang bisa Anda temukan.   -  person Tenfour04    schedule 27.01.2020
comment
terima kasih atas tanggapan Anda, sayangnya, saya belum sepenuhnya paham dengan android dan saya sedang meningkatkan keterampilan saya. bisakah Anda menyarankan saya tutorial?   -  person Mohammad    schedule 28.01.2020
comment
Ada berbagai macam topik di sini. Saya akan mulai dengan dokumentasi resmi Android di ViewModel. Saya akan memposting ikhtisar singkat di bawah ketika saya punya waktu.   -  person Tenfour04    schedule 28.01.2020
comment
terima kasih banyak.@Tenfour04   -  person Mohammad    schedule 28.01.2020


Jawaban (1)


Jika Anda melakukan tindakan jangka panjang di thread utama, Anda berisiko mengalami ANR crash.

Tata letak Anda untuk setiap fragmen harus memiliki tampilan pemuatan yang terlihat pada awalnya, dan tampilan data Anda. Sesuatu seperti ini:

(bukan kode)

FrameLayout
    loading_view (can show a progress spinner or something, size is match parent)
    content_view (probably a RecyclerView, initial visibility=GONE, size is match parent)
/FrameLayout

Anda perlu melakukan tindakan jangka panjang pada thread latar belakang atau coroutine, lalu menukar visibilitas kedua tampilan ini saat data siap ditampilkan di UI.

Anda tidak boleh menangani pemuatan data secara langsung dalam kode Fragmen Anda, karena Fragmen adalah pengontrol UI. Library Android Jetpack menyediakan kelas ViewModel untuk tujuan ini. Anda akan menyiapkan ViewModel Anda seperti ini. Dalam contoh ini, MyData bisa berupa apa saja. Dalam kasus Anda, kemungkinan besar itu adalah Daftar atau Kumpulan sesuatu.

class MyBigDataViewModel(application: Application): AndroidViewModel(application) {

    private val _myBigLiveData = MutableLiveData<MyData>()
    val myBigLiveData: LiveData<MyData>() = _myBigLiveData 

    init {
        loadMyBigData()
    }

    private fun loadMyBigData() {
        viewModelScope.launch { // start a coroutine in the main UI thread
            val myData: MyData = withContext(Dispatchers.Default) { 
                // code in this block is done on background coroutine
                // Calculate MyData here and return it from lambda
                // If you have a big for-loop, you might want to call yield()
                // inside the loop to allow this job to be cancelled early if
                // the Activity is closed before loading was finished.
                //...
                return@withContext calculatedData
            }

            // LiveData can only be accessed from the main UI thread so
            // we do it outside the withContext block
            _myBigLiveData.value = myData
        }
    }

}

Kemudian di fragmen Anda, Anda mengamati data langsung untuk memperbarui UI ketika sudah siap. Di bawah ini menggunakan perpustakaan fragment-ktx, yang perlu Anda tambahkan ke proyek Anda. Anda pastinya harus membaca dokumentasi di ViewModel.

class MyFragment: Fragment() {

    // ViewModels should not be instantiated directly, or they won't be scoped to the
    // UI life cycle correctly. The activityViewModels delegate handles instantiation for us.
    private val model: MyBigDataViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        model.myBigLiveData.observe(this, Observer<MyData> { myData ->
            loading_view.visibility = View.GONE
            content_view.visibility = View.VISIBLE
            // use myData to update the view content
        })
    }
}
person Tenfour04    schedule 28.01.2020