在 Android 的 FrameLayout 中放置视图

Posted

技术标签:

【中文标题】在 Android 的 FrameLayout 中放置视图【英文标题】:Place view inside FrameLayout in Android 【发布时间】:2011-04-20 10:40:57 【问题描述】:

我想以编程方式在 FrameLayout 中添加一个视图,并将其放置在布局中具有特定宽度和高度的特定点。 FrameLayout 支持这个吗?如果不是,我应该使用中间 ViewGroup 来实现吗?

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

我最初的想法是在 FrameLayout 中添加一个 AbsoluteLayout,并将视图放在 AbsoluteLayout 中。不幸的是,我刚刚发现 AbsoluteLayout 已被弃用。

任何指针将不胜感激。谢谢。

【问题讨论】:

您是否以某种方式解决了这个问题?我对非 AbsoluteLayout 解决方案感兴趣 :) 【参考方案1】:

以下示例(工作代码)显示了如何在 FrameLayout 中放置视图 (EditText)。它还展示了如何使用 FrameLayout 的 setPadding 设置器设置 EditText 的位置(每次用户点击 FrameLayout 时,EditText 的位置都会设置为点击的位置):

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_
    android:layout_>
    <FrameLayout 
        android:id="@+id/frameLayout1" 
        android:layout_ android:layout_>
    </FrameLayout>

</LinearLayout>

【讨论】:

这与问题有什么关系? 嗯.. 它是 Framelayout 内部的视图,不是吗?另外,我正在展示如何使用 setPadding 设置器将嵌入视图定位在特定位置。【参考方案2】:

您还可以在新添加的视图周围添加边距,以将其定位在 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);

这会将 FrameLayout 定位在距屏幕底部 20 像素处。

编辑: 完成了示例,使其独立存在。哦,是的,它确实有效。

【讨论】:

1) 什么是宽度?它从何而来? 2) metric.width 不存在,它的metric.widthPixels。 3)这不起作用,如果可以,它仍然不会,因为您没有在任何地方添加 v...【参考方案3】:

确实,使用 FrameLayout,所有子级都固定在屏幕的左上角,但您仍然可以控制设置它们的填充。如果你为不同的子元素设置不同的填充值,它们会出现在 FrameLayout 的不同位置。

【讨论】:

但是这样做的问题是点击监听器将从左上角开始跨越整个区域...【参考方案4】:

来自linkQuinn1000 提供:

您可以将多个子级添加到 FrameLayout,但所有子级都固定在屏幕的左上角。

这意味着您不能将 View 放在 FrameLayout 内的特定点(除非您希望它位于左上角 :-))。

如果需要View的绝对定位,试试AbsoluteLayout:

一种布局,可让您指定其子项的确切位置(x/y 坐标)。与没有绝对定位的其他类型的布局相比,绝对布局更不灵活且更难维护。

至于设置View的宽度和高度,也像Quinn1000说的,你提供v.setLayoutParams()方法一个LayoutParams对象,取决于你选择的容器(AbsoluteLayout,LinearLayout等)

【讨论】:

不幸的是 AbsoluteLayout 已被弃用。 你是对的。当我早些时候查看 API 时,我错过了这一点。我想您可以在 FrameLayout 中为 View 使用 margin-left/top 以获得与 AbsoluteLayout 类似的体验。 我怎样才能以编程方式做到这一点? 查看 FrameLayout.LayoutParams 的 API(链接在我的答案中):它扩展了 MarginLayoutParams,它提供了“setMargins”方法。【参考方案5】:

*** 上的线程

How do you setLayoutParams() for an ImageView?

在某种程度上涵盖了它。

例如: LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(30, 30); yourImageView.setLayoutParams(layoutParams);

暗示您需要定义一个 LinearLayout.LayoutParams(或在您的情况下为 FrameLayout.layoutParams)对象以传递给您的 v 对象的 setLayoutParams 方法。

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

这几乎让您看起来可以要求您的 v :

如果没有具体定义参数,则通过此方法生成DefaultLayoutParams()。

但是已经晚了,这些链接让我的眼睛有点流血。让我知道他们是否有任何帮助:-)

【讨论】:

以上是关于在 Android 的 FrameLayout 中放置视图的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Android 中的 FrameLayout 上检测手势

Android:如何在 FrameLayout 元素中绘制?

Android中FrameLayout总结

在android中使用fragment和frameLayout有啥区别?两者可以互换使用吗?

Android零基础入门第30节:两分钟掌握FrameLayout帧布局

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