Desplazamiento sobre lienzo grande

Necesito ayuda para entender los fundamentos de desplazamiento sobre elementos que se dibujan a un lienzo en Android. Supongamos que quiero crear una línea de tiempo donde el tiempo en 0 es la parte superior de una visualización y, a medida que aumenta el tiempo, la línea de tiempo continúa mostrándose debajo del punto anterior. Si quiero hacer esto en Android, sé que podría simplemente crear un montón de elementos en un lienzo sobreescribiendo onDraw (). Sin embargo, supongamos que la visualización es mayor de lo que permite la pantalla.

Por ejemplo en la primera imagen debajo de la gran caja negra contiene el lienzo entero como lo hago. Creo una línea azul que corre verticalmente hacia arriba y hacia abajo, así como varios rectángulos amarillos, verdes y azules. El cuadro rojo representa la pantalla del Android que está procesando la visualización. Como se abre inicialmente todos los elementos se dibujan, pero sólo los elementos contenidos en el cuadro rojo aparecen en la pantalla.

Antes de desplazarse

Ahora si el usuario debe desplazarse hacia abajo, los elementos que aparecieron inicialmente debajo del cuadro rojo están a la vista mientras que los elementos que han salido de los confines de la caja roja ya no son visibles, como se representa en la segunda imagen.

Después de la exploración

Creo que necesito usar scrollables pero estoy muy perdido como hacerlo. He leído sobre esta página http://developer.android.com/training/custom-views/custom-drawing.html explicando cómo crear sus propias imágenes de clientes y esta página http://developer.android.com/training /custom-views/making-interactive.html explicando cómo hacer la interfaz de usuario interactiva, pero creo que me estoy perdiendo algo.

Un código de ejemplo que ilustra este problema (esto es básico, suponga que hay una lógica que dicta dónde van las cajas / líneas, etc.) es como sigue:

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

y

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

Lo que no puedo entender, sin embargo, es cómo uso un desplazamiento para desplazarse hacia abajo a los rectángulos que están fuera de la pantalla. También estoy inseguro si he comenzado esto correctamente o debería usar drawables en su lugar …

Método simple (si la altura requerida no es muy grande).

Utilice un ScrollView y agregue su vista de Draw en él. Calcule la altura requerida para esa vista en 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); } } 

Una alternativa puede ser usar valores de desplazamiento X / Y.

Cómo manejar los valores de compensación depende de ti, aunque prefiero usar una clase que llamo Camera . El acceso debe ser estático.

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

Y para pan el lienzo:

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

Y una muestra Camera-class:

 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; } } 
  • Desplazar RecyclerView para mostrar el elemento seleccionado en la parte superior
  • ¿Puedo deshabilitar el desplazamiento en TextView cuando se utiliza LinkMovementMethod?
  • Iniciar una animación onstart CustomViewPager
  • Sincronizar la posición de dos vistas ScrollView
  • Alinear texto al borde de la etiqueta en ScrollView en kivy
  • Limitar el número de líneas en TextView
  • Vista de cuadrícula de desplazamiento horizontal
  • Detectar cuando RecyclerView alcanza la posición más baja durante el desplazamiento
  • Desplazamiento de desplazamiento de GridView
  • Desplazamiento de imagen enriquecido y zoom en android
  • Cómo detectar si un listview está desplazándose hacia arriba o hacia abajo en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.