Postingan lainnya
Adapter recycleview tidak terbaca
Mastah, saya mau bertanya lagi.
Rencanannya saya mau buat fragment berisi detail barang sesuai dengan ID yang didapatkan dari fragment sebelumnya.
Nah, di fragment detail barang saya mau pasang recycleview untuk menampilkan slide gambar-gambar barangnya. Tapi entah kenapa adapternya tidak terjalankan, padahal sudah dipanggil di fragment detail barang.
Ini script untuk manggil APInya:
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import kotlinx.coroutines.Deferred
import okhttp3.OkHttpClient
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
object Apifactory{
// Add legacy cipher suite for Android 4
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
fun retrofit() : Retrofit = Retrofit.Builder()
.client(OkHttpClient().newBuilder().build())
.baseUrl("https://next.json-generator.com/")
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
val placeHolderApi : PlaceholderApi = retrofit().create(PlaceholderApi::class.java)
}
interface PlaceholderApi{
@GET("api/json/get/N1WAZtL1u")
fun getPosts() : Deferred<Response<List<BarangData>>>
@GET("api/json/get/NkQP2XCkd")
fun getDetail() : Deferred<Response<DetailBarang>>
}
Data Class Detail Barang :
data class DetailBarang(
val id: String,
val nama: String?,
val harga: String?,
val sisa: String?,
val nama_toko: String?,
val alamat_toko: String?,
val dest: String?,
val image: List<DataImage> = listOf<DataImage>()
)
Data Class Image :
data class DataImage(
val id: String,
val Image: String
)
XML Detail barang (Fragment_Detailbr.xml) :
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="com.reitorious.ajimart.overview.barang.DetailbrViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#22FFFFFF">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".overview.barang.DetailbrFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_Image"
android:layout_width="match_parent"
android:layout_height="200dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="horizontal"
app:spanCount="2"
tools:listitem="@layout/image_single"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.cardview.widget.CardView
android:id="@+id/cardView3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/recycler_Image">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.item.harga}"
android:textSize="21sp"
app:fontFamily="sans-serif-condensed-medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.03"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.item.sisa}"
android:textSize="21sp"
app:fontFamily="sans-serif-condensed-medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.94"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardView2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView3">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mikhaellopez.circularimageview.CircularImageView
android:id="@+id/profile_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/ajimart"
app:civ_border_color="#3f51b5"
app:civ_border_width="4dp"
app:civ_shadow="true"
app:civ_shadow_color="#3f51b5"
app:civ_shadow_radius="10"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.03"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:text="@{viewModel.item.nama_toko}"
app:fontFamily="sans-serif-condensed-medium"
app:layout_constraintStart_toEndOf="@+id/profile_image"
app:layout_constraintTop_toTopOf="@+id/profile_image" />
<TextView
android:id="@+id/textView4"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{viewModel.item.alamat_toko}"
app:fontFamily="sans-serif-condensed-medium"
app:layout_constraintEnd_toEndOf="@+id/textView3"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/textView3"
app:layout_constraintTop_toBottomOf="@+id/textView3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Deskripsi"
android:textAlignment="center"
android:textSize="24dp"
app:fontFamily="sans-serif-condensed-medium" />
<TextView
android:id="@+id/textView6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="@{viewModel.item.dest}"
app:fontFamily="sans-serif-condensed-medium" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
Image_Single.xml :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="@+id/rootContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"/>
</LinearLayout>
</layout>
Data view modelnya (DetailbrViewModel) :
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.reitorious.ajimart.connection.Apifactory
import com.reitorious.ajimart.connection.DataImage
import com.reitorious.ajimart.connection.DetailBarang
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.lang.Exception
class DetailbrViewModel(id : String) : ViewModel(){
private val _response = MutableLiveData<DetailBarang>()
private val _images = MutableLiveData<List<DataImage>>()
val item : LiveData<DetailBarang>
get() = _response
val images : LiveData<List<DataImage>>
get() = _images
init {
Log.d("debug", "Detail Kebuka ID : " + id)
iniData()
}
private fun iniData(){
val service = Apifactory.placeHolderApi
GlobalScope.launch(Dispatchers.Main) {
val detailBarang = service.getDetail()
try {
val response = detailBarang.await()
val barang = response.body()
_response.value = barang
_images.value = barang!!.image
}catch (e: Exception){
Log.d("debug", "Error Koneksi : " + e)
}
}
}
}
Recyclerview Adapter (DetailbrImageAdapter) :
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.reitorious.ajimart.connection.DataImage
import com.reitorious.ajimart.databinding.ImageSingleBinding
import com.reitorious.ajimart.showImage
class DetailbrImageAdapter (private val viewModel: DetailbrViewModel):
ListAdapter<DataImage, DetailbrImageAdapter.DetailbrImageViewHolder>(DiffCallbackDetail){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DetailbrImageViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = ImageSingleBinding.inflate(inflater)
return DetailbrImageViewHolder(binding)
}
override fun onBindViewHolder(holder: DetailbrImageViewHolder, position: Int) {
// Fungsi Glide showImage(ImageView, url)
showImage(holder.image, viewModel.images.value!![position].Image)
}
inner class DetailbrImageViewHolder(private var binding: ImageSingleBinding):
RecyclerView.ViewHolder(binding.root){
val image = binding.image
}
companion object DiffCallbackDetail: DiffUtil.ItemCallback<DataImage>(){
override fun areItemsTheSame(oldItem: DataImage, newItem: DataImage): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: DataImage, newItem: DataImage): Boolean {
return oldItem.equals(newItem)
}
}
}
Kotlin Detail Barang (DetailbrFragment) :
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
import com.reitorious.ajimart.databinding.FragmentDetailbrBinding
class DetailbrFragment : Fragment() {
private lateinit var recyclerview: RecyclerView
private lateinit var viewModel: DetailbrViewModel
private lateinit var viewAdapter: DetailbrImageAdapter
private lateinit var binding: FragmentDetailbrBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentDetailbrBinding.inflate(inflater)
binding.setLifecycleOwner(this)
// Menerima ID dari fragment sebelumnya
var argsID = DetailbrFragmentArgs.fromBundle(arguments!!).id
val vmFactory = DetailbrViewModelFactory(argsID)
viewModel = ViewModelProviders.of(this, vmFactory).get(DetailbrViewModel::class.java)
binding.viewModel = viewModel
viewAdapter = DetailbrImageAdapter(viewModel)
recyclerview = binding.recyclerImage
recyclerview.apply {
adapter = viewAdapter
}
return binding.root
}
}
Dan hasilnya semua data berhasil ditampilkan kecuali recyclerview :
Mohon bantuannya... Terima kasih sebelumnya
1 Jawaban:
sepertinya ada typo <pre> recyclerview = binding.recyclerImage </pre>
harusnya <pre> recyclerview = binding.recycler_Image </pre>