1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Zeichnen auf Canvas

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von soma-web, 28.07.2011.

  1. soma-web, 28.07.2011 #1
    soma-web

    soma-web Threadstarter App-Anbieter (kostenpfl.)

    Beiträge:
    146
    Erhaltene Danke:
    18
    Registriert seit:
    06.07.2011
    Hi AH-Community,
    ich habe folegndes Problem, ich versuche über eine Methode aus einer Activity-Klasse auf eine Canvas/View Klasse zu zeichnen und anscheinend habe ich da nen tierischen Denkfehler drinne nur ich kann ihn mir im Moment nicht erklären. Wäre nett wenn sich jemand folgendes mal anschauen könnte und mir weiterhelfen könnte. beim Aufruf der Methode addLine passiert nämlich rein gar nix auf meinem "Canvas"

    Code:
    public class Striche extends View{
    	Paint paint;
    	Canvas canvas;
    	int breite;
    	int hoehe;
    	boolean isInitialized;
    	Bitmap bitmap;	 
    	
    	
    	public Striche(Context context, AttributeSet attrs) {
    		super(context, attrs);			 
    
    		paint = new Paint();
    	    paint.setColor(Color.BLACK);
    	    paint.setAntiAlias(true);
    	    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    	     
    	     isInitialized = false;
    	}
    	 private void init()
    	   {
    	     bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.RGB_565);
    	     
    	     canvas = new Canvas();
    	     isInitialized = true;
    
    	  }
    	
    	@Override	
    	protected void onDraw(Canvas canvas) {
    		if (!isInitialized)
    		       init();
    		Bitmap eBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.deckel) ;
    		        
           
    		canvas.drawBitmap(eBitmap ,0,0,  null) ;
    		breite = canvas.getWidth();
    		hoehe = canvas.getHeight();		
    		Paint bild = new Paint();		
    
    		paint.setColor(R.color.kulli);
    		paint.setStyle(Paint.Style.STROKE);
    		paint.setStrokeWidth(6);		
    		paint.setAntiAlias(true);
    
    		canvas.drawLine(40,40,60,60, paint);
    		
    
    	}
    	
    	public void addLine(int ort, int count){
    		paint = new Paint();
    		canvas.drawLine(0,0,77,132,paint);
    		paint.setColor(R.color.schwarz);
    		canvas.drawLine(40,40,70,70, paint);
    		paint.setColor(R.color.kulli);
    	}
    }
    
    Was mach ich denn falsch? Bei dem Aufruf von kulli.addLine müssten doch die Beiden Linien gezeichnet werden

    PSEUDOCODE DES AUFRUFS:
    Code:
    Striche kulli;
    LinearLayout layout;
    ..onCreate(){
            kulli = new Striche(this, null);
            layout = (LinearLayout)findViewById(R.id.lay);
            layout.addView(kulli);
    ...
    }
    onClickListener(){
    ..
    kulli.addLine(1, 1);
    }
    
    Danke für eure Hilfe!
    Grüße Soma
     
  2. DieGoldeneMitte, 28.07.2011 #2
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    Du hast zwei Variablen namens Canvas. Einmal als Parameter in onDraw (was du darein malst, wird sichtbar) und dann die Instanzvariable - dort malt addLine hinein. Wieso sollte das, was du in den einen Canvas malst, in dem anderen erscheinen?

    Um eins vorneweg zu nehmen: Du solltest einen Canvas nicht als Instanzvariable speichern. Wenn du von außen (also nicht in onDraw) den Inhalt eines Views verändern willst, dann macht man eher so, dass du in eine Bitmap malst, deren Canvas du kontrollierst (da sieht dein Code auch so aus, als hättest du das schon halb implementiert) und im addLine invalidierst du dann den View, der dann im onDraw die bitmap abholt und in den "sichtbaren" Canvas malt.
     
    Zuletzt bearbeitet: 28.07.2011
    soma-web bedankt sich.
  3. soma-web, 28.07.2011 #3
    soma-web

    soma-web Threadstarter App-Anbieter (kostenpfl.)

    Beiträge:
    146
    Erhaltene Danke:
    18
    Registriert seit:
    06.07.2011
    Danke für die Antwort!
    Aber kannst du mir nen Pseudocode schreiben wie ich das mach?
    Also du meintest ich sollte auf die bitmap malen und die dann im onDraw immer wieder neu malen? Dumme frage wann wird denn die onDraw Methode immer aufgerufen?

    Code:
    ondraw(){
    ....
    canvas.drawBitmap(bitmap, 10, 10, paint);
    }
    public void addLine(int ort, int count){
    		Canvas c = new Canvas(bitmap);		
    		Paint p = new Paint();
    		p.setColor(R.color.kulli);
    		p.setStyle(Paint.Style.STROKE);
    		p.setStrokeWidth(6);		
    		p.setAntiAlias(true);
    		c.drawLine(0,0,77,132,p);
    		p.setColor(R.color.schwarz);
    		c.drawLine(40,40,70,70, paint);
    		p.setColor(R.color.kulli);		
    	}
    
    meinst du so? Läuft aber auch noch nicht.
    Danke dir!
     
    Zuletzt bearbeitet: 28.07.2011
  4. soma-web, 28.07.2011 #4
    soma-web

    soma-web Threadstarter App-Anbieter (kostenpfl.)

    Beiträge:
    146
    Erhaltene Danke:
    18
    Registriert seit:
    06.07.2011
    Ich habs danke!!!!
    Eine frage hab ich noch und zwar sind meine neuen Linien immernoch schwarz wora kann das liegen?

    Code:
    package happy.prog.bier;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class Striche extends View{
    	Paint paint;
    	Canvas canvas;
    	int breite;
    	int hoehe;
    	boolean isInitialized;
    	Bitmap bitmap;	 
    	
    	
    	public Striche(Context context, AttributeSet attrs) {
    		super(context, attrs);			 
    
    		paint = new Paint();
    	    paint.setColor(Color.BLACK);
    	    paint.setAntiAlias(true);
    	    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    	     
    	     isInitialized = false;
    	}
    	 private void init()
    	   {
    	     bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8);	     
    	     canvas = new Canvas();	     
    	     isInitialized = true;
    
    	  }
    	
    	@Override	
    	protected void onDraw(Canvas canvas) {
    		if (!isInitialized)
    		       init();
    		
    
    		Bitmap eBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.deckel) ;
    		        
    		this.canvas = canvas;
    		canvas.drawBitmap(eBitmap ,0,0,  null) ;
    		breite = canvas.getWidth();
    		hoehe = canvas.getHeight();		
    		Paint bild = new Paint();
    		
    
    		paint.setColor(R.color.kulli);
    		paint.setStyle(Paint.Style.STROKE);
    		paint.setStrokeWidth(6);		
    		paint.setAntiAlias(true);
    
    		canvas.drawLine(40,40,60,60, paint);
    		canvas.drawBitmap(bitmap, 10, 10, paint);
    ;	
    	}
    	
    	public void addLine(int ort, int count){
    		Canvas c = new Canvas(bitmap);		
    		Paint p = new Paint();
    		p.setColor(Color.BLUE);
    		//p.setStyle(Paint.Style.STROKE);
    		p.setStrokeWidth(6);		
    		p.setAntiAlias(true);
    		c.drawLine(0,0,77,132,p);
    		p.setColor(Color.BLUE);
    		c.drawLine(40,40,70,70, paint);
    		p.setColor(R.color.kulli);		
    	}
    }
    
    
    Oh man wie blind ich bin!
    den Paint ändern vor dem zeichnen des bitmaps dann läufts ohne Probleme. Anscheinend is ein Btmap wirklcih nur der verfahrweg meiner Linie und die Färbung kommt dann erst beim zeichnen auf die canvas mit dem jeweiligen Paint.
    Danke DieGoldeneMitte!
     
    Zuletzt bearbeitet: 28.07.2011
  5. soma-web, 29.07.2011 #5
    soma-web

    soma-web Threadstarter App-Anbieter (kostenpfl.)

    Beiträge:
    146
    Erhaltene Danke:
    18
    Registriert seit:
    06.07.2011
    Bräcuhte nochmal Hilfe und zwar versuch ich das View per Java in mein LinearLayout einzufügen, aber ich krieg es nicht gebacken: NULLPOINTEREXCEPTION

    Ich probier es über folgenden Code:
    Code:
     
    onCreate(){
    ...
            Striche temp = new Striche(this, null);
            LinearLayout lay = (LinearLayout)findViewById(R.id.testlay);
            lay.addView(temp);
            setContentView(R.layout.zettel);        
    ...}
    
    Wie kann ich denn noch die Größe meines Views verändern weil es bis jetzt echt verdammt groß ist und mir so das ganze Layout zerschießt?

    Danke DieGoldeneMitte ^^

    Grüße Soma
     
  6. DieGoldeneMitte, 29.07.2011 #6
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    Wie soll er den View (findView) finden, wenn du ihn noch garnicht definiert (setContentView) hast?

    Dieser Fall war leicht zu sehen, aber das nächste mal ermittle bitte die Zeile, in der die NPE passiert ist (steht im LogCat) und zeig und deren Inhalt.

    ADD: Um Einfluss auf die Größe des Views zu nehmen, musst du onMeasure und onLayout überladen.
     
    Zuletzt bearbeitet: 29.07.2011
  7. soma-web, 29.07.2011 #7
    soma-web

    soma-web Threadstarter App-Anbieter (kostenpfl.)

    Beiträge:
    146
    Erhaltene Danke:
    18
    Registriert seit:
    06.07.2011
    hab ich gemacht, sorry :)
    setContentView(R.layout.start);
     
  8. DieGoldeneMitte, 29.07.2011 #8
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    Achso, die ID war auch noch falsch? :D

    Ich meinte aber was anderes: Du musst setContentView() vor findViewById() aufrufen.
    findView sucht im contentView (und nicht in den Resourcen oder so).

    ADD: Wenn du aus einer xml einen View aufbauen willst, ohne ihn zum Content zu machen, dann musst du einen LayoutInflater bemühen.
     
    Zuletzt bearbeitet: 29.07.2011

Diese Seite empfehlen