2012-09-21 6 views
5

Ho un ScrollView verticale (in realtà, un ScrollView personalizzato, codice di seguito) all'interno di ViewFlipper. ViewFlipper funziona bene a meno che non scorri orizzontalmente sopra ScrollView per passare alla vista precedente/successiva. ScrollView funziona correttamente.Impossibile ottenere l'apertura orizzontale su ScrollView all'interno di ViewFlipper per creare bolle

Ecco il design. La casella verde è ScrollView, che dovrebbe essere verticale.

enter image description here

Ecco lo ScrollView:

public class SCScrollView extends ScrollView { 

    private float xDistance, yDistance, lastX, lastY; 

    GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector()); 
    OnTouchListener gestureListener; 

    public SCScrollView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     gestureListener = new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       if (gestureDetector.onTouchEvent(event)) { 
        return true; 
       } 
       return false; 
      }  
     }; 

    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     switch (ev.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       xDistance = yDistance = 0f; 
       lastX = ev.getX(); 
       lastY = ev.getY(); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       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 false; 
     } 

     return false; 
     //return super.onInterceptTouchEvent(ev); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     super.onTouchEvent(event); 
     return gestureDetector.onTouchEvent(event); 
    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent ev){ 
     gestureDetector.onTouchEvent(ev); 
     super.dispatchTouchEvent(ev); 
     return true; 
    } 

    /** GestureDetector used to swipe between classes */ 
    class MyGestureDetector extends GestureDetector.SimpleOnGestureListener { 
     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float  velocityY) { 
      return false; 
     } 
    } 

} 

Ho cercato di basare la soluzione sul consiglio qui HorizontalScrollView within ScrollView Touch Handling e qui Swipe/Fling tab-changing in conjunction with ScrollView? ma indipendentemente da ciò che torno dai callback, non posso ottenere il ViewFlipper per vedere il fling attraverso il ScrollView e, francamente, mi sto perdendo nella catena del tatto e degli ascoltatori di gesti.

Qualche idea?

Grazie

+0

Hai cercato di aggiungere un OnTouchListener alla ScrollView dal ViewFlipper, forse si può ottenere in questo modo i TouchEvents necessari? – Artjom

+0

Ciao Artjom. Sì, è quello che ho provato prima, ma sembra che ScrollView stia consumando l'avventura orizzontale, anche se non ne ha bisogno. Ecco perché sto cercando di scavalcare ScrollView così posso interrompere il suo consumo e farlo saltare in aria con il ViewFlipper padre, ma non va bene finora :( – Simon

risposta

6

Come nel documentato detto

http://developer.android.com/reference/android/widget/ScrollView.html

ScrollView supporta solo lo scorrimento verticale. Per lo scorrimento orizzontale, utilizza HorizontalScrollView.

Quindi, ho bisogno di chiedere perché hai davvero voglia di usare la tua scrollview personalizzata?

Se si intende solo per essere in grado di scorrere, si potrebbe non c'è bisogno di usarlo

solo RelativeLayout.scrollBy (x, y); è sufficiente

Si potrebbe guardare a questo link

Scrollview vertical and horizontal in android

EDIT

Ok, quindi è necessario fare il gesto di rilevare la scappatella sul ScrollView.

Si potrebbe fare nel vostro attività senza fare personalizzato ScrollView anche

prima, è necessario

implements OnGestureListener, OnTouchListener, GestureDetector.OnDoubleTapListener 

e nella tua classe creare gestureDetector

gd = new GestureDetector(this); 

e l'oggetto ScrollView, appena dichiarato

sv.setOnTouchListener(this); 

poi, in sostituzione metodo onTouch

@Override 
public boolean onTouch(View v, MotionEvent event) { 
     onTouchEvent(event); // throw to onTouchEvent 

    return false; 
} 

e nel metodo onTouchEvent esclusione

@Override 
public boolean onTouchEvent(MotionEvent me) 
{ 
    return gd.onTouchEvent(me); // gd = gesturedetector 
} 

ora sovrascrivono il metodo onFling come questo

private static final int SWIPE_MIN_DISTANCE = 120; 
private static final int SWIPE_THRESHOLD_VELOCITY = 200; 

@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
     float velocityY) { 

    if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
     // "Left Swipe" 
     vf.showPrevious(); // vf = ViewFlipper 

    } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
     // "Right Swipe" 
     vf.showNext(); 
    } 

    return false; 
} 

e questo è tutto codice

classe ViewFlipperActivity

