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

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

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von chillout, 29.07.2012.

  1. chillout, 29.07.2012 #1
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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.5f0.5f 0.2f);
        
    pfad.lineTo(0.5f 0.010f0.5f 0.2f 0.007f);
        
    pfad.lineTo(0.5f 0.002f0.5f 0.32f);
        
    pfad.lineTo(0.5f 0.002f0.5f 0.32f);
        
    pfad.lineTo(0.5f 0.010f0.5f 0.2f 0.007f);
        
    pfad.lineTo(0.5f0.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(scalescale);
    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.
     
  2. DieGoldeneMitte, 29.07.2012 #2
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    Dein Code beinhaltet keinen Befehl (canvas.drawPath(...)), der den Pfad zeichnet. Ist es vielleicht das?
     
  3. chillout, 29.07.2012 #3
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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: 29.07.2012
  4. DieGoldeneMitte, 30.07.2012 #4
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    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?
     
  5. chillout, 30.07.2012 #5
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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(scalescale);
            
    canvas.drawPath(needlePathneedlePaint);
            
    canvas.restore();
        }
    Die Größe der View sollte mit onMeasure korrekt gesetzt werden. Hier meine OnMeasure:
    PHP:
        protected void onMeasure(int widthMeasureSpecint 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(widthheight);
            if (
    widthMode == MeasureSpec.UNSPECIFIED
                    
    || heightMode == MeasureSpec.UNSPECIFIED) {
                
    size 200;
            }
            
    setMeasuredDimension(sizesize);
        }
     
  6. DieGoldeneMitte, 30.07.2012 #6
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    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?
     
  7. chillout, 31.07.2012 #7
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    Die Farbe hab ich so definiert:
    PHP:
        needlePaint = new Paint();
        
    needlePaint.setAntiAlias(true);
        
    needlePaint.setColor(0xfcee0505);
        
    needlePaint.setShadowLayer(0.01f, -0.005f, -0.005f0x7f000000);
        
    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.
     
  8. DieGoldeneMitte, 31.07.2012 #8
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    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: 01.08.2012
  9. chillout, 01.08.2012 #9
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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.
     
  10. DieGoldeneMitte, 01.08.2012 #10
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    jetzt wird es mysteriös. :confused2:

    Und der Emulator hatte auch Android 4.x?
     
  11. chillout, 01.08.2012 #11
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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 contextAttributeSet attrs) {
            
    super(contextattrs);
        }

        public 
    Custom(Context contextAttributeSet attrsint defStyle) {
            
    super(contextattrsdefStyle);
        }
        
        @
    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.5f0.5f0.25fp);
        }
    }
    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.
     
  12. DieGoldeneMitte, 01.08.2012 #12
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    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: 01.08.2012
  13. chillout, 02.08.2012 #13
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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: 02.08.2012
  14. DieGoldeneMitte, 02.08.2012 #14
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    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: 02.08.2012
  15. chillout, 02.08.2012 #15
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    Habs jetzt mal mit "fill_parent" und auch mal mit "match_parent" versucht.
    Beides hatte keine Auswirkungen. Am Emulator gehts am Tablet nicht.
     
  16. DieGoldeneMitte, 02.08.2012 #16
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    Noch möglich:

    * Du machst was in deiner Main Activity falsch.
    * Du startest die falsche (alte=kaputte) App auf dem Tablet.
     
  17. chillout, 02.08.2012 #17
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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);
        }
    }
     
  18. DieGoldeneMitte, 03.08.2012 #18
    DieGoldeneMitte

    DieGoldeneMitte Android-Lexikon

    Beiträge:
    1,230
    Erhaltene Danke:
    256
    Registriert seit:
    05.02.2010
    Phone:
    Nexus 5X
    Tablet:
    Nexus 7 (2013)
    Eine Idee hab ich noch: hast du neben dem layouts Verzeichnis irgendein anderes? "layout-schlagmichtot" oder sowas?
     
  19. chillout, 09.08.2012 #19
    chillout

    chillout Threadstarter Junior Mitglied

    Beiträge:
    32
    Erhaltene Danke:
    0
    Registriert seit:
    26.11.2010
    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.
     

Diese Seite empfehlen