バックエンド API から List of Item を取得し、リストの項目を Viewpager に水平に表示します。リストが取得され、ViewPager に正常に表示されました。しかし、問題は、最初のスライドがスムーズではなく、時々スムーズにスライドすることです。最初から滑りを滑らかにする方法
サーバーからリストを取得するために Retrofit と rxjava を使用します。また、LiveData を使用して Fragment の viewModel の変数の変化を観察します
TestimonialService.kt
@GET(Constants.API_TESTIMONIAL)
fun getAllTestimonial(): Flowable<Response<TestimonialResponse>>
WelcomeViewModel.kt
val uiState: MutableLiveData<Event<UiState<TestimonialResponse>>> = MutableLiveData()
fun getAllTestimonial() {
compositeDisposable += testimonialService.getAllTestimonial()
.performOnBackgroundOutputOnMain()
.doOnSubscribe { uiState.value = Event(loading(true)) }
.doOnTerminate { uiState.value = Event(loading(false)) }
.subscribe({
if (it.isSuccessful) {
uiState.value = Event(success(it.body()!!)!!)
} else {
uiState.value = Event(alert(it.code().toString()))
}
}, {
uiState.value = Event(failure(it))
})
}
TestimonialAdapter.kt
class TestimonialAdapter: RecyclerView.Adapter<TestimonialViewHolder>() {
var testimonialList: List<Testimonial>? = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestimonialViewHolder {
val view = ItemTestimonialBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return TestimonialViewHolder(view)
}
override fun onBindViewHolder(holder: TestimonialViewHolder, position: Int) {
holder.bind(testimonialList?.get(position)!!)
}
override fun getItemCount() = testimonialList?.size ?: 0
fun notifyChanged(testimonialList: ArrayList<Testimonial>) {
this.testimonialList = testimonialList
notifyDataSetChanged()
}
}
TestimonialViewHolder.kt
class TestimonialViewHolder(private val bindingView: ItemTestimonialBinding) : RecyclerView.ViewHolder(bindingView.root) {
fun bind(testimonial: Testimonial) {
bindingView.testimonial = testimonial
}
}
item.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>
<import type="com.caretutors.api.serviceModel.testimonials.Testimonial"/>
<variable name="testimonial" type="Testimonial" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
app:cardElevation="0dp"
app:cardCornerRadius="@dimen/_22sdp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center"
android:padding="5dp">
<ImageView
android:id="@+id/client_image_view"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginStart="5dp"
android:layout_gravity="center_vertical"
app:image="@{testimonial.photo}"
tools:src="@drawable/ic_round_avatar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/name_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@{testimonial.name}"
tools:text="@string/john_doe"
android:textColor="@color/black_85_percent"
android:textSize="@dimen/fourteen_sp_text_size"
android:fontFamily="@font/inter_semi_bold"/>
<TextView
android:id="@+id/designation_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-4dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@{testimonial.designation}"
tools:text="@string/web_developer"
android:textColor="@color/dark_ash"
android:textSize="@dimen/twelve_sp_text_size" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:fillViewport="true">
<TextView
android:id="@+id/comment_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:justificationMode="inter_word"
android:ellipsize="end"
android:text="@{testimonial.comment}"
tools:text="@string/short_description"
android:textColor="@color/black_50_percent"
android:textSize="@dimen/eleven_sp_text_size" />
</ScrollView>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</layout>
fragment.welcome.xml
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/testimonial_view_pager"
android:layout_width="match_parent"
android:layout_height="@dimen/_110sdp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:orientation="horizontal" />
WelcomeFragment.kt
override fun initWidget() {
with(testimonial_view_pager) {
adapter = testimonialAdapter
offscreenPageLimit = 1
setPageTransformer(CustomPageTransformer(context!!, R.dimen.testimonial_viewpager_visible_portion_of_next_item, R.dimen.testimonial_viewpager_current_item_horizontal_margin))
addItemDecoration(CustomHorizontalMarginItemDecorator(context, R.dimen.testimonial_viewpager_current_item_horizontal_margin))
}
}
override fun observeLiveData() {
with(viewModel) {
getAllTestimonial()
uiState.observe(this@WelcomeFragment, Observer {
it.getContentIfNotHandled()?.let { state ->
when (state) {
is Progress -> {
with(shimmer_view_container) {
if (state.isLoading) {
startShimmer()
} else {
stopShimmer()
visibilityGone()
}
}
}
is Success -> {
val testimonialList = state.successInfo.data as ArrayList<Testimonial>
testimonialAdapter.notifyChanged(testimonialList)
AutoSlider(testimonial_view_pager, testimonialList.size).startAutoSlider()
}
is Alert -> context?.showToast(state.alert)
is Failure -> {
if (state.throwable is IOException) {
context?.showToast("Internet Connection Failed")
} else {
context?.showToast("Json Parsing Error")
}
}
}
}
})
}
}
AutoSlider.kt
class AutoSlider(private val viewPager: ViewPager2, private val totalItem: Int) {
private var runnable: Runnable? = null
private val handler = Handler()
init {
runnable = Runnable {
var position = viewPager.currentItem
position += 1
if (position >= totalItem) position = 0
viewPager.currentItem = position
}
}
fun startAutoSlider() {
val swipeTimer = Timer()
swipeTimer.schedule(object : TimerTask() {
override fun run() {
handler.post(runnable)
}
}, 3000, 3000)
}
}
最初はスクロールがスムーズではありません。しかし、時々、スムーズにスクロールし始めます