首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当定义为parents RelativeLayout时,自定义height可以超过parents height吗?

当定义为parents RelativeLayout时,自定义height可以超过parents height吗?
EN

Stack Overflow用户
提问于 2018-01-13 15:08:21
回答 1查看 164关注 0票数 0

我在视图层次结构中有以下结构

代码语言:javascript
复制
ScrollView
   LinearLayout (horizontal)
      - RelativeLayout (X)
         -LinearLayout
         -CustomView
      - RelativeLayout
      - RelativeLayout
      - RelativeLayout
      - RelativeLayout
      - RelativeLayout

下面是xml中的一个示例

代码语言:javascript
复制
<ScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
    <LinearLayout
        android:id="@+id/linLayoutWrapper"
        android:layout_width="match_parent"
        android:layout_height="1080dp"
        android:background="@color/white">
        <!--- note this include is a <RelativeLayout> -->
        <include
            android:id="@+id/dg_axis"
            layout="@layout/day_grid_axis"></include>
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="@color/grayBorder"></View>
        <--- start of repetitive substructure which his higlighted in screen shot -->
        <RelativeLayout
            android:id="@+id/sundayColumn"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="1080dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:layout_height="wrap_content">

            </LinearLayout>
            <com.mynursesstation.views.DayView
                android:id="@+id/sundayDayView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </RelativeLayout>
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="@color/grayBorder"></View>

        <!--- repeat above sub structure 6 more times --->
    </LinearLayout>
  </ScrollView>

其中内部结构(X)对所有其他RelativeLayout兄弟重复。线性布局,RelativeLayouts

注意:(X)以红色突出显示,其父级为整个屏幕宽度,并以其上方的灰色垂直线分隔。

如果所有的RelativeLayouts都是相同的大小(这是我的实验观点,还没有得到证实),那么它们都会齐平到线性布局的顶部。如果其中一个比其余的大,则默认情况下它们与底部对齐。我的问题是,当RelativeLayout的子项由父项定义时,这些子项如何超越父项?会不会是我以编程方式创建的视图的内在高度超过了其父视图的高度?android对此案的官方处理方式是什么?视图是否像HTML DOM元素一样溢出?

更新:

在检查每个RelativeLayout时,我认为其中一个超过3240像素的假设是错误的。他们中没有一个是这样的。只是似乎有一个上边距应用于一些(理论上会增加它的父级的高度,作为wrap_content),但它没有。

RelativeLayout的定义称为CustomView,是一个RelativeLayout,在其中以编程方式定位相对布局。它们在父级中的位置如下所示:

代码语言:javascript
复制
    int pixels = (int) (height * scale + 0.5f);
    pixels = (pixels + 4) / 5 * 5;
    relativeLayout.setLayoutParams(new RelativeLayout.LayoutParams(
            columnWidth / maxConflicts,
            pixels));

    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    params.addRule(RelativeLayout.ALIGN_PARENT_START);

    start = cal2.get(Calendar.HOUR_OF_DAY);
    height = start > 0 ? start * 44.000000000f + (start - 1) : start * 44.00000000f;
    height += cal2.get(Calendar.MINUTE) / 60.00000000000f;
    pixels = (int) (height * scale + 0.5f);


    if (offsetAmount != null){
        params.setMargins( (columnWidth / maxConflicts) * offsetAmount, pixels, 0, 0);
    } else {
        params.setMargins(0, pixels, 0, 0);
    }
    relativeLayout.setLayoutParams(params);

然而,从来不存在以上relativeLayout的上边距加上relativeLayout的高度超过1080dp的情况。我通过使用以下代码记录CustomView DayView的高度来动态验证这一点:

代码语言:javascript
复制
    columnHeight = MeasureSpec.getSize(heightMeasureSpec);

它总是以3240像素的形式记录下来,在3的尺度上,它恰好是1080dp

因此,这消除了一个DayView超过1080的可能性,这就是为什么不是顶级LinearLayout的所有子级都刷新到其顶部的原因。然而,我仍然不能理解是什么导致了这种行为。所有以编程方式添加到DayView的元素都是它们的父元素的alignTop,并且以垂直边距定位,其中以编程方式添加的视图的高度不会超过1080dp。

请注意,红色视图添加了一个神秘的mTop,即使它们的动态高度是1080dp。mTop + 1080dp > 1080dp但父级是1080dp (它是wrap_content)!

仔细看一下平齐的视图。它也有相同的高度,但mTop为零。我不明白为什么会这样,也不知道怎么可能。

在此处输入图像描述

周六更新:

好消息!我已经将问题缩小到一个子视图的子视图中,当忽略它时,不会在我的布局逻辑/意图中造成这种奇怪的不一致。罪魁祸首是以编程方式添加到两种类型事件中的<TextView>,这两种类型的事件都是以编程方式添加到DayView中的<RelativeLayout>。当两种类型的视图都将文本视图添加为子视图时,它会破坏视图层次结构。当只存在一个视图时,视图将按预期显示。下面是用于以编程方式布局日历事件的代码,日历事件的全部内容由DayView的所有子视图组成:

代码语言:javascript
复制
private void createEventLayout(CalendarEvent e, Integer offsetAmount, int maxConflicts) {
    final float scale = getContext().getResources().getDisplayMetrics().density;
    int idForMyView = e.assignmentId > 0 ? e.assignmentId : -e.conflictId;
    RelativeLayout relativeLayout = new RelativeLayout(getContext());
    relativeLayout.setId(idForMyView);

    Calendar cal2 = Calendar.getInstance();
    cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
    cal2.setTime(e.startDate);

    Calendar cal3 = Calendar.getInstance();
    cal3.setTimeZone(TimeZone.getTimeZone("UTC"));
    cal3.setTime(e.endDate);

    float start = cal2.get(Calendar.HOUR_OF_DAY);
    start += cal2.get(Calendar.MINUTE) / 60.0000000f;

    float end = cal3.get(Calendar.HOUR_OF_DAY);
    end += cal3.get(Calendar.MINUTE) / 60.00000000f;
    float height = (end - start) * 45.0000000f;

    int pixels = (int) (height * scale + 0.5f);
    pixels = (pixels + 4) / 5 * 5;

    relativeLayout.setLayoutParams(new RelativeLayout.LayoutParams(
            columnWidth / maxConflicts,
            pixels));

    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    params.addRule(RelativeLayout.ALIGN_PARENT_START);

    start = cal2.get(Calendar.HOUR_OF_DAY);
    height = start > 0 ? start * 44.000000000f + (start - 1) : start * 44.00000000f;
    height += cal2.get(Calendar.MINUTE) / 60.00000000000f;
    pixels = (int) (height * scale + 0.5f);

    if (offsetAmount != null){
        params.setMargins( (columnWidth / maxConflicts) * offsetAmount, pixels, 0, 0);
    } else {
        params.setMargins(0, pixels, 0, 0);
    }
    relativeLayout.setLayoutParams(params);

    if (e.assignmentId > 0){
        // company name
        TextView tv = new TextView(getContext());
        tv.setId(idForMyView);
        tv.setText(e.companyName);
        LayoutParams tvParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        tvParams.setMargins(0,0,0,0);
        tv.setLayoutParams(tvParams);
        RelativeLayout.LayoutParams companyNameParams = (RelativeLayout.LayoutParams) tv.getLayoutParams();
        tv.setTextColor(Color.parseColor("#ffffff"));
        tv.setTypeface(null, Typeface.BOLD);
        companyNameParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);

        //time of assignment / conflict
        TextView tvTime = new TextView(getContext());
        tvTime.setTextColor(Color.parseColor("#ffffff"));

        SimpleDateFormat sdf = new SimpleDateFormat("h:mm a");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String startTime = sdf.format(e.startDate);
        String endTime = sdf.format(e.endDate);
        tvTime.setText(startTime + " - " + endTime);
        tvTime.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        RelativeLayout.LayoutParams timeParams = (RelativeLayout.LayoutParams) tvTime.getLayoutParams();
        timeParams.addRule(RelativeLayout.BELOW, idForMyView);

        relativeLayout.addView(tv);     // ALSO this will break if present with the other kind
        relativeLayout.addView(tvTime);  // this too
        relativeLayout.setBackground(ContextCompat.getDrawable(getContext(), R.drawable.gradient_background_home));
        relativeLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final int assignmentId = view.getId();
                if (assignmentId > 0) {
                    Intent intent = new Intent(getContext(), AssignmentDetailActivity.class);
                    intent.putExtra(getContext().getString(R.string.extra_assignment_id), assignmentId);
                    getContext().startActivity(intent);
                }
            }
        });
    } else {
        final CalendarEvent event = e;
        relativeLayout.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.conflict));

        if (isConflictMode && e.isAllDay == 1){
            TextView tv = new TextView(getContext());
            tv.setId(idForMyView);
            tv.setText(ALL_DAY_TEXT);
            LayoutParams tvParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            tvParams.setMargins(0,0,0,0);
            tv.setLayoutParams(tvParams);
            RelativeLayout.LayoutParams companyNameParams = (RelativeLayout.LayoutParams) tv.getLayoutParams();
            tv.setTextColor(Color.parseColor("#ffffff"));
            tv.setTypeface(null, Typeface.BOLD);
            companyNameParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);

            tv.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                    getResources().getDimension(R.dimen.calendar_small_font));
            relativeLayout.addView(tv); //THIS will break the layout logic
       }
    }

    this.addView(relativeLayout);
    return;
}

我尝试通过设置以下内容来确保<TextView>被其父对象裁剪

代码语言:javascript
复制
tv.setGravity(Gravity.CLIP_HORIZONTAL | Gravity.CLIP_VERTICAL)

当我在视图中检查它时,它似乎精确地剪切到电视的边界,然而,基于以下事实,某些东西似乎正在超出其父代的高度:当<TextViews>消失时,一切都会增加,但当它们存在时,似乎有太多垂直内容。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-16 04:24:48

所以我的问题是,我将相同的id分配给了作为特定CalendarEvent<RelativeLayout>以及这个视图的子视图<TextViews>。这创建了循环逻辑,它引用了父和子,导致视图不能正确对齐,我认为特别是与其中一个textViews的BELOW要求,本质上是低于其本身。通过在每次创建<TextView>时使用View.generateId()创建唯一的id,这样就可以实现预期的布局。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48237702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档