簡體   English   中英

將 RecyclerView 轉換為 ViewPager/PagerAdapter

[英]Converting RecyclerView to ViewPager / PagerAdapter

背景- Android 的新手,但移動布局非常漂亮,了解 Java、Kotlin 和 XML。然而,這項任務似乎超出了我的理解范圍。

問題- 我希望將以下 Java 文件 (RecyclerView) 轉換為 Kotlin 文件 (ViewPager) - 因為我已經連接了一個 ViewPager,其滾動行為與所需的相同。 我的印象是,對於經驗豐富的開發人員來說,這是一項 10 分鍾的工作。 如果是這樣的話,我想知道我是否可以尋求社區的幫助? 至少要弄清楚從哪里開始。 我似乎找不到有關如何將 RecyclerView 轉換為 PagerAdapter 或 ViewPager 的指南。

本質上,我正在使用的現有 ViewPager 有 static 個數據(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 - 未來 (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)
    }
}

如果您有相對大量的物品並且需要回收視圖,那么RecyclerView是您的正確選擇。 它肯定比使用固定項目計數和視圖持有者模式創建自定義視圖尋呼機適配器更容易。 默認/通用PageAdapter不會回收任何內容 - 它會被添加以確保您已啟動所有視圖並准備輕掃。 但是,您可以使用https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html ,它將在不再使用或重用時銷毀/重新創建片段。

任務完成。 我真的很驚訝自己能夠修改回收器視圖以精確地模仿PageView的行為(包括填充,快照滾動等)。 感謝簡單的子類SnapHelper 為我節省了大量工作,因此無需重構代碼庫。

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

PagerSnapHelper 解決了我的問題。

   binding.recyclerViewHomeAnnouncement.apply {
        layoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
        binding.recyclerViewHomeAnnouncement.layoutManager = layoutManager
        setHasFixedSize(true)
        itemAnimator = DefaultItemAnimator()
        adapter = homeAnnouncementAdapter
    }
    
    val snapHelper: SnapHelper = PagerSnapHelper()
    snapHelper.attachToRecyclerView(binding.recyclerViewHomeAnnouncement)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM