簡體   English   中英

為什么Android以不正確的方式將View繪制在另一個內(以像素為單位定義寬度和高度)?

[英]Why does Android draw View inside another (with width and height defined in pixels) in incorrect way?

我想知道Android以哪種方式在布局視圖中的屏幕上繪制視圖,其中定義了android:layout_widthandroid:layout_height值(以像素為單位)。

我正在使用Android類視圖擴展android.view.SurfaceView 只需MjpegView即可在Android應用中顯示來自相機的MJPEG流。 我正在使用此代碼(進行一些小的更改): 使用AsyncTask的Android ICS和MJPEG

這個MjpegView類放在RelativeLayout MjpegView編程方式添加MjpegView對象,此RelativeLayout具有以這種方式定義的屬性:

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

此大小值對於此應用程序是必需的,因此我無法更改它們。 應用程序僅適用於橫向。 我的MjpegView需要在RelativeLayout (800 x 600 px)內設置320 x 240像素大小。 我的應用程序放大此RealtiveLayout以填充當前設備上的屏幕。 這也是與流媒體MJPEG相關的問題。 我正在研究Nexus 7(2012版),其分辨率為1280 x 800

要在布局內獲得此視圖的實際大小,我必須測量Nexus 7屏幕的高度而不需要操作和導航欄。 為了得到這個,我在一個Activity使用了這個方法:

@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();
    }
}

我得到703值作為正在運行的Activity的measuredActivityHeight 因此,要獲得Android在800 x 600 px內將320 x 240 px轉換為屏幕上的dp值的比率,我已經編寫了此方法:

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

所以對於Nexus 7上的320 x 240 px ,我得到了374 x 281 要獲得此大小的MjpegView ,我需要在MjpegView類中使用此方法:

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

並且流視圖的大小是所需大小。 但這種觀點還有其他黑色區域。 所以實際上整個視圖(相機流+底部和右側的黑色區域)大小為440 x 328

我已經檢查過MjpegView中的Rect對象是用374 x 281大小繪制的,所以沒關系。 SurfaceHolderCanvas也有這個尺寸。 Bitmap對象的大小為320 x 240 ,但這是正常的,因為Bitmap對象來自相機流。 並將其調整為所需大小。

當我將RelativeLayout切換到800dp x 600dp大小並調用MjpegView對象的setResolution(320, 240) 800dp x 600dp )時,問題消失(沒有黑色區域, MjpegView相對於其他視圖的位置和大小正確setResolution(320, 240) 但整個布局在這個時刻太大了。

編輯

感謝@mathiash的評論。 我剛剛從Nexus 7(2012年版)上傳截圖,向您展示我的問題。

如您所見,綠色區域是RelativeLayout ,定義為800 x 600 px大小。 http://trackfield.webcam.oregonstate.edu/獲取MJPEG流。 我使用過這個URL: http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=320x240http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=320x240

對於此屏幕截圖,我調用了setResolution(320, 240)方法。 黑色區域有374 x 281 ,視頻流320 x 240

320×240

對於此屏幕截圖,我調用了setResolution(374, 281)方法。 黑色區域更大,視頻流為374 x 281 在這種情況下,視頻流的大小正確,但這個黑色區域是不必要的。

374x281

正如Levente Kurusa建議的那樣,使用像dp這樣的虛擬像素單元可以解決您的問題。 我們應該避免直接使用px。

不要使用dp,甚至dp會隨着不同的屏幕而變化。 相反,我學會了使用自己的價值倍密度。 因此,使用DisplayMetrics metrics = getResources()。getDisplayMetrics(); 和metrics.getDensity()* 50例如。 還嘗試使用權重來保持它們在不同屏幕中的相對性。

你可以試試

whateveryourvideoname.setDisplayMode(MjpegView.SIZE_BEST_FIT)

為了在布局視圖中最好地擬合您的輸入inputstream (使用之前設置的分辨率)。


但是如果你在layout.xml文件中定義了與源圖像分辨率相同的Mjpegview ,那么這一切都沒有意義,所以最好的方法是跳過setResolution命令並使用

whateveryourvideoname.setDisplayMode(MjpegView.SIZE_FULLSCREEN)

並且您的圖像將完美地適合您的MjpegView顯示屏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM