2013-04-09 15 views
10

Ho bisogno di aiuto per capire i fondamenti dello scorrimento degli elementi disegnati su una tela in Android. Supponiamo di voler creare una timeline in cui il tempo a 0 è la parte superiore di una visualizzazione e mentre il tempo aumenta la timeline continua a essere visualizzata sotto il punto precedente. Se desidero renderlo su Android, so che potrei semplicemente creare un gruppo di elementi su una tela sovrascrivendo suDraw(). Tuttavia, supponiamo che la visualizzazione sia maggiore di quanto consentito dallo schermo.Scorrimento su tela di grandi dimensioni

Ad esempio nella prima figura sotto la grande scatola nera contiene l'intera tela mentre la eseguo. Creo una linea blu che scorre verticalmente su e giù così come diversi rettangoli gialli, verdi e blu. La casella rossa rappresenta lo schermo di Android che sta visualizzando la visualizzazione. All'apertura iniziale, tutti gli elementi vengono disegnati ma solo gli elementi contenuti nella casella rossa vengono visualizzati sullo schermo.

Before_Scroll

Ora, se l'utente è quello di scorrere verso il basso, gli oggetti che inizialmente apparivano sotto la casella rossa sono in vista, mentre gli elementi che sono andati fuori dai confini della scatola rossa non sono più visibile, come rappresentato in la seconda immagine.

After_Scroll

credo che ho bisogno di usare scrollables ma sono abbastanza perso come farlo. Ho letto questa pagina http://developer.android.com/training/custom-views/custom-drawing.html spiegando come creare le immagini dei tuoi clienti e questa pagina http://developer.android.com/training/custom-views/making-interactive.html che spiega come rendere l'interfaccia utente interattiva, ma penso che mi manchi qualcosa.

Un codice di esempio che illustra questo problema (questo è fondamentale, assumere c'è una logica dettare dove lo scatole/linee vanno, etc.) è la seguente:

package com.example.scrolltest; 

import com.example.scrolltest.Draw; 

import android.os.Bundle; 
import android.app.Activity; 
import android.graphics.Color; 

public class MainActivity extends Activity { 
    Draw draw; 

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

    draw = new Draw(this); 
    draw.setBackgroundColor(Color.WHITE); 
    setContentView(draw); 
    } 
} 

e

package com.example.scrolltest; 


import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.view.View; 


public class Draw extends View { 
    Paint paint = new Paint(); 

    public Draw(Context context) { 
     super(context);    
    } 

    @Override 
    public void onDraw(Canvas canvas) { 

     paint.setColor(Color.GREEN); 
     canvas.drawRect(30, 30, 90, 200, paint); 
     paint.setColor(Color.BLUE); 

     canvas.drawLine(100, 20, 100, 1900, paint); 

     paint.setColor(Color.GREEN); 
     canvas.drawRect(200, 2000, 400, 3000, paint); 
     } 
} 

Quello che non riesco a capire però, è il modo in cui uso uno scorrevole per scorrere verso il basso fino ai rettangoli che sono fuori dallo schermo. Non sono sicuro di averlo avviato correttamente o di utilizzare invece i drawable ...

risposta

20

Metodo semplice (se l'altezza richiesta non è molto grande).

Utilizzare ScrollView e aggiungere la vista Draw in esso. Calcola l'altezza richiesta per quella vista in onMeasure.

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

draw = new Draw(this); 
draw.setBackgroundColor(Color.WHITE); 
ScrollView scrollView = new ScrollView(this); 
scrollView.addView(draw); 
setContentView(scrollView); 
} 

public class Draw extends View { 
     Paint paint = new Paint(); 

     public Draw(Context context) { 
      super(context);    
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      // Compute the height required to render the view 
      // Assume Width will always be MATCH_PARENT. 
      int width = MeasureSpec.getSize(widthMeasureSpec); 
      int height = 3000 + 50; // Since 3000 is bottom of last Rect to be drawn added and 50 for padding. 
      setMeasuredDimension(width, height); 
     } 

     @Override 
     public void onDraw(Canvas canvas) { 

      paint.setColor(Color.GREEN); 
      canvas.drawRect(30, 30, 90, 200, paint); 
      paint.setColor(Color.BLUE); 

      canvas.drawLine(100, 20, 100, 1900, paint); 

      paint.setColor(Color.GREEN); 
      canvas.drawRect(200, 2000, 400, 3000, paint); 
      } 
    } 
+0

come si può aggiungiamo panning funzione per la tela? –

0

Un'alternativa può essere l'uso di valori X/Y offset.

Il modo in cui gestisci i valori di offset dipende da te, anche se preferisco usare una classe che chiamo Camera. L'accesso dovrebbe essere statico.

public void render(Canvas c){ 
    c.drawRect(100 - offsetX, 100 - offsetY, 120 - offsetX, 120 - offsetY, Paints.BLUE); 

} 

E per scorrere la tela:

float x, y; 
@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    if(ev.getAction() == MotionEvent.ACTION_DOWN){ 
     x = ev.getX(); 
     y = ev.getY(); 
    }else if (ev.getAction() == MotionEvent.ACTION_MOVE) { 
     float currX = ev.getX(); 
     float currY = ev.getY(); 

     float newOffsetX = (x - currX), 
       newOffsetY = (y - currY); 
     //The next two if-statements are to add sensitivity to the scrolling. 
     //You can drop these if you don't plan on having touch events 
     //with pressing. Pressing works without this as well, but the canvas may move slightly 
     //I use DP to handle different screen sizes but it can be replaced with pixels. c is a context-instance 
     if (newOffsetY < Maths.convertDpToPixel(2, c) && newOffsetY > -Maths.convertDpToPixel(2, c)) 
      newOffsetY = 0; 

     if (newOffsetX < Maths.convertDpToPixel(2, c) && newOffsetX > -Maths.convertDpToPixel(2, c)) 
      newOffsetX = 0; 
     offsetX += newOffsetX; 
     offsetY += newOffsetY; 
     x = ev.getX(); 
     y = ev.getY(); 
    } 

    return true; 

} 

E un campione Camera-classe:

public class Camera{ 

    public static float offsetX, offsetY; 
    //The constructor. ix and iy is the initial offset. Useful if you are creating a game and need to change the initial offset to center around a starting position. 
    //Most of the time it will be enough to set the values to 0 
    public Camera(float ix, float iy){ 
     this.offsetX = ix; 
     this.offsetY = iy; 
    } 

} 
Problemi correlati