我使用castorflex/VerticalViewPager庫包含帶有ListView裏面的片段。問題是,當我開始滑過ListView元素時,我無法更改ViewPager的頁面。當ListView到達ViewPager的頂部/底部列表時,是否有任何方法可以傳遞觸摸事件?我wan't達到流暢的效果(當列表不能再被滾動,ViewPager開始滾動,都在同一個觸摸事件)滾動縱向ViewPager與ListView裏面
回答
這是我爲實現here
取而代之的是RecyclerView的垂直尋呼機級解決方案實施擴展它,我們的定製內部RecyclerView類重寫自定義類 public boolean onTouchEvent(MotionEvent event)
在這裏我們可以通過MotionEvent event
到一個類像如下,以確定是否要攔截事件:
/**
* Tests the MotionEvent for valid behavior to care about overriding the touch event with
*/
private boolean shouldDisableScrollableParent(final MotionEvent event) {
boolean intercept = false;
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
// Here you can try to detect the swipe. It will be necessary to
// store more than the previous value to check that the user move constantly in the same direction
intercept = detectSwipe(dx, dy);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
default:
break;
}
mPreviousX = x;
mPreviousY = y;
return intercept;
}
/**
* Tests if we want to disable the parent touch interception
*/
private boolean detectSwipe(final float dx, final float dy) {
// True if we're scrolling in Y direction
if (Math.abs(dx) < Math.abs(dy)) {
FoundationLog.d(TAG, "Direction Y is yielding: " + dy);
if (dy < 0) {
// Touch from lower to higher
return true;
}
// Top view isn't shown, can always scroll up
final View view = getChildAt(0);
if (view == null) {
return true;
}
// Top view baseline doesn't equal to top of the RecyclerView
if (view.getTop() < 0) {
return true;
}
}
return false;
}
然後在自定義RecyclerView類的public boolean onTouchEvent(MotionEvent event)
方法,檢查是否getParent()
(也可能是反覆這麼根父)解析爲類,你想從覆蓋觸摸的視圖的ViewParent
。如果是的話,設置requestDisallowInterceptTouchEvent()
到true
上ViewParent
這是一個有點晚答覆,但我最近要求我們的應用程序ViewPager改爲垂直和我在我的名單有完全相同的問題。我希望這可以幫助可能有同樣問題的其他人。
首先,我的片段是ListFragment的擴展,但它對於包含列表的任何片段(顯然具有較小的修改)的作用方式相同。首先,我在列表中設置了一個OnScrollListener,並在onScrollStateChanged中設置了一個方法updateListVisibility,如果列表的頂部或底部的頂部在列表中可見(updateListPositionVisibility),則返回Activity的更新。
public class MyListFragment extends ListFragment {
.....
private OnScrollStateChangedListener mListener;
.....
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
......
getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
updateListVisibility();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
}
public void updateListVisibility() {
if (getListView() != null && getListView().getChildCount() > 0) {
boolean firstItemVisible = getListView().getFirstVisiblePosition() == 0;
boolean topOfFirstItemVisible = getListView().getChildAt(0).getTop() == 0;
boolean lastItemVisible = getListView().getLastVisiblePosition() == getListView().getAdapter().getCount() - 1;
boolean bottomOfLastItemVisible = getListView().getChildAt(getListView().getChildCount() - 1).getBottom() <= getListView().getHeight();
mListener.updateListPositionVisibility(firstItemVisible && topOfFirstItemVisible, lastItemVisible && bottomOfLastItemVisible);
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnScrollStateChangedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnScrollStateChangedListener");
}
}
/**
* Container Activity must implement this interface....
*/
public interface OnScrollStateChangedListener {
public void updateListPositionVisibility(boolean topIsVisible, boolean bottomIsVisible);
}
.....
}
在我的活動我把我的ViewPager的OnPageChangeListener和使用onPageSelected我用我的轉接器來獲得片段,這樣我可以稱之爲updateListVisibility就可以了,然後叫回我的活動。我的回調實現使用列表頂部和底部的可見性狀態更新了ViewPager(請參閱setListViewPositionsInViewPager)。
public class VerticallyPagedActivity extends BaseFragmentActivity implements
MyListFragment.OnScrollStateChangedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
......
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Object fragment = mAdapter.mItems.get(position);
if (fragment instanceof MyListFragment) {
((MyListFragment) fragment).updateListVisibility();
} else {
setListViewPositionsInViewPager(false, false);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void setListViewPositionsInViewPager(boolean handleEventTop, boolean handleEventBottom) {
mPager.setListVisibility(handleEventTop, handleEventBottom);
}
// Callback.
@Override
public void updateListPositionVisibility(boolean topIsVisible, boolean bottomIsVisible) {
setListViewPositionsInViewPager(topIsVisible, bottomIsVisible);
}
我的適配器只是在mItems中維護片段的一個實例。
public class MyAdapter extends FragmentStatePagerAdapter {
.....
public Map<Integer, Fragment> mItems;
public MyAdapter(FragmentManager fm, List<Content> content) {
super(fm);
mItems = new HashMap<>();
.....
@Override
public Fragment getItem(int position) {
.....
MyListFragment fragment = new MyListFragment();
.....
mItems.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
mItems.remove(position);
super.destroyItem(container, position, object);
}
}
然後在我的Castorflex垂直視圖分頁器中,我使用名爲setListVisibility的方法設置列表可見性值。每次滾動列表或ViewPager被分頁時,這些都會更新,這意味着它們始終處於最新狀態。最重要的部分是,當頁面頂部可見並且用戶試圖向上或底部可見並且用戶試圖下去時,尋呼機攔截事件。使用MotionEvent.ACTION_MOVE下的switch語句內計算的dy值很容易實現這一點。
public class VerticalPager extends ViewGroup {
.....
private boolean topOfListIsVisible;
private boolean bottomOfListIsVisible;
public void setListVisibility(boolean pTop, boolean pBottom) {
topOfListIsVisible = pTop;
bottomOfListIsVisible = pBottom;
}
.....
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
......
switch (action) {
case MotionEvent.ACTION_MOVE: {
......
final float y = MotionEventCompat.getY(ev, pointerIndex);
final float dy = y - mLastMotionY;
final float yDiff = Math.abs(dy);
......
// Pager needs to handle the event.
if (topOfListIsVisible && bottomOfListIsVisible || bottomOfListIsVisible && dy < 0 || topOfListIsVisible && dy > 0) {
return true;
}
}
.....
}
.....
}
- 1. ViewPager裏面ListView
- 2. 滾動視圖裏面viewpager不滾動
- 3. RecyclerView裏面的另一個RecyclerView裏面的ViewPager不滾動
- 4. NestedScrollView裏面的ViewPager裏面NestedScrollView:最內層的NestedScrollView不滾動
- 5. 縱向'帶頁面的Gridview'或'Viewpager'
- 6. Viewpager裏面Recyclerview作爲項目使用Viewpager阻止Recyclerview滾動
- 7. 滾動型與Viewpager
- 8. GridView裏面的ListView不滾動?
- 9. 無盡的ListView裏面滾動型
- 10. Android - ListView不會滾動DialogFragment裏面
- 11. ListView裏面的ScrollView滾動改進
- 12. scrollviewer裏面的listview防止scrollviewer滾動
- 13. ListView裏面的ViewFlipper - 滾動問題
- 14. ListView with Viewpager作爲TabPage裏面的TabPageIndicator
- 15. 在ViewPager中動態滾動android(像listView)
- 16. Android ViewPager裏面ViewPager
- 17. ViewPager NrollPointerException當向後滾動
- 18. 向上滾動時向上滾動listview
- 19. Viewpager與自動滾動android
- 20. ViewPager內部的ListView - 不滾動
- 21. ListView裏面的ViewPager與SlidingTabLayout - 高度問題
- 22. MapView裏面viewpager
- 23. 裏面ViewPager
- 24. viewpager與tabLayout滾動問題
- 25. 縱向佈局不會橫向滾動
- 26. UIScrollview縱向和橫向滾動ios
- 27. 的ListView裏面ViewPager - 在ListView的項目保持空白
- 28. Recyclerview裏面的ViewPager滾動視圖不工作
- 29. 避免在裏面ViewPager底視圖滾動內CoordinatorLayout
- 30. ScrollView裏面viewpager滾動垂直不工作