RecyclerView滚动条目错乱求助:插广告后Holder数据及VIP背景异常
Hey, let's tackle this RecyclerView item错乱 issue you're facing—it's super common when dealing with multiple item types and view reuse, so let's break it down step by step.
1. Fix Item Type & Position Calculation (Root Cause of Wrong Data)
The core problem here is that you aren't adjusting for inserted ads when calculating which data to bind or identifying item types. Here's how to fix it:
First, update getItemCount() to include ad items in the total count:
@Override public int getItemCount() { // Calculate number of ads: 1 ad every 15 content items int adCount = carList.size() / LIST_AD_DELTA; return carList.size() + adCount; }
Next, correct getItemViewType() to accurately spot ad positions (ads should appear right after every 15th content item):
@Override public int getItemViewType(int position) { // Ads fall at every (15+1)th position (since we add 1 ad after 15 content items) if ((position + 1) % (LIST_AD_DELTA + 1) == 0) { return AD_TYPE; } else { return CONTENT_TYPE; } }
Then, in onBindViewHolder(), calculate the correct index for your Car data by subtracting ads that appear before the current position:
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position); if (viewType == AD_TYPE) { // Bind your ad content here AdViewHolder adHolder = (AdViewHolder) holder; // ... add ad loading/binding logic } else { // Count how many ads are before this position int adCountBefore = position / (LIST_AD_DELTA + 1); // Get the actual index in the original carList int dataIndex = position - adCountBefore; ContentViewHolder contentHolder = (ContentViewHolder) holder; Car car = carList.get(dataIndex); // Bind car data normally contentHolder.carName.setText(car.getName()); // ... other content binding steps // Fix VIP background color错乱 here if (car.isVip()) { contentHolder.itemView.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.vip_background)); } else { // Critical: Reset to default background to avoid reuse issues contentHolder.itemView.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.default_background)); } } }
2. Fix View Reuse State Leaks (VIP Background Issue)
The background color错乱 happens because RecyclerView reuses ViewHolders. If a VIP item's background is set, the next reused holder will keep that background unless you explicitly reset it.
Always reset view states for non-matching cases—this applies to text, images, visibility, and any other dynamic UI elements, not just backgrounds.
3. Verify ViewHolder Creation
Make sure onCreateViewHolder() inflates the correct layout for each item type:
@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(mCtx); if (viewType == AD_TYPE) { View adView = inflater.inflate(R.layout.item_ad, parent, false); return new AdViewHolder(adView); } else { View contentView = inflater.inflate(R.layout.item_car, parent, false); return new ContentViewHolder(contentView); } }
Quick Final Checks
- Confirm
LIST_AD_DELTAis correctly set to 15 (no typos!) - Reset all dynamic UI states (not just backgrounds) for non-VIP items
- Test aggressive scrolling up/down to confirm the错乱 is resolved
内容的提问来源于stack exchange,提问作者Kerim

