GridViewPager中的Android Wear WearableListView

时间:2014-07-17 13:02:41

标签: android android-fragments wear-os

我正在构建一个Android Wear应用程序,我希望将其作为几个可以横向滑动的页面呈现。

为此,我使用的是GridViewPager和相关联的FragmentGridPagerAdapter,它使用单行进行硬连线。这适用于在瓷砖之间水平滑动,但是在我的一个片段中,我想使用WearableListView来允许用户在多个动作之间进行选择。不幸的是,这不起作用,因为看起来GridViewPager阻止任何滑动到达WearableListView。有没有人知道是否有办法可以使用所描述的组件来完成?

我也尝试过使用标准的ViewPager,这样可以让WearableListView滚动得很好,但水平滑动会变得很脆弱,你经常需要滑动几次才能移动视图寻呼机。

3 个答案:

答案 0 :(得分:31)

修改
在下面发布我的原始答案后的一段时间,我找到了正确的方法来做到这一点。只需设置

    wearableListView.setGreedyTouchMode( true )

并且列表视图在GridViewPager中完美运行。

原始答案仍然是一个很好的视图,使滚动工作与垂直滚动GridViewPager嵌套在水平滚动内。

原始回答
通过像这样扩展GridViewPager,可以更简洁地实现与接受的答案大致相同的事情:

public class HorizontalListPager extends GridViewPager {

    private final GestureDetector mGestureDetector;

    public HorizontalListPager( Context context, AttributeSet attrs ) {
        super( context, attrs );
        mGestureDetector = new GestureDetector( context, new HScrollDetector() );
    }

    @Override
    public boolean onInterceptTouchEvent( MotionEvent ev ) {
        // If we have more horizontal than vertical scrolling, intercept the event,
        // otherwise let the child handle it
        return super.onInterceptTouchEvent( ev ) && mGestureDetector.onTouchEvent( ev );
    }

    class HScrollDetector extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll( MotionEvent e1, MotionEvent e2, float distanceX, float distanceY ) {
            // Returns true if scrolling horizontally
            return ( Math.abs( distanceX ) > Math.abs( distanceY ) );
        }
    }
}

答案 1 :(得分:10)

我遇到了同样的事情。只设置一行或覆盖canscrollvertically()不起作用。我发现的唯一选择是覆盖Neevek答案中的触摸事件: HorizontalScrollView within ScrollView Touch Handling

这对我有用:

private float xDistance, yDistance, lastX, lastY;

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            setDownPosition(ev);
            break;
        case MotionEvent.ACTION_MOVE:
            if (isVerticalScroll(ev))
                return false;
    }

    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            setDownPosition(ev);
            break;
        case MotionEvent.ACTION_MOVE:
            if (isVerticalScroll(ev))
                return false;
    }

    return super.onTouchEvent(ev);
}

private void setDownPosition(MotionEvent ev){
    xDistance = yDistance = 0f;
    lastX = ev.getX();
    lastY = ev.getY();
}

private boolean isVerticalScroll(MotionEvent ev){
    final float curX = ev.getX();
    final float curY = ev.getY();
    xDistance += Math.abs(curX - lastX);
    yDistance += Math.abs(curY - lastY);
    lastX = curX;
    lastY = curY;
    if(xDistance < yDistance) {
        return true;
    }
    return false;
}

答案 2 :(得分:1)

非常感谢Graydyn Young ..因为我花时间找到了如何实现他的解决方案的方式:

  • 创建一个类(FragmentViewPager),它使用前面的代码扩展GridViewPager。
  • 使用此类而不是GridViewPager

    import android.content.Context;
    import android.support.wearable.view.GridViewPager;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    
    
    public class FragmentViewPager extends GridViewPager {
    
    
        public FragmentViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public FragmentViewPager(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public FragmentViewPager(Context context) {
            super(context);
        }
        private float xDistance, yDistance, lastX, lastY;
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    setDownPosition(ev);
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (isVerticalScroll(ev))
                        return false;
            }
    
            return super.onInterceptTouchEvent(ev);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    setDownPosition(ev);
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (isVerticalScroll(ev))
                        return false;
            }
    
            return super.onTouchEvent(ev);
        }
    
        private void setDownPosition(MotionEvent ev){
            xDistance = yDistance = 0f;
            lastX = ev.getX();
            lastY = ev.getY();
        }
    
        private boolean isVerticalScroll(MotionEvent ev){
            final float curX = ev.getX();
            final float curY = ev.getY();
            xDistance += Math.abs(curX - lastX);
            yDistance += Math.abs(curY - lastY);
            lastX = curX;
            lastY = curY;
            if(xDistance < yDistance) {
                return true;
            }
            return false;
        }
    }
    

在你的活动布局中:

<com.example.FragmentViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

在您的活动onCreate()中:

final FragmentViewPager pager = (FragmentViewPager) findViewById(R.id.pager);