Pfad auf Canvas zeichen, nach dem das Canvas skaliert wurde.

C

chillout

Neues Mitglied
0
Ich hab folgendes Beispiel im Internet gefunden Beispiel und wollte dieses Unter Android 4.0 nachprogrammieren bzw. etwas rumspielen.

Jetzt hab ich in meiner OnDraw-Methode zunächst ein Bitmap auf das Canvas gelegt und anschließen will ich auf dem Canvas noch einen Pfad zeichnen.

PHP:
	Path pfad= new Path();
	pfad.moveTo(0.5f, 0.5f + 0.2f);
	pfad.lineTo(0.5f - 0.010f, 0.5f + 0.2f - 0.007f);
	pfad.lineTo(0.5f - 0.002f, 0.5f - 0.32f);
	pfad.lineTo(0.5f + 0.002f, 0.5f - 0.32f);
	pfad.lineTo(0.5f + 0.010f, 0.5f + 0.2f - 0.007f);
	pfad.lineTo(0.5f, 0.5f + 0.2f);

Die angaben mit 0.5f usw. sollten wohl funktionieren wenn das Canvas skaliert wurde. Deshalb wird folgendes gemacht:
PHP:
float scale = (float) getWidth();		
canvas.scale(scale, scale);

Nur wird der Pfad nicht auf dem Canvas gezeichnet.
Wie genau funktioniert das mit dem scale? Wenn ich im Pfad Pixelangaben mache, dann wird der Pfad gezeichnet.
 
Dein Code beinhaltet keinen Befehl (canvas.drawPath(...)), der den Pfad zeichnet. Ist es vielleicht das?
 
Danke, aber an canvas.DrawPath(...) hab ich gedacht nur nicht dazugeschrieben.

Gezeichnet wird ja nur wenn ich bei dem Pfad feste Pixelangaben anstatt 0.5f mache. Nur sollte es mit 0.5f gehen.

Mir ist eigentlich auch das Prinzip des Skalierens nicht klar.
Ich möchte mein Canvas am liebsten mit Prozentangaben ansprechen, also sollte die Mitte von Canvas mit (50%,50%) sein.
Mit diesem Scale kann man zumindest soweit ich es jetzt versucht habe mit (0.5f,0.5f) auch auf die Mitte des Canvas zugreifen.
Nur wie wird das festgelegt?
 
Zuletzt bearbeitet:
Der Canvas benutzt intern eine Transformationsmatrix, die jeden Drawbefehl in physische Koordinaten übersetzt. Man muss den Scale also vor dem drawPath machen. Hast du das so gemacht? Und noch ein Problem: Bist du sicher, dass die Breite des View korrekt ist, also ist der View zu dem Zeitpunkt, wo du scale aufrufst, schon gelayoutet?
 
Scale wird vor dem drawPath aufgerufen. Hier mein onDraw:
PHP:
	protected void onDraw(Canvas canvas) {
		drawBackgroundBitmap(canvas);
		float scale = (float) getWidth();		
		canvas.save(Canvas.MATRIX_SAVE_FLAG);
		canvas.scale(scale, scale);
		canvas.drawPath(needlePath, needlePaint);
		canvas.restore();
	}

Die Größe der View sollte mit onMeasure korrekt gesetzt werden. Hier meine OnMeasure:
PHP:
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int width = MeasureSpec.getSize(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int height = MeasureSpec.getSize(heightMeasureSpec);
		int size = Math.min(width, height);
		if (widthMode == MeasureSpec.UNSPECIFIED
				|| heightMode == MeasureSpec.UNSPECIFIED) {
			size = 200;
		}
		setMeasuredDimension(size, size);
	}
 
Das sieht alles eigentlich ganz gut aus (mit Catlog vllt mal gucken, ob die width stimmt....)

Aber hast du eventuell den Alphawert in deinem Paint falsch gesetzt?
 
Die Farbe hab ich so definiert:
PHP:
	needlePaint = new Paint();
	needlePaint.setAntiAlias(true);
	needlePaint.setColor(0xfcee0505);
	needlePaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000);
	needlePaint.setStyle(Paint.Style.FILL);

Es liegt an den float Werten die ich angeben und dem skalieren. Nur weiss ich nicht wo dort der Fehler ist.
 
