Question

I want to add a view inside a FrameLayout programmatically and to place it in a specific point within the layout with a specific width and height. Does FrameLayout support this? If not, should I use an intermediate ViewGroup to achieve this?

int x; // Can be negative?
int y; // Can be negative?
int width;
int height;
View v = new View(context);
// v.setLayoutParams(?); // What do I put here?
frameLayout.addView(v);

My initial idea was to add an AbsoluteLayout to the FrameLayout and place the view inside the AbsoluteLayout. Unfortunately I just found out that AbsoluteLayout is deprecated.

Any pointers will be much appreciated. Thanks.

Was it helpful?

Solution

It's true that with FrameLayout all children are pegged to the top left of the screen, but you still have some control with setting their padding. If you set different padding values to different children, they will show up at different places in the FrameLayout.

OTHER TIPS

The following example (working code) shows how to place a view (EditText) inside of a FrameLayout. Also it shows how to set the position of the EditText using the setPadding setter of the FrameLayout (everytime the user clicks on the FrameLayout, the position of the EditText is set to the position of the click):

public class TextToolTestActivity extends Activity{
    FrameLayout frmLayout;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        frmLayout = (FrameLayout)findViewById(R.id.frameLayout1);
        frmLayout.setFocusable(true);
        EditText et = new EditText(this);

        frmLayout.addView(et,100,100);
        frmLayout.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.i("TESTING","touch x,y == " + event.getX() + "," +     event.getY() );
                frmLayout.setPadding(Math.round(event.getX()),Math.round(event.getY()) , 0, 0);
            return true;
        }
    });

}

}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <FrameLayout 
        android:id="@+id/frameLayout1" 
        android:layout_height="fill_parent" android:layout_width="fill_parent">
    </FrameLayout>

</LinearLayout>

You can also add a margin around the newly added view to position it inside the FrameLayout.

FrameLayout frameLayout = (FrameLayout) findViewById(R.id.main); // or some other R.id.xxx
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(0, metrics.heightPixels - 20, 0, 0);
View v = new View(context);
v.setLayoutParams(params);
frameLayout.addView(v);

This will position the FrameLayout 20 pixels from the bottom of the screen.

Edit: completed the example so it stands by itself. And oh, yes it does work.

From the link Quinn1000 provided:

You can add multiple children to a FrameLayout, but all children are pegged to the top left of the screen.

This means you can't put your View at a specific point inside the FrameLayout (except you want it to be at the top left corner :-)).

If you need the absolute positioning of the View, try the AbsoluteLayout:

A layout that lets you specify exact locations (x/y coordinates) of its children. Absolute layouts are less flexible and harder to maintain than other types of layouts without absolute positioning.

As for setting the width and height of the View, also like Quinn1000 said, you supply the v.setLayoutParams() method a LayoutParams object, depending on the container you chose (AbsoluteLayout, LinearLayout, etc.)

The thread here on stackOverflow at

How do you setLayoutParams() for an ImageView?

covers it somewhat.

For instance: LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(30, 30); yourImageView.setLayoutParams(layoutParams);

implies that you need to be defining a LinearLayout.LayoutParams (or in your case a FrameLayout.layoutParams) object to pass to the setLayoutParams method of your v object.

At

http://developer.android.com/reference/android/widget/FrameLayout.html

it almost makes it looks like you could ask your v to:

generateDefaultLayoutParams () via this method if you have not defined the parameters specifically.

But it's late, and those links are making my eyes bleed a little. Let me know if they nhelp any :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top