简体   繁体   English

在 recyclerview 的 onBindViewHolder 中显示进度条

[英]show progressbar in recyclerview's onBindViewHolder

I want to show progressBar from activity (in SubitemAdapter.kt) when elements in recyclerView are being loaded (about 150 to populate) but now this progressBar not shows at all.我想在加载 recyclerView 中的元素时(在 SubitemAdapter.kt 中)显示progressBar(在 SubitemAdapter.kt 中),但现在这个 progressBar 根本不显示。 Here is my code:这是我的代码:

CurrencyListFragment.kt CurrencyListFragment.kt

class CurrencyListFragment : Fragment(), MainContract.View {

    companion object {
        private val TAG = CurrencyListFragment::class.qualifiedName
    }


    private val restModel: RestModel = RestModel()
    private val handler: Handler = Handler(Looper.getMainLooper())
    private lateinit var mainPresenter: MainPresenter
    private lateinit var itemAdapter: ItemAdapter
    private lateinit var _layoutManager: LinearLayoutManager
    private lateinit var onChangeFragment: OnChangeFragment
    private lateinit var currentDate: String
    private var isLoading: Boolean = false
    private var apiResponseList: MutableList<ApiResponse> = arrayListOf()
    private var listSize: Int = 0

    override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            if (activity is OnChangeFragment) onChangeFragment = activity as OnChangeFragment
        } catch (error: ClassCastException) {
            error.message?.let { Log.e(TAG, it) }
        }
    }

    // @formatter:off
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.currency_list_fragment, container, false)
    }
    // @formatter:on

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        _layoutManager = LinearLayoutManager(activity)
        mainPresenter = MainPresenter(this, restModel, SharedPreferencesModel(activity as Activity))
        currentDate = mainPresenter.convertCurrentDate()
        if (mainPresenter.checkIfSuchDateExistsinSp(currentDate)) {
            Log.i(TAG, "Date $currentDate already exists in SharedPreferences")
            mainPresenter.processDateWithoutMakingACall(currentDate)
        } else {
            mainPresenter.makeACall(currentDate)
            Log.i(TAG, "Date $currentDate does not exist in SharedPreferences. Retrofit call made")
        }
        mainPresenter.saveNumberOfMinusDaysIntoSp(0)
        addScrollerListener()
    }

    override fun showProgressBarOnLoadingCurrencies() {
        progress_bar.visibility = View.VISIBLE
    }

    override fun hideProgressBarOnFinishedLoadingCurrencies() {
        progress_bar.visibility = View.GONE
    }

    override fun setRecyclerViewStateToLoading() {
        if (apiResponseList.size > 0) {
            apiResponseList.add(ApiResponse("", "", listOf(Currency("", 0f)), true))
            itemAdapter.notifyItemInserted(apiResponseList.size - 1)
        }
    }

    override fun removeRecyclerViewStetOfLoading() {
        if (apiResponseList.size > 1) {
            apiResponseList.removeAt(apiResponseList.size - 1)
            listSize = apiResponseList.size
            itemAdapter.notifyItemRemoved(listSize)
        }
        isLoading = false
    }

    override fun getApiResponseList(): List<ApiResponse> {
        return apiResponseList
    }

    override fun showLogAboutExistingDateInSp(date: String) {
        Log.i(TAG, "Date $date already exists in SharedPreferences (new element)")
    }

    override fun showLogAboutNotExistingDateInSp(date: String) {
        Log.i(TAG, "Date $date does not exist in SharedPreferences. Retrofit call made (new element)")
    }

    override fun assignResponseToRecyclerview(apiResponse: ApiResponse?) {
        rv_item.apply {
            layoutManager = _layoutManager
            apiResponseList.add(apiResponse!!)
            itemAdapter = activity?.let { ItemAdapter(apiResponseList, it) }!!
            adapter = itemAdapter
        }
    }

    private fun addScrollerListener() {
        rv_item.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(rvItem: RecyclerView, newState: Int) {
                super.onScrollStateChanged(rvItem, newState)
                mainPresenter.processRvitemOnScroll(isLoading, rvItem, newState)
            }
        })
    }

    private fun loadMore() {
        setRecyclerViewStateToLoading()
        var numberOfDays = mainPresenter.getNumberOfMinusDays()
        numberOfDays++
        mainPresenter.saveNumberOfMinusDaysIntoSp(numberOfDays)
        val dateMinusXDays = mainPresenter.currentDateMinusXDaysToStr(numberOfDays)

        val nextLimit = listSize + 1
        for (i in listSize until nextLimit) {

            if (mainPresenter.checkIfSuchDateExistsinSp(dateMinusXDays)) {
                Log.i(TAG, "Date $dateMinusXDays already exists in SharedPreferences (new element)")
                handler.postDelayed({
                    mainPresenter.processDateWithoutMakingACall(dateMinusXDays)
                }, 2000)
            } else {
                Log.i(TAG, "Date $dateMinusXDays does not exist in SharedPreferences. Retrofit call made (new element)")
                mainPresenter.makeACall(dateMinusXDays)
            }
        }
        itemAdapter.notifyDataSetChanged()
    }

    override fun notifyChangedItemAdapter() {
        itemAdapter.notifyDataSetChanged()
    }


    override fun onDestroy() {
        super.onDestroy()
        restModel.cancelJob()
    }
}

