当我的列表到达底部的recyclerview时,如何显示进度条?

时间:2019-06-04 13:28:22

标签: android

我创建了错误的页面库之类的stmth,当我到达列表的底部时,我想在下载数据之前显示进度栏。我认为notifyItemInserted()将对我有所帮助,因为我不知道该在哪里插入此项目。我认为我还必须使用notifyItemChanged隐藏所有数据字段并在列表项中显示进度栏。因此,当我到达列表末尾时,这是我自己加载的其他数据:

 jobLst.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                if (dy > 0) {
                    val visibleItemCount = mLayoutManager.childCount
                    val totalItemCount = mLayoutManager.itemCount
                    val pastVisibleItems = mLayoutManager.findFirstVisibleItemPosition()
                    if (loading) {
                        if (visibleItemCount + pastVisibleItems >= totalItemCount && !recyclerView.canScrollVertically(1)) {
                 // here I would like to show loader

getJobList(Integer.parseInt(Uri.parse(nextUrl).getQueryParameter("offset")), type, sp.getString("access_token", ""), filterData, true) 
                        }
                    }
                }
            }
        })

我认为我将不得不更改项目布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="15dp"
    android:layout_marginTop="4dp"
    android:layout_marginEnd="15dp"
    android:background="@drawable/message_list_item_bg"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="5dp"
        android:layout_marginEnd="10dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_job_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3.5"
            android:ellipsize="end"
            android:fontFamily="@font/opensans_semibold"
            android:singleLine="true"
            android:textColor="#333333"
            app:autoSizeMaxTextSize="20sp"
            app:autoSizeMinTextSize="8sp"
            app:autoSizeStepGranularity="2sp"
            app:autoSizeTextType="uniform" />

        <TextView
            android:id="@+id/tv_date"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="0.5"
            android:fontFamily="@font/opensans_semibold"
            android:gravity="end"
            android:textSize="12sp" />

    </LinearLayout>

    <TextView
        android:id="@+id/tv_address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="5dp"
        android:layout_marginEnd="10dp"
        android:ellipsize="end"
        android:fontFamily="@font/opensans_regular"
        android:gravity="center_vertical"
        android:singleLine="true"
        android:textColor="#999999"
        app:autoSizeMaxTextSize="20sp"
        app:autoSizeMinTextSize="8sp"
        app:autoSizeStepGranularity="2sp"
        app:autoSizeTextType="uniform" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="5dp"
        android:layout_marginEnd="10dp"
        android:orientation="horizontal"
        tools:ignore="UseCompoundDrawables">

        <TextView
            android:id="@+id/tv_company"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="30dp"
            android:layout_weight="3.5"
            android:ellipsize="end"
            android:fontFamily="@font/opensans_regular"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:textColor="#666666"
            app:autoSizeMaxTextSize="20sp"
            app:autoSizeMinTextSize="8sp"
            app:autoSizeStepGranularity="2sp"
            app:autoSizeTextType="uniform" />


        <ImageView
            android:id="@+id/add_to_notepad"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/add_to_notepad"
            android:gravity="end" />


        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:gravity="end"
            android:visibility="gone" />
    </LinearLayout>


</LinearLayout>

当前进度条已被使用,不能用于此目的。因此,在加载一些新数据之前和之后,我将需要添加然后删除具有另一种视图类型的一项。我的主要布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context=".jobAGENT.JobsList">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="75dp"
        android:gravity="center_horizontal"
        android:text="@string/no_jobs"
        android:textSize="32sp"
        android:textStyle="italic"
        android:visibility="gone" />

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/refresh_t"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="5dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="5dp"
        android:background="@color/white">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/job_list_t"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="10dp" />


    </android.support.v4.widget.SwipeRefreshLayout>


</FrameLayout>

那么,您能给我什么建议?

4 个答案:

答案 0 :(得分:1)

Use the below code snippet