import android.os.Bundle; 
import android.app.Activity; 
import android.view.GestureDetector; 
import android.view.GestureDetector.OnGestureListener; 
import android.view.View.OnTouchListener; 
import android.view.MotionEvent; 
import android.view.View; 
import android.webkit.WebSettings; 
import android.webkit.WebView; 
import android.widget.HorizontalScrollView; 
import android.widget.ScrollView; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.widget.ViewFlipper; 

public class ViewFlipperActivity extends Activity implements OnGestureListener, OnTouchListener, GestureDetector.OnDoubleTapListener 
{ 

    TextView tv; 
    GestureDetector gd; 
    ScrollView sv; 
    ViewFlipper vf; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     gd = new GestureDetector(this); 

     setContentView(R.layout.activity_viewflipper); 

     tv = (TextView)findViewById(R.id.textView1); 
     sv = (ScrollView)findViewById(R.id.scrollView1); 
     vf = (ViewFlipper)findViewById(R.id.viewFlipper1); 

     sv.setOnTouchListener(this); 

    } 

    @Override 
    public boolean onDoubleTap(MotionEvent arg0) { 
     tv.setText("double tap"); 
     return false; 
    } 

    @Override 
    public boolean onDoubleTapEvent(MotionEvent arg0) { 
     tv.setText("double tap event"); 
     return false; 
    } 

    @Override 
    public boolean onSingleTapConfirmed(MotionEvent arg0) { 
     tv.setText("single tap confirm"); 
     return false; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent me) 
    { 
     return gd.onTouchEvent(me); 
    } 

    @Override 
    public boolean onDown(MotionEvent arg0) { 
     tv.setText("down"); 
     return false; 
    } 

    private static final int SWIPE_MIN_DISTANCE = 120; 
    private static final int SWIPE_THRESHOLD_VELOCITY = 200; 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 

     if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
      tv.setText("Left Swipe"); 
      vf.showPrevious(); 

     } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
      tv.setText("Right Swipe"); 
      vf.showNext(); 
     } 

     return false; 
    } 

    @Override 
    public void onLongPress(MotionEvent arg0) { 
     tv.setText("long press"); 

    } 

    @Override 
    public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, 
      float arg3) { 
     tv.setText("scroll"); 
     return false; 
    } 

    @Override 
    public void onShowPress(MotionEvent arg0) { 
     tv.setText("show press"); 
    } 


    @Override 
    public boolean onSingleTapUp(MotionEvent arg0) { 
     tv.setText("single tab up"); 
     return false; 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     onTouchEvent(event); 

     return false; 
    } 
} 

e activity_viewflipper.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" 
     android:text="TextView" /> 

    <ViewFlipper 
     android:id="@+id/viewFlipper1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     android:layout_below="@+id/textView1" > 

     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" > 

      <ScrollView 
       android:id="@+id/scrollView1" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_above="@+id/textView3" 
       android:layout_alignParentLeft="true" 
       android:layout_alignParentTop="true" 
       android:layout_marginLeft="28dp" 
       android:layout_marginTop="63dp" 
       android:layout_toLeftOf="@+id/textView2" > 

       <ImageView 
        android:id="@+id/imageView1" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:scaleType="matrix" 
        android:src="@drawable/thailandmap" /> 

      </ScrollView> 

      <TextView 
       android:id="@+id/textView2" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentRight="true" 
       android:layout_alignTop="@+id/scrollView1" 
       android:layout_marginRight="30dp" 
       android:text="TextView" /> 

      <TextView 
       android:id="@+id/textView3" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentBottom="true" 
       android:layout_alignRight="@+id/scrollView1" 
       android:layout_marginBottom="250dp" 
       android:layout_marginRight="29dp" 
       android:text="TextView" /> 

     </RelativeLayout> 

     <ImageView 
      android:id="@+id/imageView2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:scaleType="matrix" 
      android:src="@drawable/thwriting" /> 

    </ViewFlipper> 

</RelativeLayout> 
+0

Ciao e grazie per la tua risposta Non sto cercando di ottenere una ScrollView orizzontale. Sto cercando di far sì che ViewFlipper riconosca lo scorrimento orizzontale sullo ScrollView che dovrebbe andare alla vista precedente o successiva.Ho modificato la domanda per renderla (si spera) più chiara. – Simon

+0

OK, guarda la mia risposta modificata. L'ho provato e funziona. –

+0

Grazie amico, ci proverò domani e tornerò ... – Simon

Problemi correlati