I am wondering in which way Android draws views on the screen inside layout views with defined android:layout_width
and android:layout_height
values in pixels.
I am using Android class view extends android.view.SurfaceView
. It is just MjpegView
to display MJPEG stream from the camera on the Android app. I am working with this code (with some small changes): Android ICS and MJPEG using AsyncTask
This MjpegView
class is placed inside the RelativeLayout
. MjpegView
object is added programmatically and this RelativeLayout
has attributes defined in this way:
android:layout_width="800px"
android:layout_height="600px"
This size values is necessary for this application so I can't change them. Application is working only in landscape orientation. My MjpegView
need to be set 320 x 240
pixels size inside RelativeLayout (800 x 600 px)
. My application enlarges this RealtiveLayout
to fill the screen on the current device. And this is a problem connected also with the streaming MJPEG. I am working on Nexus 7 (2012 version), which has 1280 x 800
resolution.
To get the real size of this view inside layout I have to measured the height of the Nexus 7 screen without action and navigation bars. To get this I have used this method inside one 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();
}
}
I am getting 703
value as the measuredActivityHeight
of the running Activity. So to get the ratio in which Android translates 320 x 240 px
inside 800 x 600 px
to the dp
value on the screen I have written this method:
public int calculateForCurrentScreen(float pixelValue) {
float ratio = PageActivity.measuredActivityHeight / 600f;
int result = (int) (pixelValue * ratio);
return result;
}
So for the 320 x 240 px
on the Nexus 7 I am getting 374 x 281
. And to get MjpegView
in this size I need to use this method inside the MjpegView
class:
public void setResolution(int width, int height) {
holder.setFixedSize(width, height);
}
And the size of the streaming view is in the wanted size. But this view has additional black areas. So in fact the whole view (camera stream + black areas on the its bottom and right side) has 440 x 328
size.
I have checked that Rect
object in MjpegView
is drawing with 374 x 281
size so it is OK. SurfaceHolder
and Canvas
also have this size. Bitmap
object has 320 x 240
size, but this is OK because Bitmap
object is from camera stream. And it is resized to the wanted size.
Problem disappear (there is no black areas and MjpegView
is in correct position and size relative to other views) when I have switched RelativeLayout
to the 800dp x 600dp
size and invoke setResolution(320, 240)
for the MjpegView
object. But the whole layout is in this moment too big.
EDIT
Thanks @mathiash for your comment. I have just uploaded screenshot from Nexus 7 (2012 edition) to show you my problem.
As you can see, the green area is the RelativeLayout
with defined 800 x 600 px
size. To get MJPEG stream from the http://trackfield.webcam.oregonstate.edu/
. I have used this URL: http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=320x240
.
For this screenshot I have invoked setResolution(320, 240)
method. And black area has 374 x 281
and video stream 320 x 240
.
For this screenshot I have invoked setResolution(374, 281)
method. And black area is much bigger and video stream is 374 x 281
. And in this case video stream has correct size but this black area is unnecessary.