Avoid layout to be resized on margin changed - android

I'm programmatically changing the margin of a layout inside a framelayout. My goal is to make a sliding view like the Facebook app. Is it possible to avoid this layout to be resized? This is my layout moving:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#00a2ff"
android:gravity="center_vertical"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:id="#+id/ivGPSSearching"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:src="#drawable/actionbar_gps_searching" />
</LinearLayout>
<ImageView
android:id="#+id/ivStarsFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="#drawable/actionbar_star" />
</LinearLayout>
I don't want the left LinearLayout to be resized. I hope you will understand what I want :)
Thanks

To achieve something similar we extended a HorizontalScrollView - just overriding onInterceptTouchEvent and onTouchEvent to always return false.
Then you just need to put your menu in the left side and the content on the right (the content must match the screen width).
Finally setup the initial HorizontalScrollView scroll and bind to a button click a event to change the scroll position(horizontalScrollView.scrollTo or horizontalScrollView.smoothScrollTo).
I hope this helps.

The below is an example code for using TranslateAnimation and set listener for the animation and in
#Override
public void onAnimationEnd(Animation animation)
{
//Just set the layout params for your view (layout) which is animated,
//to make your view shift to the new position
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutWidth, LayoutHeight);
params.leftMargin = 100; //for example you want to shift 100 px from left
params.rightMargin = -Layoutwidth; //this will avoid your view
//from shrinking and make it as wide as its width was, and - negative value will
//move it towards right
otherLayout.setLayoutParams(params);
}
I hope it make you people clear how to move your view after animation

I've been scratching my head around this for the last few hours as well.
Turns out that if you change both opposite margins, the views inside the ReleativeLayout will not be resized nor moved around:
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.setMargins(0, - yOffset, Integer.MIN_VALUE, yOffset);
This is crazy but it works...

Related

Android change gravity programmatically

I have this layout:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:gravity="left" />
<TextView
android:id="#+id/button_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="40dp" />
</LinearLayout>
Now, I want to modify gravity of the ImageView to left and gravity of the TextView to right. All other values present in xml (width, height, ...) must be preserved.
I tried:
1) setGravity method. Unfortunately, ImageView doesn't have this method. Why?
2)
LinearLayout.LayoutParams iconLayoutParams = new LinearLayout.LayoutParams(icon.getWidth(), icon.getHeight());
iconLayoutParams.gravity = Gravity.LEFT;
This somehow destroys View's dimensions
3)
android.view.ViewGroup.LayoutParams iconLayoutParams = icon.getLayoutParams();
This doesn't have gravity property.
(how is that even possible that icon.setLayoutParams() accepts layout parameters where gravity can be set and icon.getLayoutParams return some different kind of layout params without gravity property? That is a mess)
Can you please help me with that?
I think the easiest way to sort this out is using the 3rd approach but modify it slightly.
LinearLayout.LayoutParams iconLayoutParams = (LinearLayout.LayoutParams) icon.getLayoutParams();
And then do:
iconLayoutParams.gravity = Gravity.LEFT;
Reason LayoutParams itself does not have Gravity is that not all containers have gravity. LinearLayout does, so you need to cast to LinearLayout.LayoutParams since you surely know that your container is LinearLayout. And the method getLayoutParams is in the View class so it must return the parent of all other LayoutParams, which again, does not have to have Gravity.
I hope I explained properly :)

Edit position of an Android button created with a linearLayout

I am trying to dynamically create buttons, and they will be of varying size and in varying positions.
I have the code to create a button of varying size, but I am stuck on changing the position.
I am using linearlayout and am trying to use setMargins to move the button around, but it seems to be changing the margin within the button. My code is as follows:
public void button(int a, int b) {
newButton = new Button(this);
newButton.setText("HELLO");
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 0, 0);
ViewGroup.LayoutParams params = layout.getLayoutParams();
params.width = a;
params.height = b;
layout.requestLayout();
layout.addView(newButton, layoutParams);
}
Here is my manifest for this bit:
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_marginTop="58dp"
android:layout_toRightOf="#+id/textView1"
android:text="Button" />
<LinearLayout
android:id="#+id/layout"
android:layout_width="50sp"
android:layout_height="40sp"
android:orientation="vertical" >
</LinearLayout>
Do you understand what a LinearLayout is and why you're using it? Every child of the layout snaps in place. If I have a LinearLayout that's vertical and it has 3 children they will be on top of each other. I can change their gravity so they are attracted to different margins but to "change" its position is impossible depending on what you mean by "change".
Check out the other layouts. You may want to use a RelativeLayout.
Why donĀ“t you use button.setX(float x) and button.setY(float y)? You'll need to use RelativeLayout instead of the LinearLayout. It's more easy but it's only available since api 11...