ItemAdapter.kt项目适配器.kt

class ItemAdapter(private var items: MutableList<ApiResponse>, private val activity: Activity) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        private const val VIEW_TYPE_DATA = 0
        private const val VIEW_TYPE_PROGRESS = 1
    }

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): RecyclerView.ViewHolder {
        return when (p1) {
            VIEW_TYPE_DATA -> {
                val view = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)
                DataViewHolder(view, activity)
            }
            VIEW_TYPE_PROGRESS -> {
                val view = LayoutInflater.from(parent.context).inflate(R.layout.progress_bar_layout, parent, false)
                ProgressViewHolder(view)
            }
            else -> throw IllegalArgumentException("Different View type")
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is DataViewHolder)
            holder.bind(items[position])
    }

    override fun getItemCount() = items.size

    override fun getItemViewType(position: Int): Int {
        val viewtype = items[position]
        return when (viewtype.isLoading) {//if data is load, returns PROGRESSBAR viewtype.
            true -> VIEW_TYPE_PROGRESS
            false -> VIEW_TYPE_DATA
        }
    }

    class DataViewHolder(view: View, activity: Activity) : RecyclerView.ViewHolder(view) {
        private var isRvSubitemVisible = false
        private val tvDate = view.tv_date
        private val rvSubitem = view.rv_subitem
        private val activity = activity

        fun bind(apiResponse: ApiResponse) {
            tvDate.text = String.format(itemView.context.getString(R.string.day_x), apiResponse.date)
            tvDate.setOnClickListener {
                if (isRvSubitemVisible) {
                    rvSubitem.visibility = View.GONE
                    isRvSubitemVisible = false
                } else {
                    rvSubitem.visibility = View.VISIBLE
                    isRvSubitemVisible = true
                }
            }
            rvSubitem.apply {
                layoutManager = LinearLayoutManager(itemView.context)
                adapter = SubitemAdapter(apiResponse.rates, apiResponse.date, activity)
            }
        }
    }

    inner class ProgressViewHolder(view: View) : RecyclerView.ViewHolder(view)
}

SubitemAdapter.kt子项适配器.kt

class SubitemAdapter(private val subitems: List<Currency>, private val day: String, private val activity: Activity) : RecyclerView.Adapter<SubitemAdapter.SubitemViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, p1: Int): SubitemViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.subitem, parent, false)
        return SubitemViewHolder(view, day, activity)
    }

    override fun onBindViewHolder(holder: SubitemViewHolder, position: Int) {
        if(position < subitems.size - 1) {
            activity.progress_bar.visibility = View.VISIBLE
        }
        else
            activity.progress_bar.visibility = View.GONE
        holder.bind(subitems[position], position)
    }

    override fun getItemCount() = subitems.size

    class SubitemViewHolder(view: View, day: String, activity: Activity) : RecyclerView.ViewHolder(view) {
        private val subitemRootView = view.subitem_root
        private val tvCurrencyName = view.tv_currency_name
        private val tvCurrencyValue = view.tv_currency_value
        private val day = day
        private val activity = activity
        fun bind(currency: Currency, position: Int) {
            subitemRootView.setOnClickListener { v ->
                activity as OnChangeFragment
                activity.changeFragment(SpecificCurrencyFragment(), ChangeFragmentData(hashMapOf(currency.currencyName to currency.currencyValue.toString()), day))
            }
            tvCurrencyName.text = currency.currencyName
            tvCurrencyValue.text = currency.currencyValue.toString()
        }
    }
}

Here is I think everything to help me.这里是我认为对我有帮助的一切。 But if you need something else more just aks.但是,如果您需要更多其他东西,则只是aks。 Any help will bve really appreciated.任何帮助将不胜感激。 Thank you in advance!先感谢您!

You are already passing a List<Currency> which are the items to be loaded inside your recyclerview.您已经在传递一个List<Currency> ,它们是要在您的回收视图中加载的项目。 You should not be checking this inside onBindViewHolder since you already have those items when you passed them as an argument to the recyclerview adapter您不应该在onBindViewHolder检查这个,因为当您将它们作为argument传递给recyclerview adapter时,您已经拥有这些项目

Instead, when you are passing the List<Currency> to your adapter, you must update the progressbar at that time from activity itself.相反,当您将List<Currency>传递给您的适配器时,您必须在那时从活动本身更新进度条。 You can edit your question and add code for your Activity if this didn't help you, I'll try to answer you :)如果这对您没有帮助,您可以编辑您的问题并为您的Activity添加代码,我会尽力回答您:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM