Подтвердить что ты не робот

Android Wear WearableListView в GridViewPager

Я создаю приложение Android Wear, которое я бы хотел представить в виде нескольких страниц, которые можно прокручивать по горизонтали.

Для этого я использую GridViewPager и связанный FragmentGridPagerAdapter, который жестко связан с одной строкой. Это отлично работает для прокрутки по горизонтали между плитами, однако в одном из моих фрагментов я хочу использовать WearableListView, чтобы позволить пользователю выбирать между несколькими действиями. К сожалению, это не работает, поскольку кажется, что GridViewPager предотвращает попадание swipes в WearableListView. Кто-нибудь знает, есть ли способ сделать это, используя описанные компоненты?

Я также пробовал использовать стандартный ViewPager, и это позволило WearableListView прокручивать все в порядке, но горизонтальное прокручивание затем становится ошибочным, и вам часто нужно несколько раз пронести по экрану для просмотра пейджера.

4b9b3361

Ответ 1

Я столкнулся с тем же. Просто установка одной строки или переопределение canscrollvertically() не работает. Единственный вариант, который я нашел, - это переопределить события касания, например, в ответе Нивека: HorizontalScrollView в обращении с сенсорным экраном ScrollView

Это работает для меня:

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

ИЗМЕНИТЬ:
Через некоторое время после публикации моего первоначального ответа я нашел правильный способ сделать это. Просто установите

    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 ) );
        }
    }
}

Ответ 3

Большое спасибо Грейдын Янг. Потому что я нашел время, чтобы найти, как реализует его решение так, как я делаю:

  • создайте класс (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);