Layouts + Canvas

Estou tentando fazer um aplicativo com 3 HorizontalScrollView.
As duas primeiras são compostas de TextView que combinadas geram um cursor para o que será exibido na terceira HorizontalScrollView.
O problema é essa última que teria que ser dinâmica (pois é resultado de um cursor podendo vir de 1 até 9 resultados).
Essa última seria uma imagem que seria “montada” na hora.
Existe um meio de combinar e exibir Layouts e Canvas? Estou conseguindo fazer ou um ou outro. Pensei nesse layout:

<HorizontalScrollView> ... </HorizontalScrollView>
<HorizontalScrollView> ... </HorizontalScrollView>
<HorizontalScrollView> 
       <LinearLayout> 
                 <MinhaClasseQueMontaODesenho> ... </MinhaClasseQueMontaODesenho>
       </LinearLayout>
</HorizontalScrollView>

Com resultados do cursor quero incluir novas views com addView(objetos de MinhaClasseQueMontaODesenho).
Em MinhaClasseQueMontaODesenho que extende View, escrevi o método onDraw.
Acontece que no onCreate se faço setContentView(R.layout.layoutdescrito) não exibe o desenho, ou seja, parece não disparar o onDraw de MinhaClasseQueMontaODesenho.
E se faço setContentView(objDesenho) só exibe o desenho.
Não consigo fazer layouts+Canvas juntos. Alguém tem idéia de como fazer isso, pois todos os tutoriais que vejo que usam Canvas o utilizam como fullScreen e eu queria layout na parte superior da tela e canvas na parte inferior.

Uma View precisa ser independente da hierarquia que está inserida.

Voce pode criar sua View, sobreescrever o onDraw dele e colocar no Layout como se fosse outro componente qualquer.

Sim. Por isso estou criando a classe só que não estou conseguindo fazê-la aparecer.
Vamos supor um exemplo em que a cada clique num botão faça aparecer um desenho em uma HorizontalScrollView.
Então faço o XML com a classe dentro dele:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Button" />

    <HorizontalScrollView
        android:id="@+id/hsv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="143dp" >

        <LinearLayout
	        android:id="@+id/mLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal" >
            
            <com.example.testecanvas.Desenhar
            	android:layout_width="match_parent"
            	android:layout_height="match_parent" >
            </com.example.testecanvas.Desenhar>
            
        </LinearLayout>
    </HorizontalScrollView>

</RelativeLayout>

E a classe que desenharia seria algo assim:

package com.example.testecanvas;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

	public class Desenhar extends View{

		Bitmap bm; 
	   	Paint mPaint;

	   	public Desenhar(Context context) {	super(context);	init();	}
	    public Desenhar(Context context, AttributeSet attrs) { super(context, attrs); init(); }
	    public Desenhar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); }
	 
	    private void init() 
	    {
			bm = BitmapFactory.decodeResource(getResources(), R.drawable.grafico);
			mPaint=new Paint();
	    }
	   	
	   	@Override
		protected void onDraw(Canvas canvas)
		{
			super.onDraw(canvas);
			canvas.save();
			mPaint.setColor(Color.RED);
	        canvas.drawBitmap(bm, 20, 50, mPaint);
	        canvas.drawCircle(10, 10, 10, mPaint);
			canvas.restore();
		}   	
	}

E a Activity assim:

package com.example.testecanvas;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends Activity {
	Desenhar objDesenhar;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        final Button botao = (Button) findViewById(R.id.button1);
    	final LinearLayout mLayout = (LinearLayout) findViewById(R.id.mLayout);
        
        botao.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
            	objDesenhar = new Desenhar(getBaseContext());
            	objDesenhar.invalidate();
            	mLayout.addView(objDesenhar);
            }
          });        
    }
}

A imagem coloquei na pasta res/drawable-hdpi.
Mas não aparece a imagem com o círculo na tela.
Onde ESTÃO os erros? :slight_smile:

Obrigado.

Olhe seu Layout

<HorizontalScrollView  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"   >  
  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"   >  
              
            <com.example.testecanvas.Desenhar  
                android:layout_width="match_parent"  
                android:layout_height="match_parent" />  
              
        </LinearLayout>  
    </HorizontalScrollView>  

HorizontalScrollView = WRAP_CONTENT
LinearLayout = MATCH_PARENT
Desenhar = MATCH_PARENT

Nenhum componente tem algum tamanho para o WRAP_CONTENT funcionar.

Pelo que vi seu código está certo, da uma olhada nisso.

E outra, voce poderia alterar a instancia de objDesenhar invés de criar um novo toda hora que clicar no botao.

Marky:

Na verdade estava torcendo para vc responder minha questão.
Claro que deve ter notado que a classe que extend View é bem baseada na sua do Pong. :wink:
Você não tem idéia quantas vezes alterei esse código e na verdade era apenas um erro de layout. Você matou a charada legal!!! Valeu MESMO!!!

Esse exemplo, na verdade, tinha outro erro similar ao que vc apontou.
Só passou a aparecer as novas figuras incluídas quando no init() setei o LayoutParams.
Mas sua dica que me levou a essa correção.

Quanto a rever como instanciar a nova classe, é o seguinte: Esse foi apenas um exemplo bem mais simples do que realmente quero.
O método onDraw() que vou criar vai desenhar coisas diferentes de acordo com o resultado de uma query, entende?

Valeu!!!

Fico feliz em saber que minha ajuda resolveu seu problema ^^

Pode perguntar se precisar de mais alguma coisa.

Alis, acho que entendi o que voce quer fazer vai ter algum tipo de model? Algo como o Adapter do Android ou o TableModel do JTable?

Desculpe só ter visto sua msg agora.
Respondendo: acho que está mais para um adapter do android.
Terminei a aplicação. Ficou do jeito que queria. Vou ver se depois coloco um vídeo para que, se vc tiver curiosidade, possa ver.
Só não ficou uma coisa legal: Para testar eu entrei e saí da aplicação umas 8 vezes seguidas (sem fazer nada, só entrando e saindo) e o android acaba por dar uma mensagem que a aplicação parou.
Estou fechando o BD existente.
Ainda não descobri o que falta encerrar.
valeu!

Poste depois sim, voce está olhando no logcat as Exceptions que fecham sua aplicação?

Ei-lo:

Valeu!

Gostei do icone e da splash com som.

Ficou bem legal essa sua custom View dos acordes.

O aplicativo ficou bem maneiro, vi que voce entendeu bem o esquema de adapters .

Parabéns!

PS: “Apareceu até uma formiginha aqui em cima… pronto” ehauehauheuaheuaheuhaeuahuehau

Obrigado!
A formiga foi f… Depois lembrei daquele meme "Ai que dó! Que dó!"
Valeu.