2014-06-09 5 views
6

Ich frage mich, auf welche Weise Android Ansichten auf dem Bildschirm in Layout-Ansichten mit definierten android:layout_width und android:layout_height Werte in Pixeln zeichnet.Warum zeichnet Android View in einem anderen (mit in Pixel definierten Breite und Höhe) falsch auf?

Ich verwende Android-Klasse Ansicht erweitert android.view.SurfaceView. Es ist nur MjpegView, um MJPEG Stream von der Kamera auf der Android App anzuzeigen. Ich arbeite mit diesem Code (mit einigen kleinen Änderungen): Android ICS and MJPEG using AsyncTask

Diese MjpegView Klasse ist innerhalb der RelativeLayout platziert. MjpegView Objekt hinzugefügt wird programmatisch und diese RelativeLayout hat Attribute auf diese Weise definiert:

android:layout_width="800px" 
android:layout_height="600px" 

Diese Größenwerte für diese Anwendung erforderlich ist, so kann ich sie nicht ändern. Die Anwendung funktioniert nur im Querformat. Meine MjpegView müssen 320 x 240 Pixel Größe innerhalb RelativeLayout (800 x 600 px) gesetzt werden. Meine Anwendung vergrößert diese RealtiveLayout, um den Bildschirm des aktuellen Geräts zu füllen. Und das ist ein Problem, das auch mit dem Streaming MJPEG verbunden ist. Ich arbeite an Nexus 7 (Version 2012), die 1280 x 800 Auflösung hat.

Um die tatsächliche Größe dieser Ansicht im Layout zu erhalten, muss ich die Höhe des Nexus 7-Bildschirms ohne Aktions- und Navigationsleisten messen. Um dies ich diese Methode in einem Activity verwendet haben:

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 
    RelativeLayout parentLayout = (RelativeLayout) findViewById(R.id.parent_layout); 
    if (parentLayout != null && isLandscape) { 
     this.measuredActivityHeight = parentLayout.getBottom(); 
    } 
} 

Ich erhalte 703 Wert als measuredActivityHeight der Laufaktivität. Also um das Verhältnis zu erhalten, in dem Android übersetzt 320 x 240 px innerhalb 800 x 600 px, um den dp Wert auf dem Bildschirm ich diese Methode geschrieben habe:

public int calculateForCurrentScreen(float pixelValue) { 
    float ratio = PageActivity.measuredActivityHeight/600f; 
    int result = (int) (pixelValue * ratio); 
    return result; 
} 

Also für die 320 x 240 px auf dem Nexus 7 I 374 x 281 bin immer. Und um MjpegView in dieser Größe brauche ich in der MjpegView Klasse diese Methode zu verwenden:

public void setResolution(int width, int height) { 
    holder.setFixedSize(width, height); 
} 

und die Größe der Streaming-Ansicht ist in der gewünschten Größe. Aber diese Ansicht hat zusätzliche schwarze Bereiche. In der Tat hat die gesamte Ansicht (Kamerastrom + schwarze Bereiche auf der unteren und rechten Seite) 440 x 328 Größe.

Ich habe überprüft, dass Rect Objekt in MjpegView Zeichnung mit 374 x 281 Größe ist, so ist es in Ordnung. SurfaceHolder und Canvas haben auch diese Größe. Bitmap Objekt hat 320 x 240 Größe, aber das ist OK, weil Bitmap Objekt aus Kamerastrom ist. Und es wird auf die gewünschte Größe angepasst.

Problem verschwinden (es keine schwarzen Flächen ist und MjpegView ist in der richtigen Position und Größe im Vergleich zu anderen Ansichten), wenn I RelativeLayout zur 800dp x 600dp Größe und rufen setResolution(320, 240) für das Objekt MjpegView eingeschaltet habe. Aber das ganze Layout ist in diesem Moment zu groß.

EDIT

Dank @mathiash für Ihren Kommentar. Ich habe gerade einen Screenshot von Nexus 7 (Ausgabe 2012) hochgeladen, um Ihnen mein Problem zu zeigen.

Wie Sie sehen können, ist der grüne Bereich der RelativeLayout mit definierter 800 x 600 px Größe. Um MJPEG-Stream von der http://trackfield.webcam.oregonstate.edu/ zu bekommen. Ich habe diese URL verwendet: http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=320x240.

Für diesen Screenshot habe ich setResolution(320, 240) Methode aufgerufen. Und schwarze Fläche hat 374 x 281 und Videostream 320 x 240.

320x240

Für diesen Screenshot ich setResolution(374, 281) Methode aufgerufen haben. Und schwarze Fläche ist viel größer und Video-Stream ist 374 x 281. Und in diesem Fall hat der Videostream die richtige Größe, aber dieser schwarze Bereich ist nicht notwendig.

374x281

+0

Tut mir leid, ich habe Ihre Frage verpasst – pskink

+1

Diese Frage ist interessant, aber, es tut mir leid zu sagen, eher schwer zu verstehen. :/Vielleicht wäre ein Screenshot nützlich? – matiash

+0

@matiash danke für deinen Kommentar, ich habe meine Frage mit den Sreenshots aktualisiert – woyaru

Antwort

2

Als Levente Kurusa vorgeschlagen, eine virtuelle Pixeleinheit wie dp verwendet, kann Ihr Problem lösen. Wir sollten es vermeiden, px direkt zu verwenden.

+0

Wie ich im Kommentar zur mu Frage erwähnt habe: Ich habe es mit '800 x 600 probiert dp' Größe auch. Und es sieht OK aus (ohne schwarzen Bereich), aber meine App unterstützt das Zoomen mit zwei Fingern, und das Zoomen bewirkt, dass dieser schwarze Bereich ebenfalls erscheint ... - also ist die Verwendung von dp oder Pixel keine Lösung. Ich suche nach einer Lösung, wie man die Größe der Ansicht, die 'SurfaceView' erweitert, komplex einstellt – woyaru

1

dp nicht verwenden, auch dp ändert sich mit verschiedenen Bildschirmen. Stattdessen habe ich gelernt, meine eigene Wert-Zeit-Dichte zu verwenden. Verwenden Sie also DisplayMetrics metrics = getResources(). GetDisplayMetrics(); und metrics.getDensity() * 50 zum Beispiel. Versuchen Sie auch, Gewichte zu verwenden, um sie in verschiedenen Bildschirmen relativ zu halten.

0

können Sie mit versuchen

whateveryourvideoname.setDisplayMode(MjpegView.SIZE_BEST_FIT) 

, um die am besten passende Ihrer inputstream (mit der Auflösung, die Sie vorher einrichten) in der Layout-Ansicht zu machen.


Aber all das macht keinen Sinn, wenn Sie Ihre Mjpegview in der layout.xml Datei mit der gleichen Größe wie die Auflösung des Quellbildes definiert haben, so dass der beste Weg ist, den setResolution Befehl zu überspringen und einfach verwenden,

whateveryourvideoname.setDisplayMode(MjpegView.SIZE_FULLSCREEN) 

und Ihr Bild passt perfekt in Ihr MjpegView-Display.

Verwandte Themen