<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rcylv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="@dimen/dimen_5dp"/>


    <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:scaleX="3"
            android:scaleY="3"
            android:visibility="gone"/>

 And inside activity

 jobLst.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            if (dy > 0) {
                val visibleItemCount = mLayoutManager.childCount
                val totalItemCount = mLayoutManager.itemCount
                val pastVisibleItems = mLayoutManager.findFirstVisibleItemPosition()
                if (loading) {
                    if (visibleItemCount + pastVisibleItems >= totalItemCount && !recyclerView.canScrollVertically(1)) {
             progressBar.visibility = View.VISIBLE -> Kotlin
                       or
             progressBar.setVisibility(View.VISIBLE); -> Java

                    }
                }
            }
        }
    })

答案 1 :(得分:1)

在您的适配器中添加它。.

        @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        if(i==list.size()){
            //show your progress bar
        }
}

答案 2 :(得分:1)

您可以为RecyclerView适配器添加特殊的加载ViewHolder类型,并将特殊项保留在最后一个。

正在加载的ViewHolder项目布局仅包含一个ProgressBar

此特殊项目分辨率的一个优点是,当显示或隐藏正在加载的项目时,您可以轻松使用RecyclerView动画。

|=== normal item ====|
|=== normal item ====|
|=== normal item ====|
|=== normal item ====|
|=== normal item ====|
--- insert data here ----
|=== loading item ===|

这是Adapter演示代码,我没有运行该演示,但足以显示该想法。

class ListAdapter(list: List<ItemModel>) : RecyclerView.Adapter<ListAdapter.BaseItemHolder>() {

    companion object {
        private const val VIEW_TYPE_LOADING = 1
        private const val VIEW_TYPE_NORMAL = 2
    }
    private var mList = list
    private var mShowLoading = false

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseItemHolder {
          when(viewType) {
              VIEW_TYPE_NORMAL -> return NormalViewHolder.create(parent)
              VIEW_TYPE_LOADING -> return LoadingViewHolder.create(parent)
          }
        return BaseItemHolder(parent)
    }

    override fun getItemCount(): Int {
         // return data list size + loading item size
        return mList.size + if (mShowLoading) { 1 } else { 0 }
    }

    override fun onBindViewHolder(holder: BaseItemHolder, position: Int) {
        if (holder is NormalViewHolder) {
            holder.bind(mList[position])
        } else if (holder is LoadingViewHolder) {
            //do nothing
            //LoadingViewHolder does not need bind data
        }
    }

    override fun getItemViewType(position: Int): Int {
        if (position < mList.size) {
            return VIEW_TYPE_NORMAL
        }
        return VIEW_TYPE_LOADING
    }

    fun hideLoading() {
        mShowLoading = false
        //be careful with the index
        notifyItemRemoved(itemCount)
    }

    fun showLoading() {
        mShowLoading = true
        //be careful with the index
        notifyItemInserted(itemCount - 1)
    }


    open class BaseItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    class LoadingViewHolder(itemView: View) : BaseItemHolder(itemView) {

        private var mText: TextView = itemView.findViewById(R.id.item_title)

        companion object {
            fun create(parent: ViewGroup): LoadingViewHolder {
                //R.layout.layout_loading_item just contain a progress bar or something like that
                return LoadingViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_loading_item, parent, false))
            }
        }

        // LoadingViewHolder does not need bind data
        //fun bind() {
        //  
        //}

    }

    class NormalViewHolder(itemView: View) : BaseItemHolder(itemView) {

        private var mText: TextView = itemView.findViewById(R.id.item_title)

        companion object {
            fun create(parent: ViewGroup): NormalViewHolder {
                return NormalViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_list_item, parent, false))
            }
        }

        fun bind(itemModel: ItemModel) {
            //bind your data with ItemModel data
        }

    }
} 

答案 3 :(得分:0)

似乎我已经设法通过最简单的方法解决了我的问题。在放置RecyclerView的主布局中,您必须添加进度栏,该进度条将位于RV下面,并且为此,您必须使用相对布局。然后,您可以像下面那样将scrollListener用于recyclerview:

recyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    if (!recyclerView.canScrollVertically(1)) {
                        loader.visibility = View.VISIBLE
                    }else{
                        loader.visibility = View.GONE
                    }
                }
            }


        })

,当您的响应成功时,您将隐藏进度栏。也许它将帮助我以外的其他人:)