将RecyclerView转换为ViewPager / PagerAdapter

时间:2019-06-19 19:17:35

标签: java android kotlin android-viewpager

背景-是Android的新功能,但布局灵活,可以理解Java,Kotlin和XML,非常漂亮。但是,这项任务似乎超出了我的头绪。

问题-我正在尝试将以下Java文件(RecyclerView)转换为Kotlin文件(ViewPager)-因为我已经连接了一个ViewPager,并且具有所需的滚动行为。我觉得对于一个经验丰富的开发人员来说,这是10分钟的工作。如果是这样,我想知道我是否可以要求社区提供一些帮助?至少要弄清楚从哪里开始。我似乎找不到有关如何将RecyclerView转换为PagerAdapter或ViewPager的指南。

基本上,我正在使用的现有ViewPager具有静态数据(5个项目),而这个项目可能有数十个项目,因此需要使用单独的数据源(CardItem的项目)来动态化。


RecyclerViewAdapter-当前(Java)

package com.APPNAME.fragments.cards;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import com.APPNAME.R;
import com.APPNAME.databinding.FragmentCardsRecentlyViewedBinding;
import com.APPNAME.model.cardItem.CardItem;



public class RecentlyViewedAdapter extends RecyclerView.Adapter<RecentlyViewedAdapter.RecentlyViewedViewHolder> {

    public OnCardClicked listener;
    private ArrayList<CardItem> items = new ArrayList<>();

    public void addItems(ArrayList<CardItem> list) {
        items = list;
        notifyDataSetChanged();
    }

    @Override
    public RecentlyViewedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        FragmentCardsRecentlyViewedBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.fragment_cards_recently_viewed, parent, false);
        return new RecentlyViewedViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(RecentlyViewedViewHolder holder, int position) {
        holder.binding.setViewModel(new RecentlyViewedViewModel(items.get(position)));
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    interface OnCardClicked {
        void onCardClicked(View view, CardItem cardItem);
    }

    class RecentlyViewedViewHolder extends RecyclerView.ViewHolder {
        FragmentCardsRecentlyViewedBinding binding;

        public RecentlyViewedViewHolder(FragmentCardsRecentlyViewedBinding itemView) {
            super(itemView.getRoot());
            binding = itemView;
            binding.cardView.setOnClickListener(v -> {
                if (listener != null) {
                    listener.onCardClicked(v, items.get(getAdapterPosition()));
                }
            });
        }
    }
}

ViewPagerAdapter-Future(Kotlin)

package com.APPNAME.fragments.cards
import android.support.annotation.DrawableRes
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import java.util.*
import kotlinx.android.synthetic.main.fragment_cards_recently_viewed.view.*
import com.APPNAME.R
import com.APPNAME.activities.BaseActivity
import com.APPNAME.activities.cards.NewCardActivity
import com.APPNAME.model.cardItem.CardItem
import com.APPNAME.views.wrapContentViewPager.ObjectAtPositionPagerAdapter


class RecentlyViewedItemAdapter constructor(private val activity: BaseActivity) : ObjectAtPositionPagerAdapter() {

    private var items = ArrayList<CardItem>()

    override fun instantiateItemObject(container: ViewGroup, position: Int) : Any {
    return getImageView(container, R.drawable.placeholder_card_image) { NewCardActivity.start(activity, it) }
    }

    private fun getImageView(container: ViewGroup, @DrawableRes imageResourceId: Int, onClick: (imageResourceId: Int) -> Unit = {}): View {
    val layoutInflater = LayoutInflater.from(container.context)
        val layout = layoutInflater.inflate(R.layout.fragment_cards_recently_viewed, container, false)
        val image = layout.recentlyViewedImage
        image.setImageResource(imageResourceId)
        image.setOnClickListener { onClick(imageResourceId) }
        container.addView(layout)
        return layout
    }

    override fun isViewFromObject(view: View, anObject: Any) = (view == anObject)
    override fun getCount() = 5     //Placeholder

    override fun destroyItemObject(container: ViewGroup, position: Int, view: Any) {
        container.removeView(view as View)
    }
}

2 个答案:

答案 0 :(得分:0)

如果您有相对较多的项目并且需要回收视图,那么RecyclerView是您的正确选择。这绝对比创建具有固定项目数和视图持有者模式的自定义视图寻呼机适配器要容易。 默认的/通用的PageAdapter不回收任何东西-添加它是为了确保您已启动所有视图并准备进行浏览。但是,您可以使用https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html来销毁/重新创建不再使用或重用的片段。

答案 1 :(得分:0)

工作完成。实际上,我能够修改回收器视图以精确地模仿PageView的行为(包括填充,快照滚动等),使我感到惊讶。感谢简单的子类 SnapHelper 。为我节省了大量的工作,因此无需重构代码库。

SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);