2014-07-17 12 views
18

Sto costruendo un'applicazione Android Wear che desidero presentare come poche pagine che possono essere trascinate orizzontalmente.Android Wear WearableListView in a GridViewPager

Per questo sto utilizzando un GridViewPager e FragmentGridPagerAdapter associato che è cablato per utilizzare una singola riga. Funziona bene per scorrere in orizzontale tra i riquadri, tuttavia in uno dei miei frammenti voglio usare un WearableListView per consentire all'utente di selezionare tra diverse azioni. Purtroppo questo non funziona in quanto sembra che GridViewPager impedisca a qualsiasi swipe di raggiungere WearableListView. Qualcuno sa se c'è un modo in cui questo può essere fatto usando i componenti descritti?

Ho anche provato a utilizzare un ViewPager standard e questo ha permesso a WearableListView di scorrere bene, ma lo scorrimento orizzontale diventa quindi "flakey" e spesso è necessario scorrere alcune volte per spostare la visualizzazione del cercapersone.

risposta

10

Mi sono imbattuto nella stessa cosa. Basta impostare una riga o ignorare canscrollvertically() non funziona. L'unica opzione che ho trovato è quello di ignorare gli eventi touch come nella risposta di Neevek qui: HorizontalScrollView within ScrollView Touch Handling

Questo è il lavoro per me:

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; 
} 
+0

Grazie non avrebbe mai capito questo me stesso. Continuo a chiedermi perché è così difficile ottenere qualcosa in Android a volte. Cose davvero semplici. – powder366

+0

Lo scorrimento di CardFragments funziona perfettamente in GridViewPager. Proverò a vedere come è fatto. – Gak2

+1

questa dovrebbe essere la risposta accettata: http://stackoverflow.com/a/25498711/271804 wearableListView.setGreedyTouchMode (true) è sufficiente per farlo funzionare grazie @Mome – rubdottocom

1

Grazie mille a Graydyn giovane .. causa ho preso tempo per trovare il modo in cui implementa la sua soluzione:

  • creare una classe (FragmentViewPager) che estende GridViewPager con il codice precedente.
  • uso questa classe invece di 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; 
        } 
    } 
    

nel layout di attività:

<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" /> 

nella vostra attività onCreate():

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

EDIT:
Un po 'di tempo dopo aver postato la mia risposta originale di seguito, ho trovato il modo corretto per farlo. Basta impostare

wearableListView.setGreedyTouchMode(true) 

e la visualizzazione elenco funziona perfettamente all'interno di GridViewPager.

La risposta originale è ancora una buona idea per ottenere lo scorrimento lavorando con uno scorrimento verticale GridViewPager annidato all'interno di uno scorrimento orizzontale.

ORIGINALE RISPOSTA:
Più o meno la stessa cosa come la risposta accettata può essere implementato più succintamente estendendo il GridViewPager in questo modo:

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

Devi amare questo materiale non documentato! Mi riempie come Cristoforo Colombo – Ran

+0

Questa risposta aggiornata dovrebbe essere accolta. Grazie per avermi salvato il tempo a programmare le cose cablate con gli eventi touch. –

+0

"setGreedyTouchMode" consente ancora il paging orizzontale? I documenti lo fanno sembrare come se non lo fosse: "Controlla se' WearableListView' debba intercettare tutti gli eventi di tocco e anche impedire al genitore di riceverli. " – stkent

Problemi correlati