Pregunta

Soy nuevo en Android.

Estoy dibujando mapas de bits, líneas y formas en un lienzo dentro del método OnDraw (Lona) de mi vista. Busco ayuda sobre cómo implementar el desplazamiento suave en respuesta a una carga por parte del usuario. He buscado, pero no encontró ningún tutoriales para que me ayude con esto.

La referencia de lienzo parece decir que si un lienzo se construye a partir de un mapa de bits (llamado bmpBuffer, por ejemplo), entonces nada dibujado en el lienzo también se dibuja en bmpBuffer. ¿Sería posible utilizar bmpBuffer para implementar un pergamino ... quizá lo copie en el lienzo desplazado por unos pocos píxeles a la vez? Pero si uso Canvas.drawBitmap para dibujar bmpBuffer de nuevo a la lona desplazado por unos pocos píxeles, no será dañado bmpBuffer? Tal vez, por lo tanto, debería copiar bmpBuffer a continuación, dibuje bmpBuffer2 bmpBuffer2 de nuevo a la lona.

Un enfoque más sencillo sería para dibujar las líneas, formas, etc. directamente en un mapa de bits tampón luego dibujar que tampón (con un cambio) en el lienzo pero hasta ahora que puedo ver los diversos métodos: drawLine (), drawShape (), etc., no están disponibles para la elaboración de un mapa de bits ... sólo para un lienzo.

¿Puedo tener 2 lienzos? Uno de los cuales se construye a partir del mapa de bits de tampón y se utilizó simplemente para el trazado de las líneas, formas, etc., y a continuación, el mapa de bits tampón serían atraídos a la otra lona para mostrar en la vista?

Debería recibir 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 de "blit" o "BitBlt" en la documentación de Android. Son equivalentes de Canvas.drawBitmap y Bitmap.Copy Android?

¿Fue útil?

Solución

he tenido este problema también,

Hice el dibujo como esto:

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 había necesidad de hacer algún tipo de método que toma un par de puntos después de desplazarse (es decir, el primer punto de desplazamiento y el 10), restar esos y desplazamiento por ese número en una para cada bucle que hace que sea poco a poco más lenta (scrollamount - gira - fricción).

Espero que esto da una visión más clara.

Otros consejos

Me parece haber encontrado una respuesta. He puesto la mayor parte del código de dibujo (que estaba previamente en onDraw ()) en un método nuevo doDrawing (). Este método se inicia mediante la creación de un nuevo mapa de bits mayor que la pantalla (lo suficientemente grande para contener el dibujo completo). A continuación, crea un segundo lienzo en el que para 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 recoge con dibujo detallado a BufferCanvas.

El método completo 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 de la aplicación onCreate (). 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 poner en práctica el desplazamiento suave. O estoy y con vistas a algo !?

Continuación de la respuesta a Viktor ...

De hecho, la situación es más complicada. Debido a que el proceso es bastante lento doDrawing (tomar 2-3 segundos en mi lenta antiguo teléfono HTC Hero) He encontrado que es deseable para que aparezca un mensaje de aviso emergente para advertir al usuario de que estaba sucediendo y para indicar el motivo. La manera obvia de hacerlo era crear un nuevo método que contiene 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, he encontrado que la tostadora o bien nunca apareció o mostró tan breve que no se puede leer. Mi solución ha sido utilizar un manejador de comprobación de tiempo para forzar al programa a dormir durante 200 milisegundos entre la visualización de la tostada y llamando doDrawing (). Aunque esto retrasa ligeramente el inicio de un redibujado Siento que este es un precio a pagar en términos de facilidad de uso del programa debido a que el usuario sepa lo que está pasando. reDrawBuffer () ahora dice lo siguiente:

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

y el código del controlador (que está anidado dentro de mi vista de clase) 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 es necesario para la actividad que se reinicie! (Per prepbgg Ene 27 de 10 respuesta a su Ene 17 de 10 'respuesta') en lugar de reciclar el mapa de bits y de incurrir en la sobrecarga de tener la actividad vuelve a cargar, se puede evitar que la aplicación cargada poniendo el 'android: configChanges' atributo se muestra a continuación, en el elemento de 'actividad' del archivo AndroidManifest.xml para la aplicación. Esto le dice al sistema de la aplicación se encargará de la orientación cambia y que no tiene que 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 recibir una notificación cuando se cambia el orienation:

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!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top