【问题标题】:LinearLayout layout_weight and weight_sum for sizing?LinearLayout layout_weight 和 weight_sum 用于调整大小?
【发布时间】:2019-05-23 02:12:49
【问题描述】:

我有 5 个线性布局。为了便于书写和理解,我将它们称为视图 A - E。

视图 A 是视图 B、C、D 和 E 的父视图。

我已将视图 A 的 layout_weight 设置为 8.0f,并将视图 B - E 的权重分别设置为 1.0f、3.0f、1.0f、3.0f。

我知道这是为了管理父视图中的空白空间,但我希望调整我的视图和子视图的大小以占据屏幕的百分比,而不是仅仅争夺可用空间。

但是,这一切都是以编程方式完成的,所以我是否应该将 LinearLayouts 的高度设置为其父级(视图 A)的 getHeight() 方法/访问器的系数?如果是这样,那么如果尚未将视图添加到其父级,我如何获取父级的高度,这将使用 MATCH_PARENT 设置其高度?

由于getHeight() 方法将为onCreateonStart 和第一个onResume 返回0,我不得不继续寻找答案。我找到了ViewTreeObserverOnGlobalLayoutListener,它们会在设置Layouts 时通知我。但是,我真的很感激在任何绘图发生之前有高度。这不可能吗?

【问题讨论】:

  • 我已经成功在片段中的onViewCreated中测量了屏幕。所以你可以用片段填充父级,然后在片段中绘制你的布局。

标签: android android-layout android-layout-weight


【解决方案1】:

如果您不需要以编程方式执行此操作,您可以在 xml 中执行此操作。为了让子 LinearLayouts 占用父 LinearLayout (LinearLayout A) 的百分比,那么您需要设置父级的 weightSum=(Total layout_weight of child LinearLayouts),然后将子 LinearLayouts 的宽度/高度属性设置为“0dip”和将它们的 layout_weight 设置为所需的百分比。

垂直方向的示例代码是:

<LinearLayout
     android:id="@+id/A"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:weightSum="8.0"
     android:orientation="vertical">
     <LinearLayout
          android:id="@+id/B"
          android:layout_height="0dip"
          android:layout_width="fill_parent"
          android:layout_weight="1.0"/>
     <LinearLayout
          android:id="@+id/C"
          android:layout_height="0dip"
          android:layout_width="fill_parent"
          android:layout_weight="3.0"
</LinearLayout>

【讨论】:

  • 我已经以编程方式完成了,除了将 LayoutParams 中的高度设置为 0dp。我将不得不尝试并回复您,因为它只是调整可用空间,而不是总空间。
  • 这通常是您创建基于百分比扩展的布局的方式。 Referenced here
  • 哇。所以,不同之处在于我需要将高度设置为 0,而不是 wrap_content。谢谢!
【解决方案2】:

不幸的是,在绘制视图之前无法获取视图的大小(除非存在我不知道的黑客行为)。在准备好布局之前,视图不会保存有关其大小的任何信息。如果在未来的版本中,他们设计的系统在绘制视图之前保存视图尺寸,那就太好了。

您可以创建一个自定义类,扩展 View 类,然后覆盖系统调用的方法并将尺寸返回给您的活动中的对象引用。但是,这可能更令人头疼,而不是帮助,并且不会真正给您带来任何真正的优势。

我建议使用 ViewTreeObserver 和 OnGlobalLayoutListener。

【讨论】:

  • 好的,好吧,我将不得不尝试所有三个答案,看看哪个表现最好。当视图出现时,它们听起来都可能存在一些绘图问题。手指交叉!
【解决方案3】:

下面是如何使用上面提到的 Fragments 来做到这一点。

首先在 onAttach 方法中保存对上下文的引用(无论如何,您可能都希望设置对活动的回调:

Context context;

@Override
public void onAttach(Activity activity){
    super.onAttach(activity);

    context = activity;


} 

然后在 onViewCreate 中进行测量并使用它们:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Display display = ((WindowManager)
        context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);

    float pixHeight = metrics.heightPixels;
    float pixWidth = metrics.widthPixels;
    float density  = context.getResources().getDisplayMetrics().density;
    float dpHeight = pixHeight / density;
    float dpWidth  = pixWidth / density;

    // make various layouts using your measurements, send the
    // measure of each parent to each custom drawn child, or 
    // send the bounds of each child as determined by the size of each parent

    return someView;
}

【讨论】:

  • 感谢您的回答!我将不得不尝试一切,看看什么表现最好,因为在很短的时间内有很多绘图要做。
  • 在其中一个中通过测量可能是个好主意:developer.android.com/reference/android/graphics/RectF.html
  • 这是一个很好的参考,但是它会降低性能,因为它是Object 子类,而不是原始数据类型。我只需要传递一个高度参数,但感谢您的链接! :)
  • 当我进行自定义绘图时,我会向每个需要自己绘制的孩子发送边界(我使用比 RectF 更轻的对象)。你确定你没有过早优化吗?如果您真的担心速度,我的理解是 LinearLayout 是资源匮乏的,如果在某些情况下您可以使用相对或框架,那就更好了。
  • 哦?相对布局更高效?我可以部分切换到那些。但这绝对不是过早优化,因为我必须在绘图方法中处理视图创建。我希望应用程序尽可能流畅。也许我误解了你过早优化的意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2016-03-01
相关资源
最近更新 更多