Desplazamiento suave de una lona en Android

Soy nuevo en Android.

Estoy dibujando bitmaps, líneas y formas sobre un lienzo dentro del método OnDraw (Canvas canvas) de mi vista. Estoy buscando ayuda sobre cómo implementar desplazamiento suave en respuesta a un arrastre por el usuario. He buscado, pero no he encontrado ningún tutorial para ayudarme con esto.

La referencia para Canvas parece decir que si un lienzo se construye a partir de un mapa de bits (llamado bmpBuffer, digamos) entonces cualquier cosa dibujada en el lienzo también se dibuja en bmpBuffer. ¿Sería posible utilizar bmpBuffer para implementar un desplazamiento … tal vez copiarlo de nuevo a la lona desplazado por unos pocos píxeles a la vez? Pero si utilizo Canvas.drawBitmap para dibujar bmpBuffer de nuevo a la lona desplazada por unos pocos píxeles, no bmpBuffer ser dañado? Tal vez, por lo tanto, debo copiar bmpBuffer a bmpBuffer2 y luego dibujar bmpBuffer2 de nuevo a la lona.

Un acercamiento más directo sería dibujar las líneas, las formas, el etc. derecho en un almacenaje intermediario del búfer después dibujar ese almacenador intermediario (con un cambio) sobre el lienzo pero tan lejos como puedo ver los varios métodos: drawLine (), drawShape () Y así sucesivamente no están disponibles para dibujar a un mapa de bits … sólo a un lienzo.

¿Podría tener 2 Lonas? Uno de los cuales se construiría a partir del mapa de bits de memoria intermedia y se usaría simplemente para trazar las líneas, formas, etc. y entonces el mapa de bits del búfer se dibujaría sobre el otro lienzo para mostrarlo en la vista?

¡Debo acoger cualquier consejo!

Las respuestas a preguntas similares aquí (y en otros sitios web) se refieren a "blitting". Entiendo el concepto pero no puedo encontrar nada sobre "blit" o "bitblt" en la documentación de Android. ¿Son Canvas.drawBitmap y Bitmap.Copy los equivalentes de Android?

También tuve este problema,

Hice el dibujo como este:

Canvas BigCanvas = new Canvas(); Bitmap BigBitmap = new Bitmap(width,height); int ScrollPosX , ScrollPosY // (calculate these with the onScrollEvent handler) void onCreate() { BigCanvas.SetBitmap(BigBitmap); } onDraw(Canvas TargetCanvas) { // do drawing stuff // ie. BigCanvas.Draw.... line/bitmap/anything //draw to the screen with the scrolloffset //drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint) TargetCanvas.DrawBitmap(BigBitmap(new Rect(ScrollPosX,ScrollPosY,ScrollPosX + BigBitmap.getWidth(),ScrollPosY + BigBitmap.getHeight(),new Rect(0,0,ScreenWidth,ScreenHeight),null); } 

Para el desplazamiento suave que necesitas para hacer algún tipo de método que toma unos pocos puntos después de desplazamiento (es decir, el primer punto de desplazamiento y el 10 º), restarlos y desplazarse por ese número en un para cada lazo que lo hace poco a poco más lento (ScrollAmount – giros – Fricción).

Espero que esto dé una idea más.

Parece que he encontrado una respuesta. He puesto la mayor parte del código de dibujo (que anteriormente estaba en onDraw ()) en un nuevo método doDrawing (). Este método comienza creando un nuevo bitmap más grande que la pantalla (lo suficientemente grande para contener el dibujo completo). A continuación, crea un segundo lienzo en el que hacer el dibujo detallado:

  BufferBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888); Canvas BufferCanvas = new Canvas(BufferBitmap); 

El resto del método doDrawing () se toma con dibujo detallado a BufferCanvas.

El método entero onDraw () ahora se lee como sigue:

  @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(BufferBitmap, (float) -posX, (float) -posY, null); } 

Las variables de posición, posX y posY, se inicializan en 0 en el método onCreate () de la aplicación. La aplicación implementa OnGestureListener y utiliza los argumentos distanceX y distanceY devueltos en la notificación OnScroll para incrementar posX y posY.

Eso parece ser sobre todo lo que se necesita para implementar el desplazamiento suave. ¿O estoy mirando algo?

Continuación de la respuesta a Viktor …

De hecho, la situación es más complicada. Debido a que el proceso de doDrawing es bastante lento (teniendo 2-3 segundos en mi viejo teléfono HTC héroe lenta) me pareció conveniente hacer estallar un mensaje Toast para informar al usuario que estaba sucediendo y para indicar la razón. La manera obvia de hacerlo fue crear un nuevo método que contenga sólo 2 líneas:

 public void redrawBuffer(String strReason) { Toaster.Toast(strReason, "Short");` doDrawing(); } 

Y llamar a este método de otros lugares en mi programa en lugar de doDrawing ().

Sin embargo, me pareció que el tostador o nunca apareció o flash tan brevemente que no podía ser leído. Mi solución ha sido utilizar un controlador de comprobación de tiempo para forzar el programa a dormir durante 200 milisegundos entre mostrar el Toast y llamando a doDrawing (). Aunque esto retrasa ligeramente el comienzo de un redibujo siento que esto es un precio digno de pagar en términos de la utilidad del programa porque el usuario sabe lo que está sucediendo. ReDrawBuffer () ahora lee:

 public void redrawBuffer(String strReason) { Toaster.Toast(strReason, "Short"); mTimeCheckHandler.sleep(200); }` 

Y el código Handler (que está anidado dentro de mi clase View) es:

 private timeCheckHandler mTimeCheckHandler = new timeCheckHandler(); class timeCheckHandler extends Handler { @Override public void handleMessage(Message msg) { doDrawing(); } public void sleep(long delayMillis) { this.removeMessages(0); sendMessageDelayed(obtainMessage(0), delayMillis); } }` 

¡No hay necesidad de reiniciar la actividad! En lugar de reciclar el mapa de bits e incurrir en la sobrecarga de tener la actividad recargada, puede evitar tener la aplicación cargada poniendo el atributo 'android: configChanges' mostrado a continuación, En el elemento 'activity' del archivo AndroidManifest.xml de la aplicación. Esto indica al sistema que la aplicación gestionará los cambios de orientación y que no necesita reiniciar la aplicación.

 <activity android:name=".ANote" android:label="@string/app_name" android:configChanges="orientation|screenLayout"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 

Este método se puede utilizar para obtener una notificación cuando se cambia la orientación:

 public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); prt("onConfigurationChanged: "+newConfig); if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { prt(" PORTRAIT"); } else { prt(" LANDSCAPE"); } } // end of onConfigurationChanged 

Prepbgg: No creo que el código funcionará porque canvas.drawBitmap no dibuja en el mapa de bits pero dibuja el mapa de bits en el lienzo.

¡Corrígeme si estoy equivocado!

  • Lienzo Pinch-Zoom a punto dentro de límites
  • Cómo cambiar el tamaño de la imagen gif en android
  • Android Canvas.drawText
  • Cómo crear este tipo de pincel para pintar en android
  • ¿Cuál es la unidad del sistema de coordenadas de Canvas? Androide
  • Entendiendo el recorte de lienzo de Android
  • Canvas.clipPath (ruta) no recorte como se esperaba
  • onPreviewFrame y la superficie de bloqueo de excepción
  • Posición de escala incorrecta después de aplicar el efecto de zoom en el lienzo de Android
  • ¿Dónde puedo encontrar una biblioteca JAVA de efectos visuales y manipulación de imágenes?
  • Cómo dibujar un texto de gran tamaño en un lienzo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.