2009-05-18 8 views
2

J'écris une application de solitaire. J'utilise une toile pour tout dessiner sur l'écran. Parfois, une pile de cartes devient grande et s'étend au-dessous du bas de l'écran. Je voudrais faire défiler la toile afin que l'utilisateur puisse accéder à ces cartes.android canvas scroll

activité principale

package com.maulinpathare.solitaire; 

import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 

public class Solitaire extends Activity{ 
    /** Called when the activity is first created. */ 
    private Context mContext; 
    private GameView mG; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mContext = this; 
     setContentView(R.layout.main); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     boolean result = super.onCreateOptionsMenu(menu); 
     menu.add(0, 1, 0, R.string.newGame); 
     menu.add(0, 2, 0, R.string.exitGame); 
     return result; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case 1: 
      mG = new GameView(this); 
      setContentView(mG); 
      return true; 
     case 2: 
      finish(); 
      return true; 
     } 
     return false; 
    } 

}//end class 

Gameview classe C'est là que tout se passe j'ai supprimé la plupart de la logique du jeu ...

package com.maulinpathare.solitaire; 

import java.util.Stack; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.widget.ScrollView; 

public class GameView extends ScrollView implements OnTouchListener{ 
    private Deck mD; 
    private boolean mInit, mDone; 
    private Stack<Card> mPile1, mPile2, mPile3, mPile4, mPile5, mPile6, mPile7, 
           mOpenPile, mEndPile1, mEndPile2, mEndPile3, mEndPile4, mTemp; 
    private Canvas mCanvas; 
    private int mPile; 
    private boolean mPickUp, mVictory; 
    private Card mCard; 
    private final int mSpacing = 22; 
    private Paint rectPaint, wonPaint1, wonPaint2; 

    public GameView(Context context) { 
     super(context); 
        //initialize everything needed for the game 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
    mCanvas = canvas; 
    if(mInit){ 
      initialize(); 
      mInit = false; 
    } 
     //draw stuff... 

    }//end onDraw 

    public boolean onTouch(View v, MotionEvent event){ 
    int eventAction = event.getAction(); 
    int x = Math.round(event.getX()); 
    int y = Math.round(event.getY()); 

    switch(eventAction){ 
    case MotionEvent.ACTION_DOWN: 
        //check if touch has happened on one of the card piles 
      break; //end case action_touch 

    case MotionEvent.ACTION_MOVE: 
        //if card touched move it 
      break; //end case action_move 

    case MotionEvent.ACTION_UP: 
        //check if legal move has been made 
      break; //end case action_up 

    }//end switch(event) 

    invalidate(); 
    return true; 
    }//end onTouch 
} 

Où et comment dois-je mettre en œuvre le défilement de l'écran? Je voudrais que l'utilisateur soit capable de faire glisser son doigt sur l'écran dans la direction qu'il veut faire défiler.

+0

Ce poste ici http://stackoverflow.com/questions/2646028/android-horizontalscrollview-within-scrollview-touch-handling a un exemple de passer outre la méthode onInterceptTouchEvent. – andig

Répondre

2

Voir android.widget.Scroller et android.view.VelocityTracker. Ils vous permettront d'implémenter une vue défilante personnalisée. En outre, vous pouvez simplement mettre votre Canvas dans un ScrollView ...

+3

Oui, quelqu'un sur un autre forum m'a aussi dit de le faire. J'ai maintenant ajouté mon GameView en tant qu'enfant à un ScrollView. Le défilement fonctionne maintenant correctement, mais comme le ScrollView mange tous les événements tactiles, l'interaction avec les cartes est maintenant rompue. J'essaie de comprendre s'il y a un moyen d'avoir le ScrollView seulement accepter certains événements et passer le reste à ses enfants. – Maulin

0

Choses intéressantes, la façon dont j'ai compris que les vues fonctionnent sous Android est que les vues intérieures reçoivent tous les événements tactiles et les événements ne sont transmis qu'à l'encapsuleur views si l'onTouchEvent des vues internes renvoie 0 (pour dire qu'elles ne l'ont pas traité) à moins que la vue parent n'intercepte les événements tactiles.

Vous devez surcharger onInterceptTouchEvent je pense;

ScrollView

Vous voulez que les événements qui sont interceptés à transmettre à vue des enfants dans des situations plus qu'ils ne le sont actuellement.

Je trouve qu'il est souvent utile de regarder la source car la documentation peut être inégale.

Désolé je ne peux pas être plus utile, j'espère que vous pouvez trouver votre réponse en jouant avec une vue étendue.

Gav