FrameLayout中的Android中心视图不起作用


83

我有一个FrameLayout,其中有2个控件:-一个自定义视图,可在其中绘制图像和一些文本-具有文本的textview

我想同时在FrameLayout中居中,但我无法做到这一点。Texview居中就好,当我使它可见时,我的cusom视图仍保留在左侧。

<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>

对于Mathias,我在构造函数中不做任何事情,这很简单

   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();
    }
}

1
您的自定义视图从何而来?确定要在构造函数中处理参数吗?
Mathias Conradt

是否有任何特殊原因需要使用FrameLayout?TextView是否显示在View的顶部?
Octavian A. Damiean 2010年

1
是的,FrameLayout不允许您这样做。它实际上只是用于保留单个视图。如果添加的内容超出了您要提到的确切行为,它只会通过固定到左上角来在垂直堆栈中添加元素。 developer.android.com/reference/android/widget/FrameLayout.html
plainjimbo 2010年

Answers:


42

我建议使用RelativeLayout而不是FrameLayout。

假设您想让TextView始终位于ImageView下面,那么我将使用以下布局。

<?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>

请注意,如果visibility将元素的设置为,gone则该元素将消耗的空间将消失,而当您使用时,invisible它将保留其消耗的空间。

如果要在ImageView的顶部放置TextView,则只需省略android:layout_alignParentTop或将其设置为,false然后在TextView上省略android:layout_below="@id/imageview"属性。像这样。

<?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>

我希望这就是您想要的。


您的解释看起来很好,在我的情况下应该可以,但事实并非如此。在我的RelativeLayout中,除了我说的以外,还有更多内容:2个自定义视图,LinearLayout,Button和TextView。奇怪的是,一切正常都超出了我的自定义视图。另一个自定义视图不受影响,因为它作为fill_parent属性。但是,我试图查看是否没有错过任何事情。谢谢。
Alin

自定义视图的目的是什么?
Octavian A. Damiean

我在问题上添加了自定义视图的整个代码。基本上在背景上绘制一个大图像,在x,y位置上绘制一个较小的图像。
Alin

仅当您为ImageView指定src时,此方法才能按预期工作。如果您尝试将文本(或按钮或其他内容)放置在稍后将要填充的ImageView下方,则会遇到一些麻烦,因为直到onResume( ) 已完成。

4
您希望尽可能避免使用RelativeLayouts。每个RelativeLayout都需要2次测量-因此嵌套的RelativeLayouts具有指数测量时间。每次添加新的嵌套RelativeLayout时,测量时间都会加倍。
Martin Konecny 2015年

384

我们可以FrameLayout通过设置layout_gravity子视图的来将视图对齐在的中心。

在XML中:

android:layout_gravity="center"

在Java代码中:

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

注意:FrameLayout.LayoutParams不要使用其他现有的LayoutParams


107
这应该是公认的答案。另一个改变问题而不是回答问题。
Muz

是的,这个解决方案对我不起作用。在Frame layout的中心添加Imageview.cap = new ImageView(CameraActivity.this); LayoutParams params2 =新的LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); params2.gravity = Gravity.CENTER; cap.setLayoutParams(params2); cameraView.addView(cap);
Akanksha Rathore 2014年

8
现在它对我有用。我的错误是我被导入错误的程序包。4小时后,我误入了实际包应该导入的错误:android.widget.FrameLayout.LayoutParams;
Akanksha Rathore 2014年

2
@Akanksha是唯一正确的答案:)你们必须使用FrameLayout.LayoutParams将视图居中到FrameLayout中。
hrules6872

5

只要按照这个顺序

您可以将任何数量的孩子居中FrameLayout

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

所以关键是

添加android:layout_gravity="center"子视图。

例如:

我为中心的CustomViewTextView的FrameLayout这样的

码:

<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>

结果:

在此处输入图片说明


1
这是唯一对我有用的答案。我有一个FrameLayout包含一个TextureView和两个SurfaceView。有了这个(以及setZOrderOnTop(true);在Surfaces上,我终于全部集中在了图层上
Xavi,

1

设置窗口小部件的layout_gravity属性的'center_horizo​​ntal'和'center_vertical'或仅'center'

    <?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>

0

为了使视图在Framelayout中居中,有一些可用的技巧。我刚刚在Webview和Progressbar中使用了最简单的一个(非常类似于您的两个对象的布局),我刚刚添加了android:layout_gravity="center"

如果有人需要做同样的事情,这里是完整的XML

<?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>

这是我的输出

屏幕截图

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.