Pergunta

Eu sou novo para o Android.

Estou desenhando mapas de bits, linhas e formas para uma Tela dentro do OnDraw(Lona lona) método de meu ponto de vista.Estou à procura de ajuda sobre como implementar a rolagem suave em resposta a um arrastar pelo usuário.Eu procurei, mas não encontrei nenhum tutorial para me ajudar com isso.

A referência para a Tela, parece dizer que, se uma Tela é construído a partir de um mapa de bits (chamado de bmpBuffer, por exemplo), então qualquer coisa desenhada sobre a Tela também é desenhado no bmpBuffer.Seria possível usar bmpBuffer para implementar um pergaminho ...talvez copiá-lo de volta para a Tela mudou por alguns pixels de cada vez?Mas se eu usar Lona.drawBitmap para desenhar bmpBuffer de volta para a Tela mudou por alguns pixels, não bmpBuffer ser corrompido?Talvez por isso, eu deveria copiar bmpBuffer para bmpBuffer2, em seguida, desenhar bmpBuffer2 de volta para a Tela.

Uma abordagem mais simples seria para desenhar as linhas, as formas, etc.em linha reta em um buffer de mapa de bits, em seguida, desenhar buffer (com uma mudança) para a Tela, mas tão longe quanto eu possa ver os vários métodos:drawLine(), drawShape() e assim por diante não estão disponíveis para o desenho em um Bitmap ...apenas a uma Tela.

Eu poderia ter 2 Telas?Um dos quais seria construída a partir de um buffer de mapa de bits e simplesmente utilizado para plotar as linhas, as formas, etc.e, em seguida, o buffer de bitmap deve ser desenhado para a outra Tela para exibir no modo de exibição?

Eu as boas-vindas a qualquer conselho!

Respostas para perguntas semelhantes aqui (e em outros sites) consulte "blitting".Eu entendo o conceito, mas não consigo encontrar nada sobre "blit" ou "bitblt" no Android documentação.São De Lona.drawBitmap e de Bitmap.Cópia do Android equivalentes?

Foi útil?

Solução

Eu tive esse problema também,

Eu fiz o desenho assim:

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 rolagem suave, você precisaria fazer algum tipo de método que leva alguns pontos após a rolagem (ou seja, o primeiro ponto de rolagem e o 10º), subtrai -los e role por esse número em um loop que o torna gradualmente mais lento (roldição - turnos - atrito).

Espero que isso dê mais informações.

Outras dicas

Parece-me ter encontrado uma resposta.Coloquei a massa do código de desenho (que foi anteriormente no onDraw()) em um novo doDrawing() método.Este método começa por criar um novo mapa de bits maior do que a tela (grande o suficiente para manter o completo de desenho).Em seguida, ele cria uma segunda Tela em que para fazer o desenho detalhado:

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

O resto do doDrawing() o método é tomado com desenho detalhado para BufferCanvas.

Todo o onDraw() o método agora o seguinte:

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

A posição de variáveis, posX e posY, são inicializadas a 0 na aplicação do onCreate()método.A aplicação implementa OnGestureListener e usa o distanceX e distanceY argumentos devolvidos em OnScroll notificação para incrementar posX e posY.

Essa parece ser sobre tudo o que é necessário para implementar a rolagem suave.Ou eu sou sobre-procurando alguma coisa!?

Continuação da resposta a Viktor ...

De fato, a situação é mais complicada. Como o processo de Dodrawing é bastante lento (levando 2-3 segundos no meu lento e antigo telefone HTC Hero), achei desejável exibir uma mensagem de brinde para aconselhar o usuário que estava acontecendo e indicar o motivo. A maneira óbvia de fazer isso foi criar um novo método contendo apenas 2 linhas:

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

e chamar esse método de outros lugares do meu programa em vez de Dodrawing ().

No entanto, descobri que a torradeira nunca apareceu ou apareceu tão brevemente que não podia ser lida. Minha solução alternativa foi usar um manipulador de cheques de tempo para forçar o programa a dormir por 200 milissegundos entre exibir o brinde e chamar Dodrawing (). Embora isso atrase um pouco o início de um redesenho, sinto que esse é um preço que vale a pena pagar em termos da usabilidade do programa porque o usuário sabe o que está acontecendo. RedrawBuffer () agora diz:

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

E o código do manipulador (que está aninhado na minha classe de visualização) é:

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

Não há necessidade de a atividade ser reiniciada! (De acordo com 27 de janeiro de Jan 10 de janeiro de 17 de janeiro, 'Resposta') Em vez de reciclar o bitmap e incorrer na sobrecarga de ter a atividade recarregada, você pode evitar que o aplicativo seja carregado pela colocação do atributo 'Android: ConfigChanges' mostrado abaixo, No elemento 'atividade' do arquivo Androidmanifest.xml para o aplicativo. Isso informa ao sistema que o aplicativo lidará com as alterações de orientação e que não precisa reiniciar o aplicativo.

<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 pode ser usado para obter uma notificação quando a orienação é alterada:

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: Não acho que o código funcione porque o Canvas.drawbitmap não se baseia no bitmap, mas desenha o bitmap na tela.

Me corrija se eu estiver errado!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top