Geht es denn besser, wenn du alles um den Faktor 100 skalierst?

ADD: ... also das ganze so skalierst, dass 100.0 der vollen Breite entsprechen müsste.
 
Zuletzt bearbeitet:
Das mit dem Skalieren hab ich noch nicht ausprobiert.

Was ich aber heute festgestellt hab, im Emulator wird alles richtig gezeichnet, nur auf dem Tablet nicht.
 
jetzt wird es mysteriös. :confused2:

Und der Emulator hatte auch Android 4.x?
 
Das finde ich auch ;)
Beide Geräte, also Tablet und Emulator haben API-Level 15, somit Android 4.0.3.

Jetzt hab ich zum Testen einfach mal ein neues Projekt ebenfalls für API-Level 15 erstellt und nur eine einzige Customview hinzugefügt. Die Customview hab ich in Layout auf wrap_Content gesetzt.

Hier ist der Code womit ich getestet habe:

PHP:
package canvastest.test;

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

public class Custom extends View {

	public Custom(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public Custom(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public Custom(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Paint p = new Paint();
		p.setColor(Color.BLUE);
		//canvas.scale(100, 100);
		canvas.scale(getWidth(), getHeight());
		canvas.drawCircle(0.5f, 0.5f, 0.25f, p);
	}
}

Ich hab auch mal mit dem Faktor 100 skaliert, beides hat auf dem Emulator super funktioniert nur auf dem Tablet ist nichts vom dem Kreis / Elipse zu sehen.
 
Also bei mir (Acer Iconia auf ICS) funktioniert dein Code problemlos.
Was immer der Fehler ist: Es liegt nicht an dem Code, den du hier gezeigt hast.

ADD: Was liefern denn auf dem Tablet getWidth() und getHeight() für Werte?
 
Zuletzt bearbeitet:
Tablet und dessen Canvas sind gleichgroß und zwar: 1280 * 677.
Emulator und dessen Canvas sind unterschiedlich groß, der Emulator hat 1280*677, wobei das Canvas aber 1280*752 hat.

Könnte es daran liegen?

Nur um sicher zu gehen das auch der Rest stimmt.
Meine Main.xml
PHP:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <canvastest.test.Custom
        android:id="@+id/custom1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

und die AndroidManifest.xml
PHP:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="canvastest.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".CanvasTestActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
 
Zuletzt bearbeitet:
Mach mal fill_parent statt wrap_content bei deinem View.

Dein View hat keinen Content und gibt sich dann selbst die Breite 0 (es ist allerdings interessant, dass das Emulator und Tablet unterschiedlich machen).
 
Zuletzt bearbeitet:
Habs jetzt mal mit "fill_parent" und auch mal mit "match_parent" versucht.
Beides hatte keine Auswirkungen. Am Emulator gehts am Tablet nicht.
 
Noch möglich:

* Du machst was in deiner Main Activity falsch.
* Du startest die falsche (alte=kaputte) App auf dem Tablet.
 
Hab das Tablet sogar schon auf Werkseinstellungen gemacht. Auch das App von Hand deinstalliert und neu ausgeführt, kein Unterschied.

An der MainActivity hab ich nicht viel gemacht:

PHP:
package canvastest.test;

import android.app.Activity;
import android.os.Bundle;

public class CanvasTestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
 
Eine Idee hab ich noch: hast du neben dem layouts Verzeichnis irgendein anderes? "layout-schlagmichtot" oder sowas?
 
Ein anderes Layout Verzeichnis hab ich ebenfalls nicht.
Im Moment hab ich jedoch ein ganz anderes Problem und zwar läuft der Emulator nicht mehr. Ich hatte die SDK und das ADT-Plugin auf den neuesten Stand gebracht und seit dem gibts nur noch :
HTML:
Failed to allocate memory: 8
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Hab dem AVD auch mal 512MB RAM gegeben, nur hilft das auch nicht.
Das Problem tritt auch nur mit der Auflösung: WXGA800 auf.
 

Ähnliche Themen

M
  • MikelKatzengreis
Antworten
5
Aufrufe
116
swa00
swa00
5
Antworten
22
Aufrufe
1.414
590239
5
G
Antworten
8
Aufrufe
1.191
gnome2012
G
Zurück
Oben Unten