【问题标题】:When is the width of an Android View set?Android View 的宽度是什么时候设置的?
【发布时间】:2012-03-03 05:45:29
【问题描述】:

在将内容添加到 RelativeLayout 时,我对调用的顺序有一点疑问。我有一个扩展 Activity 的类(命名为 RelActivity),我想在其中创建一个 RelativeLayout 并将几个自定义视图(命名为 cusView)放入该 RelativeLayout。自定义 View 的 topMargin 和 leftMargin 是通过使用另一个自定义 View 的位置来计算的(即第一个自定义 View 必须通过设置一个数字来直接定位 topMargin 和 leftMargin)。请注意,在这种情况下,RelativeLayout 的规则是不够的。

那么,解决问题。在我的 RelActivity 我这样做:

  1. 创建一个RelativeLayout(命名为relLayout)
  2. 使用从数据库接收到的 cusView 迭代游标
  3. 对于第一个 cusView -> 使用 LayoutParameter 通过 topMargin 和 leftMargin 设置位置
  4. 对于其他 cusViews -> 使用其他 cusViews 之一和 LayoutParameter 计算它们的 topMargin 和 leftMargin
  5. 将 RelActivity 的 contentView 设置为 relLayout

发生的情况是除了第一个之外的所有 cusViews 都被挤压在左上角,因为 leftMargin 和 topMargin 总是被计算为零。出现这种情况是因为我使用了cusView的宽度来计算topMargin和leftMargin,而cusView的宽度还没有给出值。

宽度是先在cusView的重写方法onSizeChanged()中计算的吗?当布局显示在屏幕上时,是否首先调用 onSizeChanged() 方法?如果是这样,我该如何解决这个问题? onSizeChanged() 完成后是否需要计算定位?

编辑:这是一个最小的工作示例:

这是我在 RelActivity 中的 onCreate:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    relLayout = new RelativeLayout(this);
    cusViews = new ArrayList<CusView>();
    listParams = new ArrayList<RelativeLayout.LayoutParams>();

    readDBandSetLayout();

    setContentView(relLayout);
}

readDBandSetLayout() 方法中的信息太多,这里就不一一呈现了。以下是最重要的细节。如果我按以下方式创建 LayoutParams,它可以正常工作,那么 cusViews 会在彼此的下方和右侧列出:

queryCursor = customApplication.customData.query( number); //Fetches cursor

for ( int i = 0; i < numberOfRows; i++ ){

        if ( i == 0 ){
            LayoutParams p = new LayoutParams(this.getResources().getDimensionPixelSize(R.dimen.small), this.getResources().getDimensionPixelSize(R.dimen.small));
            p.topMargin = 50;
            p.leftMargin = 50;
            listParams.add(p);
        }
        else{
            LayoutParams p = new LayoutParams(this.getResources().getDimensionPixelSize(R.dimen.large),this.getResources().getDimensionPixelSize(R.dimen.large));
            p.addRule(RelativeLayout.BELOW, cusViews.get(i-1).getId());
            p.addRule(RelativeLayout.RIGHT_OF, cusViews.get(i-1).getId());
            listParams.add(p);
        }

    relLayout.addView(cusViews.get(i), listParams.get(i));
}

但是,我想在 else 语句中做的是:

else{
        LayoutParams p = new LayoutParams(this.getResources().getDimensionPixelSize(R.dimen.large),this.getResources().getDimensionPixelSize(R.dimen.large));

//Here I want to calculate cusView2Topmargin and cusView2Leftmargin based on the widths of the first or previosly positioned cusViews. But here the widths are 0 since they haven't been calculated yet.

        p.topMargin = cusView2Topmargin; //Always zero
        p.leftMargin = cusView2Leftmargin; //Always zero
        listParams.add(p);
            }

所以问题在于 cusViews 的宽度在我需要它们计算布局参数 topMargin 和 leftMargin 的点处为零。

不幸的是,我无法将 RelativeLayout 的规则用于我想要实现的目标。如果有某种方法可以创建像 RelativeLayout.RIGHT_OF 和 RelativeLayout.BELOW 这样的规则,我可以这样做。这可能吗?

【问题讨论】:

  • 您的一般方法是可以的(假设相对布局或任何其他都不够,这是一种非常罕见的情况)。我敢打赌你会做某事。设置 LayoutParams 时出错,这部分可能会变得很棘手,我过去也遇到过类似的问题。请提供一些代码示例,我们将看看我们能做些什么。
  • 我添加了一些工作代码。希望它足以理解这个问题。你知道是否可以创建我自己的 RelativeLayout 规则?这可能会解决问题,因为使用这些规则确实有效。

标签: android view


【解决方案1】:

您对此布局的目标不是很清楚。很可能使用简单的 LinearLayout 来获得您想要的。

如果你想从数据库查找中调整它们的大小,那么尝试简单地添加每个视图,使用 addView()first,存储对每个视图的引用,然后返回并设置边距放置他们在适当的位置。

【讨论】:

  • 注意:您正试图将 absolute 视图方法强制转换为 relative 视图。如果您分享最终布局的目标,可能会有更好的方法来做到这一点。
  • 我一直在研究这个,并相信 LinearLayout 是要走的路。正如你所说,我试图从相对视图中强制使用绝对视图。尽管我自己没有尝试过,但另一种方法可能是使用 GridLayout。
猜你喜欢
  • 2012-08-21
  • 2017-01-19
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多