android / views-widgets-samples

Multiple samples showing the best practices in views-widgets on Android.
Apache License 2.0
5.04k stars 3.01k forks source link

use BaseRecyclerViewAdapterHelper in ViewPager2 #105

Open WaterElva opened 4 years ago

WaterElva commented 4 years ago

java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent) at androidx.viewpager2.widget.ViewPager2$4.onChildViewAttachedToWindow(ViewPager2.java:270) at androidx.recyclerview.widget.RecyclerView.dispatchChildAttached(RecyclerView.java:7561) at androidx.recyclerview.widget.RecyclerView$5.addView(RecyclerView.java:860) at androidx.recyclerview.widget.ChildHelper.addView(ChildHelper.java:107) at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:8601) at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8559) at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1643) at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587) at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:640) at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134) at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851) at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404) at android.view.View.layout(View.java:17637) at android.view.ViewGroup.layout(ViewGroup.java:5575) at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:527) at android.view.View.layout(View.java:17637) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079) at android.view.View.layout(View.java:17637) at android.view.ViewGroup.layout(ViewGroup.java:5575) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585) at android.widget.LinearLayout.onLayout(LinearLayout.java:1494) at android.view.View.layout(View.java:17637) at android.view.ViewGroup.layout(ViewGroup.java:5575)

WaterElva commented 4 years ago

"androidx.viewpager2:viewpager2:1.0.0"

WaterElva commented 4 years ago

public class LoopWrapperAdapter extends RecyclerView.Adapter {

private RecyclerView.Adapter adapter;
private boolean isLoop;

public LoopWrapperAdapter(RecyclerView.Adapter adapter) {
    this.adapter = adapter;

}

@NonNull
@Override
public final RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return adapter.onCreateViewHolder(parent, viewType);
}

@Override
public final void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    adapter.onBindViewHolder(holder, getRealPosition(position));
}

@Override
public final void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List payloads) {
    adapter.onBindViewHolder(holder, position, payloads);
}

@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    adapter.onAttachedToRecyclerView(recyclerView);
    adapter.registerAdapterDataObserver(mObserver);
}

@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
    adapter.onDetachedFromRecyclerView(recyclerView);
    adapter.unregisterAdapterDataObserver(mObserver);
}

public int getRealPosition(int position) {
    if (getItemCount() > 0) {
        return position % getRealItemCount();
    }
    return position;
}

@Override
public final int getItemCount() {
    int realItemCount = getRealItemCount();
    if (isLoop) {
        return realItemCount > 1 ? Integer.MAX_VALUE : realItemCount;
    } else {
        return realItemCount;
    }
}

@Override
public int getItemViewType(int position) {
    return adapter.getItemViewType(position);
}

@Override
public long getItemId(int position) {
    return adapter.getItemId(position);
}

public int getRealItemCount() {
    return adapter.getItemCount();
}

public void setIsLoop(boolean isLoop) {
    this.isLoop = isLoop;
}

RecyclerView.AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() {

    @Override
    public void onChanged() {
        notifyDataSetChanged();
    }

    @Override
    public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
        notifyItemRangeChanged(positionStart, itemCount, payload);
    }

    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        notifyItemRangeInserted(positionStart, itemCount);
    }

    @Override
    public void onItemRangeRemoved(int positionStart, int itemCount) {
        notifyItemRangeRemoved(positionStart, itemCount);
    }

    @Override
    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {

    }
};

}

therajanmaurya commented 3 years ago

Here is the fix: https://stackoverflow.com/a/59727239/3176277