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

Posted

技术标签:

【中文标题】FrameLayout中的Android中心视图不起作用【英文标题】:Android center view in FrameLayout doesn't work 【发布时间】:2011-05-02 09:13:08 【问题描述】:

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

我想在 FrameLayout 中居中,但我无法做到。 Texview 居中很好,当我让它可见时,我的 cusom 视图保持在左侧。

<FrameLayout android:id="@+id/CompassMap"
               android:layout_ 
               android:layout_
               android:layout_weight="1"
               android:gravity="center">

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

                <TextView android:layout_ 
        android:layout_
        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();
    

【问题讨论】:

您的自定义视图是从哪里扩展而来的?确定您正在处理构造函数中的参数? 是否有任何特殊原因必须使用 FrameLayout 以及 TextView 是否要显​​示在 View 之上? 是的,FrameLayout 不会让你这样做。它实际上只是为了保持单一视图。如果您添加的内容超出了您所提到的确切行为,它只需通过固定到左上角将元素添加到垂直堆栈中。 developer.android.com/reference/android/widget/FrameLayout.html 【参考方案1】:

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

在 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

【讨论】:

这应该是公认的答案。另一个人改变了问题而不是回答它。 Y 这个解决方案对我不起作用。在 Frame 的中心添加 Imageview layout.cap = new ImageView(CameraActivity.this); LayoutParams params2 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params2.gravity=重力.CENTER; cap.setLayoutParams(params2); cameraView.addView(cap); 现在它对我有用。我的错误是我导入了错误的包。 4 小时后,我发现实际包应该导入的错误是 android.widget.FrameLayout.LayoutParams; @Akanksha 这是唯一的正确答案 :) 你们必须使用 FrameLayout.LayoutParams 将视图居中到 FrameLayout。【参考方案2】:

我建议使用 RelativeLayout 而不是 FrameLayout。

假设您希望 TextView 始终位于 ImageView 下方,我将使用以下布局。

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

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

如果您想让 TextView 位于 ImageView 之上,那么只需省略 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_
    android:layout_>
    <ImageView
        android:id="@+id/imageview"
        android:layout_
        android:layout_
        android:layout_alignParentTop="false"
        android:layout_centerInParent="true"
        android:src="@drawable/icon"
        android:visibility="visible"/>
    <TextView
        android:id="@+id/textview"
        android:layout_
        android:layout_
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="@string/hello"/>
</RelativeLayout>

我希望这就是你要找的。​​p>

【讨论】:

您的解释看起来非常好,它应该适用于我的情况,但它没有。在我的 RelativeLayout 中,我说的不止这些:2 个自定义视图,一个 LinearLayout,一个 Button 和一个 TextView。奇怪的是,除了我的自定义视图之外,一切正常。其他自定义视图不受影响,因为它作为 fill_parent 属性。但是,我想看看我是否错过了什么。谢谢。 自定义视图的目的是什么? 我在问题上添加了自定义视图的整个代码。基本上在 x,y 位置绘制一个大图像作为背景和一个较小的图像。 这仅在您为 ImageView 指定 src 时才能按预期工作。如果您尝试将文本(或按钮或其他任何内容)放在稍后将填充的 ImageView 下方,您将遇到一些麻烦,因为在 onResume( ) 已完成。 您希望尽可能避免使用RelativeLayouts。每个 RelativeLayout 需要 2 次测量通道 - 因此嵌套的 RelativeLayouts 具有指数测量时间。每次添加新的嵌套 RelativeLayout 时,您的测量时间都会加倍。【参考方案3】:

按照这个顺序来

您可以在FrameLayout 中居中任意数量的孩子。

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

所以关键是

在子视图中添加android:layout_gravity="center"

例如:

我将 CustomViewTextView 放在 FrameLayout 这样的中心

代码:

<FrameLayout
    android:layout_
    android:layout_
    >
    <com.airbnb.lottie.LottieAnimationView
        android:layout_
        android:layout_
        android:layout_gravity="center"
        app:lottie_fileName="red_scan.json"
        app:lottie_autoPlay="true"
        app:lottie_loop="true" />
    <TextView
        android:layout_
        android:layout_
        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>

结果:

【讨论】:

这是唯一对我有用的答案。我有一个FrameLayout,其中包含一个TextureView 和两个SurfaceView。有了这个(以及表面上的setZOrderOnTop(true);,我终于全部居中覆盖【参考方案4】:

设置小部件的 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_
    android:layout_
    tools:context=".MovieActivity"
    android:id="@+id/mainContainerMovie"
    >


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

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

【讨论】:

【参考方案5】:

要使 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_
    android:layout_
    tools:context=".WebviewPDFActivity"
    android:layout_gravity="center"
    >
    <WebView
        android:id="@+id/webView1"
        android:layout_
        android:layout_

        />
    <ProgressBar
        android:id="@+id/progress_circular"
        android:layout_
        android:layout_
        android:visibility="visible"
        android:layout_gravity="center"
        />


</FrameLayout>

这是我的输出

【讨论】:

【参考方案6】:

在https://***.com/a/13025031/962916 之后,这对我来说可以在 FrameLayout 中将 TabLayout 居中。

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

【讨论】:

以上是关于FrameLayout中的Android中心视图不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Android中FrameLayout总结

android FrameLayout详解

在 Android 的 FrameLayout 中放置视图

[Android] FrameLayout 的作用

FrameLayout 高度与父级不匹配

Android Honeycomb:如何更改 FrameLayout 中的片段,而不重新创建它们?