Android Wear WearableListView в GridViewPager
Я создаю приложение Android Wear, которое я бы хотел представить в виде нескольких страниц, которые можно прокручивать по горизонтали.
Для этого я использую GridViewPager и связанный FragmentGridPagerAdapter, который жестко связан с одной строкой. Это отлично работает для прокрутки по горизонтали между плитами, однако в одном из моих фрагментов я хочу использовать WearableListView, чтобы позволить пользователю выбирать между несколькими действиями. К сожалению, это не работает, поскольку кажется, что GridViewPager предотвращает попадание swipes в WearableListView. Кто-нибудь знает, есть ли способ сделать это, используя описанные компоненты?
Я также пробовал использовать стандартный ViewPager, и это позволило WearableListView прокручивать все в порядке, но горизонтальное прокручивание затем становится ошибочным, и вам часто нужно несколько раз пронести по экрану для просмотра пейджера.
Ответы
Ответ 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);