我们如何在 ViewPager2 中实现无限滚动
因为OnPageChangeListener()
在这个寻呼机中没有。但是每当我们更改页面时,都会有setPageTransformer()
监听器获取回调。
所以viewpager2问题的任何解决方案
注意:我正在为 viewpager2 使用 recyclerview 适配器
我们如何在 ViewPager2 中实现无限滚动
因为OnPageChangeListener()
在这个寻呼机中没有。但是每当我们更改页面时,都会有setPageTransformer()
监听器获取回调。
所以viewpager2问题的任何解决方案
注意:我正在为 viewpager2 使用 recyclerview 适配器
对于无限滚动,您不必自定义视图寻呼机。viewPager 适配器中的技巧。您可以在 getCount 覆盖方法中返回 Int.MAX 值。在 instanceiteItem 覆盖函数中,您可以使用item_position % item_size来获取实际的项目位置。代码示例如下。
class AdsSliderAdapter(
private val bannerImageList: MutableList<SliderImagesItem>,
private val callback: SliderItemClickListener) :PagerAdapter() {
private var mContext: Context? = null
override fun instantiateItem(container: ViewGroup, position: Int): Any {
mContext = container.context
val view = LayoutInflater.from(container.context)
.inflate(R.layout.item_ad_slider, container, false)
val adImage: AppCompatImageView = view.ivAd
mContext?.let {
GlideApp.with(it).load(bannerImageList[position % bannerImageList.size].imageUrl)
.into(adImage)
}
val viewPager = container as ViewPager
viewPager.addView(view, 0)
view.cardView.onClick { callback.onSliderImageClick(bannerImageList[position % bannerImageList.size]) }
return view
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun getCount(): Int {
return if (bannerImageList.size > 0) {
Int.MAX_VALUE
} else {
0
}
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
val viewPager = container as ViewPager
val view = `object` as View
viewPager.removeView(view)
}
interface SliderItemClickListener {
fun onSliderImageClick(item: SliderImagesItem)
}
}
第 1 步:创建 EndlessScrollAdapter 类
class EndlessScrollAdapter internal constructor(
fm: FragmentManager,
lifeCycle: Lifecycle
) : FragmentStateAdapter(fm, lifeCycle) {
private val items = mutableListOf<Model>()
val firstElementPosition = Int.MAX_VALUE / 2
fun updateList(list: List<Model>) {
items.apply {
clear()
addAll(list)
}
notifyDataSetChanged()
}
override fun getItemCount(): Int = if (items.isNotEmpty()) Int.MAX_VALUE else 0
override fun createFragment(position: Int): Fragment = ViewPagerFragment(
items[position.rem(items.size)])
}
步骤:2 从活动或片段调用
viewPager2.adapter = endlessScrollAdapter
endlessScrollAdapter.apply {
updateList(someModelList)
viewPager2.setCurrentItem(this.firstElementPosition, false)
}
从字面上看,这不是无止境的,但从用户的角度来看,它是,因为他永远不会到达边缘。的长度ViewPager2
是Int.MAX_VALUE
,起始位置是Int.MAX_VALUE/2
这样用户可以向前和向后滚动。
Since you mentioned you were using recyclerview adapter for viewpager2 have you tried writing it as you would while implementing infinite scroll in a recyclerview.
Basically you need to return Integer.MAX_VALUE
in your adapter's getItemCount()
method and whenever in onBindViewHolder
you need actual item position always use position % yourList.size()
. I've also added the size > 0
check in order to avoid crashes when list is empty and therefore this would otherwise throw a division by zero error.
Below is a sample adapter, you can use it as reference for your adapter and check if it works well for you. Hope this helps.
public class SampleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private List<Sample> mSampleList;
public SampleAdapter(List<Sample> mSampleList) {
this.mSampleList = mSampleList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View viewCommonItems = LayoutInflater.from(parent.getContext())
.inflate(R.layout.demo_view, parent, false);
ItemViewHolder commonHolders = new ItemViewHolder(viewCommonItems);
return commonHolders;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ItemViewHolder viewHolder = (ItemViewHolder) holder;
if(mSampleList.size()>0) {
Sample sample = mSampleList.get(position % mSampleList.size());
Glide.with(viewHolder.itemView.getContext()).load(sample.getImage())
.into(viewHolder.ivImage);
}
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.iv_img)
ImageView ivImage;
public ItemViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
您可以使用下面的代码
public class YourPagerAdapter extends FragmentStatePagerAdapter
{
public static int COUNT_OF_LOOP = 1000;
private ArrayList<Product> mProducts;
public YourPagerAdapter(FragmentManager manager, ArrayList<Product> products)
{
super(manager);
mProducts = products;
}
@Override
public Fragment getItem(int position)
{
if (mProducts != null && mProducts.size() > 0)
{
position = position % mProducts.size();
return MyFragment.newInstance(mProducts.get(position));
}
else
{
return MyFragment.newInstance(null);
}
}
@Override
public int getCount()
{
if (mProducts != null && mProducts.size() > 0)
{
return mProducts.size()*COUNT_OF_LOOP;
}
else
{
return 1;
}
}
}
mAdapter = new YourPagerAdapter(getSupportFragmentManager(), mProducts);
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mViewPager.getChildCount() * YourPagerAdapter. COUNT_OF_LOOP / 2, false);
试试下面的代码
@Override
public void onPageScrollStateChanged (int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
int curr = viewPager.getCurrentItem();
int lastReal = viewPager.getAdapter().getCount() - 2;
if (curr == 0) {
viewPager.setCurrentItem(lastReal, false);
} else if (curr > lastReal) {
viewPager.setCurrentItem(1, false);
}
}
}
我希望这可以帮助你!
谢谢你。