Align a Button with an Image inside another Layout

Apologies for the confusing header. My problem is explained better in the following image:
I need the green Button to be aligned with the top of the Image, but the Image is inside another Layout. Is this possible?
It can be done in code if necessary; XML is not required. I am targeting Android 2.2 and newer.
EDIT:
My current implementation is to simply set the MarginTop-property of the Button, but this is inconvenient when I need to change the sizes of the text inside the LinearLayout, which I plan to do depending on the screen size.
I think it can be solved by somehow finding the Y coordinate of the Image, perhaps by adding the heights of the TextViews, and then setting this as the MarginTop for the Button, but this sounds cumbersome. Is there really no other option?
The LinearLayout is going to be placed inside a ViewPager (with multiple views, all having an image in the same position), which is why I can't do it the way preeya explains.
It's possible but more complicated than including the button into the same layout. If you definitely don't want to do that, you can't use XML (which is always faster). You have to do 3 steps in your code:
1.) Wait until the view is drawn
private void waitForViewToBeDrawn(){
// get your layout
final RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ViewTreeObserver vto = mainLayout.getViewTreeObserver();
// add a listener
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
// you also want to remove that listener
mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// go on to next step
getPositionOfImageView();
}
});
}
That approach works best for me, but if you have troubles - here are some alternatives.
There are also [more solutions][2] out there when you use API level 11 and higher...
2.) Get the top-position of your imageView
private void getPositionOfImageView(){
ImageView imageView = (ImageView) findViewById(R.id.imageView);
// Top position view relative to parent (Button and ImageView have same parent)
int topCoordinate = imageView.getTop();
adjustButton(topCoordinate);
}
3.) Add or adjust the button in order to be aligned with the image
public void adjustButton(int topCoordinate){
Button button = (Button) findViewById(R.id.button);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = topCoordinate;
button.setLayoutParams(params);
}
This step would be smoother by using API 11: button.setTop(topCoordinate)
Of course you can shorten all of it and put it in a singele method, just thought that 3 steps are better to explain. Hope that code helps to get started!
U can use linearlayout for displaying image & button as follows :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/longText"
android:gravity="center"
android:text="Some very long text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="#+id/subtitle"
android:layout_below="#+id/longText"
android:text="subtitle" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_below="#+id/subtitle"
android:layout_toLeftOf="#+id/subtitle"
android:layout_height="wrap_content"
android:text="button" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/button1"
android:layout_below="#+id/subtitle"
android:orientation="horizontal"
>
<ImageView
android:id="#+id/imageView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
</RelativeLayout>

Centering a custom view in a RelativeLayout using LayoutParams

