自定义垂直ViewPager搭配PageTransformer,点击UI更新延迟问题求助
Hey there! Let's figure out why your VerticalViewPager's UI isn't updating right after clicking a control, even though the onClick event is firing. Looking through your code, I've spotted a few potential issues and fixes that should get things working as expected:
1. Touch Event Handling Might Be Blocking UI Refresh
Your custom VerticalViewPager uses a GestureDetector to handle touch events, and in onTouchEvent, you're returning true immediately for ACTION_UP/ACTION_CANCEL events. This could be preventing the system from properly finishing the touch event lifecycle, which might block UI updates after a click.
Fix: Adjust the Touch Event Return Logic
Update your onTouchEvent method to return the gesture detector's result instead of hardcoding true for those action types:
@Override public boolean onTouchEvent(MotionEvent ev) { boolean res = gestureDetector.onTouchEvent(ev); int action = ev.getAction(); if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { if (isScrollEvent) { try { endFakeDrag(); } catch (Exception e) {} } // Return the gesture detector's result instead of forcing true return res; } Log.d("event", "ontouch "+res); return res; }
Also, keep your GestureListener's onSingleTapUp returning false — this ensures the click event gets passed all the way down to your child controls, which you already confirmed is happening, but it's good to double-check.
2. You're Not Updating the UI Immediately After Clicking
From your adapter code snippet, it looks like you're modifying data (like your bookmark list in SharedPreferences) when a control is clicked, but you're not updating the actual UI element right away. Instead, you're waiting for the ViewPager to recreate the page when you switch tabs, which is why the update only happens then.
Fix: Update the UI Right in the Click Listener
Let's say your bookmark icon changes state when clicked — update its appearance immediately in the onClick handler, before saving to SharedPreferences:
// Finish that bookmark click listener you started in your adapter bookmark.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String newsId = nhBean.getId(); // Assume your NHBean has a unique ID if (list.contains(newsId)) { // Remove from bookmarks list.remove(newsId); bookmark.setImageResource(R.drawable.ic_bookmark_outline); // Update icon right away } else { // Add to bookmarks list.add(newsId); bookmark.setImageResource(R.drawable.ic_bookmark_filled); // Update icon right away } // Save the updated list to SharedPreferences SharedPreferences.Editor editor = preferences.edit(); editor.putString("BOOKMARKS", TextUtils.join(",", list)); editor.apply(); // No need for notifyDataSetChanged here unless other pages need updating } });
If you do need other pages to reflect the change, call notifyDataSetChanged() — but always update the current page's UI first for instant feedback.
3. ViewPager's Cache Might Be Preventing Refreshes
ViewPager caches nearby pages by default (usually 1 on each side). If you call notifyDataSetChanged(), the current page might not be recreated immediately, so the UI stays stale. To fix this, you can manually refresh the current page's view.
Fix: Add a Method to Update the Current Page in Your Adapter
Add this method to your MainViewPagerAdapter to refresh a specific page's UI:
public void refreshPage(ViewPager viewPager, int position) { // Get the view for the current page View currentPage = viewPager.getChildAt(position - viewPager.getFirstVisibleItem()); if (currentPage != null) { NHBean nhBean = newslist.get(position); ImageView bookmark = currentPage.findViewById(R.id.bookmark); String newsId = nhBean.getId(); // Update the bookmark icon based on current state bookmark.setImageResource(list.contains(newsId) ? R.drawable.ic_bookmark_filled : R.drawable.ic_bookmark_outline); // Update any other controls on the page here too } }
Then call it after modifying your data:
// After updating the bookmark list mainViewPagerAdapter.refreshPage(verticalViewPager, verticalViewPager.getCurrentItem());
4. Check Your VerticalPageTransformer
It's worth testing if your VerticalPageTransformer is causing any unexpected UI refresh issues. Temporarily comment out the setPageTransformer call in your VerticalViewPager's init() method and see if the UI updates correctly. If it does, you might need to adjust the transformer's logic to ensure view changes don't block refreshes.
内容的提问来源于stack exchange,提问作者Jyoti JK

