[英]Why does Android draw View inside another (with width and height defined in pixels) in incorrect way?
我想知道Android以哪種方式在布局視圖中的屏幕上繪制視圖,其中定義了android:layout_width
和android: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
大小繪制的,所以沒關系。 SurfaceHolder
和Canvas
也有這個尺寸。 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=320x240
: http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=320x240
。
對於此屏幕截圖,我調用了setResolution(320, 240)
方法。 黑色區域有374 x 281
,視頻流320 x 240
。
對於此屏幕截圖,我調用了setResolution(374, 281)
方法。 黑色區域更大,視頻流為374 x 281
。 在這種情況下,視頻流的大小正確,但這個黑色區域是不必要的。
正如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.