I am creating a Camera application where I want to restrict the camera preview to be centered and around 60% of total size of the phone screen.
One way is to have the FrameLayout of Preview with padding so that the usable screen size is restricted , but I also want to show borders (around the corners) inside the restricted area which is not possible in this options.Also it not possible to show padding in percentage so that I can restrict user to 60% of screen size.
Other way is to have a image having a transparent center rectangular area and having border in inner rectangle corners . But I somehow need to restrict the FrameLayout of preview inside this rectangle which I am not able to do . Any suggestions on this option ?
Please also let me know if there are any other options .
Thanks.
Unless I don't fully understand your issues with using android:padding to provide space around your layout, you should be able to use android:layout_margin instead to accomplish the same goal but overcome the problems you mentioned. Adding padding creates space between the border of the View and its content. However, adding margin creates space between the border of the View and its parent, so the content still fills the View itself to the edges. However, you still can't define your view spacing in terms of percentage direct from XML...you would need to define the margin as static or apply the LayoutParams in Java code where you could calculate the required margin based on the current screen size.
Another option is to take advantage of the android:layout_weight property inside of a nested LinearLayout. The calculated weight sum could give you the 60% you're looking for directly in XML. Something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:weightSum="1.0" >
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.6"
android:gravity="center"
android:weightSum="1.0">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.6" />
</LinearLayout>
</LinearLayout>
Where the SurfaceView is the location of your Camera Preview, now centered with 20% of the screen on all sides. If you wanted to place things over or under this preview you would obviously want to place this entire block into a RelativeLayout or FrameLayout along with other components.
HTH!
Related
Now I know how to make the translateAnimation, in order to go through the picture, and show it on the screen.
What I do not know how to do, is put the picture on the screen, and make it in such a way so that it will not scale it by the scale type. So I can start the translateAnimation.
I saw some posts about this, and a lot of suggestions are saying I should use a HorrizontalScrollView, in order to put a picture bigger than the device screen. But I need to make a animation go thought it, and not for me to be able to move the picture, so in my opinion that might not be the perfect way to go.
Do you guys have any other suggestions?
Did not use a horrizontalScrollView, instead, forced the width of the whole layout to be the size of a picture, set a RelativeLayout inside, with the size of the screen, and then made the animations.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="1103dp"
android:layout_height="736dp"
android:background="#color/white">
<ImageView
android:id="#+id/background"
android:visibility="invisible"
android:src="#drawable/story1"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:id="#+id/screen_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
-----------------CODE inside relative layout for normal page--------
</RelativeLayout>
</RelativeLayout>
Then inside my code I set the screen width and height for my screen container (containing everything except the background picture which will translate):
screenContainer.setLayoutParams(new RelativeLayout.LayoutParams(Math.round(Constants.screenWidth), Math.round(Constants.screenHeight)));
This is my Translation for the ImageView that matches the parent (the size of the background pic):
TranslateAnimation translateBackground = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_PARENT,from,
TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.0f,
TranslateAnimation.RELATIVE_TO_PARENT,0.0f);
translateBackground.setDuration(15000);
background.setVisibility(View.VISIBLE);
background.startAnimation(translateBackground);
I have a complex xml layout with part of it being:
...
<FrameLayout
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_weight="1" >
<ImageView
android:id="#+id/flexible_imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#drawable/gradient"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingTop="8dp" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</FrameLayout>
...
The height of the FrameLayout #+id/parent must be determined at runtime because it is displayed above many other views, and they must be shown in the layout. This way the FrameLayout fills the remaining space perfectly (using height="0dp" and weight="1" properties).
The ImageView #+id/flexible_imageview receives an image from the network, and it always shows with the correct aspect ratio. This part is already ok as well. This View is the largest and should determine the size of the FrameLayout #+id/parent.
The problem is that when the image is drawn, the width of the FrameLayout #+id/parent is not adjusted to wrap and be the ImageView #+id/flexible_imageview as it should be.
Any help is appreciated.
-- update --
I've updated the layout to clarify some of the missing parts, and to add the reasoning behind all of it.
What I want is to have an Image (ImageView #+id/flexible_imageview) with unknown dimensions to have, on top of it, a gradient and some text on top of the gradient. I can't set the FrameLayout #+id/parent dimensions to both wrap_content because there is more Views after this Image that must be shown. If there's not enough space in the layout, the Image (ImageView #+id/flexible_imageview) is reduced until it all fits in the layout, but it should maintain its aspect ratio, and the gradient/texts on top of it.
The #drawable/gradient is just:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="270"
android:endColor="#aa000000"
android:startColor="#00000000" />
</shape>
-- update 2 --
I added two images below to demonstrate what's happening, and what should happen:
Bug:
Correct:
If would help if you explained more about what you are trying to accomplish in your layout (not the layout itself but what should the user see on the screen and what are the other elements in the layout).
A FrameLayout with multiple children is usually a "code smell". Usually, FrameLayouts should have only one child element. So this makes me wonder whether there is something wrong with your design.
-- Edit --
If I understand correctly, you are trying the framelayout to wrap the content of the image but at the same time match the space left from the other layout views before/after the frame layout.
What is the parent view/layout of the frame layout?
I see a couple of problems with this design or your explanation:
You have framelayout width set to match parent, but you want to wrap the content of the image.
You want the imageView to be reduced but you are not taking into account the text views in the linear layout. You have them set to wrap content. So when the fame layout is small, you will not see all the textviews. (Unless you are resizing them as well somehow).
Sorry if this isn't helpful enough but it's difficult to understand what you are trying to accomplish with this layout. A sample use-case would help in providing you a better recommendation.
When a dimension (width / height) is MeasureSpec.EXACTLY adjustViewBounds will not effect it.
In your case, having android:width="match_parent" ensures that the image view is the size of the parent, regardless of adjustViewBounds.
It works to begin with because the height is wrap_content - the height is adjusted when the image is scaled to fill the width.
When you override the height to fit everything on the screen (this may not be a great idea to begin with), the width is still matching the parent and doesn't get adjusted. However, because the scale type is ScaleType.FIT_CENTER the image is scaled and positioned so that the entirety of it fits in the bounds of the ImageView (and centred.. hence the name).
If you turn on the debug option for drawing layout bounds, or look at your app using hierarchyviewer, you'll see that the image view is still matching the width of its parent.
There are a couple of ways you could do what you want.
Since you're already manually calculating the height, setting the width shouldn't be that hard.
Drawable drawable = imageView.getDrawable();
if (drawable != null && drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0) {
int height = // however you calculate it
int width = height / (getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth());
}
You might also get away with
<ImageView
android:id="#+id/flexible_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:minWidth="9999dp" />
Even if this works, you probably wouldn't be able to use it in a horizontal LinearLayout using weights any more (for example, if you wanted a landscape variant of the layout), or a number of other scenarios.
I have an image like this used as background in a RelativeLayout:
This image is used as background for all the levels of my game. Every level is drawn onto the blue area.
I want to keep fixed the aspect-ratio of the blue area, changing the size of the red edges to avoid to show to the user unused pixels of their screen. The green area must be fixed to 80dp for all phones. Then I must add a View (a GLSurfaceView) in my layout in such a way that it fit perfectly the blue area. Thus all levels of my Android game will be perfectly the same in all Android device.
How can I solve this problem?
The real image that I use is a little more complex. You can look it here:
Real image
I would use a FrameLayout for the middle part of the screen(blue), add an ImageView, containing the BackgroundImage you want to display, and put the GLSurfaceView on top of it.
Since the aspect ratio is always the same, you could set the ImageViews sclaing to fit xy and the image should always look the same.
Lets assume you are using a simple SurfaceView, the xml code id use to put a ImageView begind it would look like this
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
As i dont know how you build your View i cant post the code that does the job, but just add a FrameLayout instead of your GLSurfaceView to your View, with the Same Dimensions, the GLSurfaceView would have.
To that FrameLayout first add the ImageView, then the GLSurfaceView. Both with height and width set to match_parent.
To Figure out the size of your SurfaceView...
Retrieve Display Dimensions
Substract Green Bar Dimensions
Calculate the size of the Blue View, get the Height/Width (whatever is bigger) calculate the missing Dimension
Set the Red Views to Occupie the empty space.
So you would have to do this programmatically :)
Ok here is the problem...
I have a image background that need some text and additional graphics on it. The background image needs to be in the center of the screen and may not stretch. Here is what i need to do:
The problem is that i need to align the text to the background image.
I've tried to wrap it all into a relative layout - something like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bg_image"
android:layout_centerInParent="true"
android:src="#drawable/member_card"/>
<TextView
android:layout_height="wrap_content"
android:layout_alignLeft="#id/bg_image"
android:text="#string/membercard_info"
android:layout_marginTop="40dp"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignLeft="#id/bg_image"
android:layout_marginTop="200dp"
/>
</RelativeLayout>
This will not work since android adds additional padding to the image to avoid it from stretching.
Here is what happens in two different cases:
So how do I align the text to the background image?
I've solved this problem in the past in code by baking it all into one image,- but would like to do this in xml.
If you want to remove padding, you can use manually set it. However, if you want overlapping elements, you generally want to use FrameLayout. Look here: http://mobile.tutsplus.com/tutorials/android/android-sdk_frame-layout/
Set a gravity inside the frame layout to align it.
if you want an ImageView with additional layers drawn on top of that, see this thread: How to maintain multi layers of ImageViews and keep their aspect ratio based on the largest one?
There a padding around the image because you set the imageView size to fill its parent ( using match_parent )
You should try to set it to wrap its content :
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.../>
EDIT : If your picture is bigger that the screen size, you need to have it scaled keeping the aspect ratio.
To do this, use match_parent in vertical with a scaleType to FIT_CENTER
and keep the wrap_content setting for the width ( since we want the image view left/right bounds stuck to the image content )
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="fitCenter"
.../>
Is this better ?
I am using relative layout to superimpose one smaller image on top of a larger one.
I want the bottom-right corner of the smaller image to coincide with B-R corner of the larger image. I'm using margin parameters in my layout XML (specifying measurement in dips) but this doesn't seem to work for all devices and resolutions - in some cases the small image is shifted by 4-5px from the border.
Is it possible to specify the position of the smaller image without pixel values? I.e. with gravity or something?
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/big_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/bigimage"/>
<ImageView
android:id="#+id/little_image"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_alignRight="#id/big_image"
android:layout_alignBottom="#id/big_image"
android:src="#drawable/littleimage"/>
</RelativeLayout>
Nice thing about RelativeLayout is that you can use relative positions and dimensions, instead of using specific dips or pixels. In the case above, I just played with the android:layout_align* parameters, to make sure that both images are aligned. Keep in mind that I set a specific dimension of the little image, but you can change that to fit your needs.