Android center view in FrameLayout doesn't work

AndroidAndroid LayoutAndroid FramelayoutGravity

Android Problem Overview


I have a FrameLayout in which I have 2 controls:

  • a custom view which draws a image and some text on it
  • a textview with a text

I want to center both in the FrameLayout but I can't manage to do it. The Texview is centered just fine, my cusom view remains on the left side, when I make it visible.

<FrameLayout android:id="@+id/CompassMap"
               android:layout_width="fill_parent" 
               android:layout_height="wrap_content"
               android:layout_weight="1"
               android:gravity="center">

             <view class="com.MyView"
        android:id="@+id/myView"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal"
        android:visibility="gone"/>

                <TextView android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal"
        android:text="CENTERED" /> 
</FrameLayout>

To Mathias, I don't do anything in the constructor, it's just simple

   public class MyMapView extends View {

private int xPos = 0; 
private int yPos = 0;
private Bitmap trackMap;

private Matrix backgroundMatrix;
private Paint backgroundPaint;

private Bitmap position;
private Matrix positionMatrix;
private Paint positionPaint;

public MyMapView(Context context) {
	super(context);
	init(context, null);
}

public MyMapView(Context context, AttributeSet attrs) {
	super(context, attrs);
	init(context, attrs);
}

public MyMapView(Context context, AttributeSet attrs, int defStyle) {
	super(context, attrs, defStyle);
	init(context, attrs);
}

private void init(final Context context, AttributeSet attrs) {
	
backgroundMatrix = new Matrix();
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);

position = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position);
positionMatrix = new Matrix();

positionPaint = new Paint();
positionPaint.setFilterBitmap(true);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}

@Override
protected void onDraw(Canvas canvas) {
   
	int width = getMeasuredWidth();
	int height = getMeasuredHeight();

	if (trackMap!=null)
	{
		Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMap, height, height, true);
		canvas.drawBitmap(resizedBitmap, backgroundMatrix, backgroundPaint);
		
	}
	
	    canvas.save(Canvas.MATRIX_SAVE_FLAG);
		canvas.translate(xPos-position.getWidth()/2, yPos-position.getHeight()/2);
		canvas.drawBitmap(position, positionMatrix, positionPaint);
		
	    canvas.restore();
}

	public void updatePosition(int xpos, int ypos, Bitmap trackImage)
	{
		xPos=xpos;
		yPos=ypos;
		trackMap = trackImage;
		invalidate();
	}
}

Android Solutions


Solution 1 - Android

We can align a view in center of the FrameLayout by setting the layout_gravity of the child view.

In XML:

android:layout_gravity="center"

In Java code:

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;

Note: use FrameLayout.LayoutParams not the others existing LayoutParams

Solution 2 - Android

I'd suggest a RelativeLayout instead of a FrameLayout.

Assuming that you want to have the TextView always below the ImageView I'd use following layout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">
	<ImageView
		android:id="@+id/imageview"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_alignParentTop="true"
		android:layout_centerInParent="true"
		android:src="@drawable/icon"
		android:visibility="visible"/>
	<TextView
		android:id="@+id/textview"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_centerInParent="true"
		android:layout_below="@id/imageview"
		android:gravity="center"
		android:text="@string/hello"/>
</RelativeLayout>

Note that if you set the visibility of an element to gone then the space that element would consume is gone whereas when you use invisible instead the space it'd consume will be preserved.

If you want to have the TextView on top of the ImageView then simply leave out the android:layout_alignParentTop or set it to false and on the TextView leave out the android:layout_below="@id/imageview" attribute. Like this.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">
	<ImageView
		android:id="@+id/imageview"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_alignParentTop="false"
		android:layout_centerInParent="true"
		android:src="@drawable/icon"
		android:visibility="visible"/>
	<TextView
		android:id="@+id/textview"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_centerInParent="true"
		android:gravity="center"
		android:text="@string/hello"/>
</RelativeLayout>

I hope this is what you were looking for.

Solution 3 - Android

##Just follow this order You can center any number of child in a FrameLayout.

<FrameLayout
    >
    <child1
        ....
        android:layout_gravity="center"
        .....
        />
    <Child2
        ....
        android:layout_gravity="center"
        />
</FrameLayout>

> ###So the key is adding android:layout_gravity="center"in the child views.

###For example:
I centered a CustomView and a TextView on a FrameLayout like this

> Code:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
    <com.airbnb.lottie.LottieAnimationView
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:layout_gravity="center"
        app:lottie_fileName="red_scan.json"
        app:lottie_autoPlay="true"
        app:lottie_loop="true" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="#ffffff"
        android:textSize="10dp"
        android:textStyle="bold"
        android:padding="10dp"
        android:text="Networks Available: 1\n click to see all"
        android:gravity="center" />
</FrameLayout>

> Result:

enter image description here

Solution 4 - Android

Set 'center_horizontal' and 'center_vertical' or just 'center' of the layout_gravity attribute of the widget

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MovieActivity"
    android:id="@+id/mainContainerMovie"
    >


    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#3a3f51b5"
       />

    <ProgressBar
        android:id="@+id/movieprogressbar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal" />
</FrameLayout>

Solution 5 - Android

To center a view in Framelayout, there are some available tricks. The simplest one I used for my Webview and Progressbar(very similar to your two object layout), I just added android:layout_gravity="center"

Here is complete XML in case if someone else needs the same thing to do

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context=".WebviewPDFActivity"
    android:layout_gravity="center"
    >
    <WebView
        android:id="@+id/webView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        />
    <ProgressBar
        android:id="@+id/progress_circular"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:visibility="visible"
        android:layout_gravity="center"
        />


</FrameLayout>

Here is my output

screenshot

Solution 6 - Android

Following https://stackoverflow.com/a/13025031/962916, this works for me to center a TabLayout inside FrameLayout.

enter image description here

final TabLayout tabLayout = new TabLayout(this);
// Configure TabLayout...
final FrameLayout tabLayoutContainer = new FrameLayout(this);
tabLayoutContainer.setBackgroundColor(Color.RED);

final FrameLayout.LayoutParams tabLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                dpToPx(28));
final FrameLayout.LayoutParams containerLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                dpToPx(48));


tabLayoutParams.gravity = Gravity.CENTER;
tabLayoutContainer.setLayoutParams(containerLayoutParams);
tabLayoutContainer.addView(tabLayout, tabLayoutParams);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlinView Question on Stackoverflow
Solution 1 - Androiduserrp1519825View Answer on Stackoverflow
Solution 2 - AndroidOctavian A. DamieanView Answer on Stackoverflow
Solution 3 - AndroidRohit SinghView Answer on Stackoverflow
Solution 4 - AndroidMN. ValaView Answer on Stackoverflow
Solution 5 - AndroidAbdul RehmanView Answer on Stackoverflow
Solution 6 - AndroidHermandroidView Answer on Stackoverflow