رفتن به مطلب
  • 0

سه مشکل اساسی در استفاده از دو ریسایکلر ویو


fun_code

سوال

سلام دوستان

من از دو ریسایکلر ویو ،  coordinator ،  appbar layout و collaping toolbar layout در یک صفحه استفاده کردم. (دو ریسایکلر جدا هستن و در بالا و پایین صفحه)

با سه مشکل اساسی مواجه شدم و ممنون میشم راهنماییم کنید.

1. میخوام swip refresh layout بذارم جوری که دو ریسایکلر ویو رو شامل بشه اما نمیشه و ریسایکلر ویو بالا رو قبولش نمیکنه و واسه ریسایکلر ویو پایینی هم نمیشه.

2. زمانی که ریسایکلر ویو پایین صفحه خالی هست و آیتمی نداره appbar layout باز و بسته میشه و پایین صفحه یه بخش خالی رو با کاربر نمایش میده و کاربر که اسکرول میکنه بخش خالی رو میبینه.

3. یه سرچ باکس در همین صفحه درست کردم و بالای صفحه است. میخوام اون بالا ثابت بمونه و با اسکرول حرکت نکنه. اما نمیشه و با اسکرول بالا و پایین میشه و کاربر بره انتهای لیست و بخواد سرچ کنه باید اسکرول کنه و برگرده بالای بالای لیست.

پیشاپیش از راراهنمایی شما عزیزان سپاسگزارم

لینک ارسال
به اشتراک گذاری در سایت های دیگر

7 پاسخ به این سوال تاکنون داده شده است

ارسال‌های توصیه شده

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

لینک ارسال
به اشتراک گذاری در سایت های دیگر

سلام و درود. خیلی پیچیده ش کردی😅. یه اسکرین از مواردی که گفتین بزارین

لینک ارسال
به اشتراک گذاری در سایت های دیگر

در ۱۴۰۰/۹/۸ در ۲۱:۵۱، محمدرضا شاهپیری گفته است:

سلام و درود. خیلی پیچیده ش کردی😅. یه اسکرین از مواردی که گفتین بزارین

سلام استاد عزیز

خوشبختانه ثابت شدن سرچ باکس اوکی شده...

الان چیزایی که اسکرول میشن بنر هست که ایندیکیتور هست.

و دو ریسایکر که اولی افقی و دیگری عمودیه...

در ریسایکر بالا آگهی های خاصی با اسکرول افقی هستن

در ریسایکلر پایین اگهی های معمولی با اسکرول عمودی هستن.

مشکلات زیر پابرجاست 😔

1. میخوام swip refresh layout بذارم جوری که دو ریسایکلر ویو رو شامل بشه اما نمیشه و ریسایکلر ویو بالا رو قبولش نمیکنه و واسه ریسایکلر ویو پایینی هم نمیشه.

2. زمانی که ریسایکلر ویو پایین صفحه خالی هست و آیتمی نداره appbar layout باز و بسته میشه و پایین صفحه یه بخش خالی رو با کاربر نمایش میده و کاربر که اسکرول میکنه بخش خالی رو میبینه.

 

لینک دانلود اسکرین ویدیو از صفحه اصلی اپ که مشکل داره:

https://uupload.ir/view/screen_record_w8tt.mp4

 

در کلیپ ، اولین آگهی در ریسایکلر افقیه قرار داره ، از اون آگهی به بعد همگی در ریسایکلر عمودی هستن و اگر زمانی سرچ کنیم و آرایه خالی باشه تمام اون فضای ریسایکلر پایینی خالی خواهد بود و اسکرول فقط فضای خالی رو نمایش میده !

استاد بزرگوار ببخشید اگر طولانی شد. سعی کردم شفاف توضیح بدم 🌹

 

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

اولا واسه اینکه بخواین یه ریسایکلر افقی رو توی عمودی بزارید حتما باید یه سری تنظیمات رو برای ریسایکلر افقی فعال کنید. که من یه کاستوم ریسایکلر رو ترجیح میدم. به شکل زیر

package com.doreshia.app.ui.widget

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewTreeObserver
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class HorizontalRecyclerView @JvmOverloads constructor(
    context:Context,
    attrs:AttributeSet?=null,
    defStyle:Int=0
):RecyclerView(context,attrs,defStyle){
    init {
        layoutManager= LinearLayoutManager(context,HORIZONTAL,true)
        overScrollMode = View.OVER_SCROLL_NEVER
        setHasFixedSize(true)
        isNestedScrollingEnabled = false
        itemAnimator?.changeDuration = 0
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    viewTreeObserver.removeOnGlobalLayoutListener(this)
              }
        })
    }
}

علاوه بر تنظیمات بالا حتما توی آداپتر اصلیتون هم یه دونه متغیر از نوع RecycledViewPool تعریف کنید و به ریسایکلر افقی بدید که با هر بار bind شدن ViewPool جدید ساخته نشه. کلاس زیر رو به دقت بخونید و ایده بگیرید

 companion object{
        private val viewPool = RecyclerView.RecycledViewPool()
 }
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return  SlideHolder(HorizontalRecyclerView(parent.context))
 }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as SlideHolder).bind(items)
 }