I'm trying to center a custom view in relative layout. This image rotates so it needs to be in the center of the layout so it doesn't go out of the layout bounds. Right now its displaying in the top left corner. Here is my code:
container = (RelativeLayout) findViewById(R.id.lay_container);
bmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.charlie_sheen);
rotate_view = new RotationView(this, bmap);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
rotate_view.setLayoutParams(params);
container.addView(rotate_view);
Here is my relative xml layout
<RelativeLayout
android:id="#+id/lay_container"
android:layout_width="200dip"
android:layout_height="200dip"
android:layout_alignParentRight="true"
android:layout_below="#+id/txt_1"
android:layout_marginRight="45dp"
android:layout_marginTop="56dp"
android:padding="10dip" />
Do you have any ideas? I know that there is probably a simple solution to this problmem, but I can't seem to find the answer. Setting the LayoutParameter to center should center the view in the layour right?
Thanks in advance for any help or suggestions
Overall the code to add the custom view looks correct. This may be a weak suggestion, but to rule out any issues that may have been cause by the view customization you could try modifying the code in one of two ways.
Option 1: Use the explicit form of addRule(), i.e.
params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
Option 2: Use the explicit form of addView() and don't set the params on the view itself, i.e.
//Omit the line above this one
container.addView(rotate_view, params);
Beyond that, perhaps some insight into the custom view, specifically how it measures itself (it's not trying to fill parent is it)?
HTH
Ok Devunwired I will do that.
Here is how I am centering the image now.
1) I am centering the image in my canvas using a BitmapDrawable setGravity(Gravity.CENTER) property.
2) I'm centering the RotationView in my Relative Layout:
<RelativeLayout
android:id="#+id/image_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/txt_1"
android:layout_centerHorizontal="true" >
<com.mobicartel.acceldatatester.RotationView
android:id="#+id/rotate_view"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</RelativeLayout>
I'll add the background and let you know. (Right now the image isn't displaying at all. Sometimes you have to take a step backward to take two in the right direction!)

FrameLayout margin not working

My layout structure is like this
LinearLayout
FrameLayout
ImageView
ImageView
FrameLayout
TextView
LinearLayout
I have set margin's for the two ImageView which are inside FrameLayout. But FrameLayout margins are discarded and it always set's the Image to top left corner. If i change from FrameLayout to LinearLayout the margin's work properly. How to handle this ?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/inner1"
>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="24px"
android:layout_height="24px"
android:id="#+id/favicon"
android:layout_marginLeft="50px"
android:layout_marginTop="50px"
android:layout_marginBottom="40px"
android:layout_marginRight="70px"
/>
<ImageView
android:layout_width="52px"
android:layout_height="52px"
android:id="#+id/applefavicon"
android:layout_marginLeft="100px"
android:layout_marginTop="100px"
android:layout_marginBottom="100px"
android:layout_marginRight="100px"
/>
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/title"
android:layout_marginLeft="10px"
android:layout_marginTop="20px"
android:textColor="#FFFFFF"
android:textSize = "15px"
android:singleLine = "true"
/>
</LinearLayout>
I had the same issue myself and noticed that setting the layout_ margins does not work until you also set your ImageView's layout gravity i.e. android:layout_gravity="top" in the XML resource file, or from code: FrameLayout.LayoutParams.gravity = Gravity.TOP;.
To make it more clear why. The FrameLayout.onLayout() call contains this (in api v2.3.4 at least):
// for each child
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int gravity = lp.gravity;
if (gravity != -1) {
// handle all margin related stuff
So if gravity is -1, there will be no margin calculation. And the thing is, gravity in FrameLayout.LayoutParams is defined by:
gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1);
So if gravity is not set, there will be no margin calculation.
add your xml this attribute and re run
android:layout_gravity="top"
everything is Ok!
and you dont set new layout params like this;
FrameLayout.LayoutParams llp = new FrameLayout.LayoutParams(WallpapersActivity.ScreenWidth/2, layH);
use like this:
FrameLayout.LayoutParams llp = (LayoutParams) myFrameLay.getLayoutParams();
llp.height = 100;
llp.width = 100;
myFrameLay.setLayoutParams(llp);
Taken from the FrameLayout docs (link)
The size of the frame layout is the size of its largest child (plus padding), visible or not (if the FrameLayout's parent permits).
This seems to describe the fact that it'll strip margins out. Like boulder mentioned, you could try switching to padding as it can be used to produce a similar effect if done properly.
Out of curiosity, you mentioned that it does work fine when using a LinearLayout container, why the choice of FrameLayout?
Have you tried android:layout_gravity ? Try using android:padding in you ImageViews instead of android:layout_margin. AFAIK margins doesn't work properly on Frame layout. I even had to write custom layout for that purpose once. BTW, how do you want allign you ImageViews?
try setCropToPadding(true) to ImageView ,this should be helped!
you have to set your ImageView's layout gravity top i.e. android:layout_gravity="top" in the XML resource file, or from code: FrameLayout.LayoutParams.gravity = Gravity.TOP

Categories

Resources