private class SlideHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val recyclerBannerView = itemView as HorizontalRecyclerView
        init {
            recyclerBannerView.setRecycledViewPool(viewPool)
            recyclerBannerView.adapter=Adapter()
        }
        fun bind(items: ArrayList<Item>){
            (recyclerBannerView.adapter as? Adapter)?.updateData(items)
        }
    }

 

واما برای refreshlayout که به نظرم کار خاصی نیاز نیست انجام بشه. به شکل زیر تو xml ست کنید

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

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

در ۱۴۰۰/۹/۹ در ۰۱:۱۴، محمدرضا شاهپیری گفته است:

اولا واسه اینکه بخواین یه ریسایکلر افقی رو توی عمودی بزارید حتما باید یه سری تنظیمات رو برای ریسایکلر افقی فعال کنید. که من یه کاستوم ریسایکلر رو ترجیح میدم. به شکل زیر

package com.doreshia.app.ui.widget

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewTreeObserver
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class HorizontalRecyclerView @JvmOverloads constructor(
    context:Context,
    attrs:AttributeSet?=null,
    defStyle:Int=0
):RecyclerView(context,attrs,defStyle){
    init {
        layoutManager= LinearLayoutManager(context,HORIZONTAL,true)
        overScrollMode = View.OVER_SCROLL_NEVER
        setHasFixedSize(true)
        isNestedScrollingEnabled = false
        itemAnimator?.changeDuration = 0
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    viewTreeObserver.removeOnGlobalLayoutListener(this)
              }
        })
    }
}

علاوه بر تنظیمات بالا حتما توی آداپتر اصلیتون هم یه دونه متغیر از نوع RecycledViewPool تعریف کنید و به ریسایکلر افقی بدید که با هر بار bind شدن ViewPool جدید ساخته نشه. کلاس زیر رو به دقت بخونید و ایده بگیرید

 companion object{
        private val viewPool = RecyclerView.RecycledViewPool()
 }
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return  SlideHolder(HorizontalRecyclerView(parent.context))
 }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as SlideHolder).bind(items)
 }
private class SlideHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val recyclerBannerView = itemView as HorizontalRecyclerView
        init {
            recyclerBannerView.setRecycledViewPool(viewPool)
            recyclerBannerView.adapter=Adapter()
        }
        fun bind(items: ArrayList<Item>){
            (recyclerBannerView.adapter as? Adapter)?.updateData(items)
        }
    }

 

واما برای refreshlayout که به نظرم کار خاصی نیاز نیست انجام بشه. به شکل زیر تو xml ست کنید

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

 

سلام استاد شاهپیری عزیز

بینهایت متشکرم بابت توضیحاتتون ...

اما ریسایکلر افقی داخل ریسایکلر عمودی نیست.

مجزا هستن و اول ریسایکلر افقی و بعد ریسایکلر عمودی هست.

یعنی به نظر شما طبق راهنمایی هاتون ریسایکلر افقی داخل عمودی قرار بگیره بهتره ؟

لینک ارسال
به اشتراک گذاری در سایت های دیگر

بله. ریسایکلر افقی باید به عنوان یه آیتم برای ریسایکلر اصلی در نظر گرفته بشه.تو آداپتر ریسایکلر اصلی دونوع type مشخص کنید. مثلا SLIDER و ITEM اولین آیتم که اسلایدره پس ویوش یه ریسایکلر افقی که تو پست قبلی ایجاد کردیم هست. همین طور متد onCreate و onBind همه طبق مثال بالا براش پر میشه. برای آیتم دومی هم که دیگه لایه مورد نظر و هولدر مورد نظرتون رو پاس بدید

لینک ارسال
به اشتراک گذاری در سایت های دیگر

در ۱۴۰۰/۹/۹ در ۱۵:۱۰، محمدرضا شاهپیری گفته است:

بله. ریسایکلر افقی باید به عنوان یه آیتم برای ریسایکلر اصلی در نظر گرفته بشه.تو آداپتر ریسایکلر اصلی دونوع type مشخص کنید. مثلا SLIDER و ITEM اولین آیتم که اسلایدره پس ویوش یه ریسایکلر افقی که تو پست قبلی ایجاد کردیم هست. همین طور متد onCreate و onBind همه طبق مثال بالا براش پر میشه. برای آیتم دومی هم که دیگه لایه مورد نظر و هولدر مورد نظرتون رو پاس بدید

سلام استاد

بسیار ممنونم بابت راهنماییتون.

چشم ، الان مواردی که فرمودین رو اجرا میکنم. فقط با این روند مشکل خالی ماندن ریسایکلر پایینی زمانی که آرایه خالی میشه (مثلا با هیتلر یا سرچ) هم برطرف میشه ؟

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

بایگانی شده

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

  • کاربران آنلاین در این صفحه   0 کاربر

    • هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.
×
×
  • اضافه کردن...