【问题标题】:How to conditionally shrink one view or grow a different view depending on screen size?如何根据屏幕尺寸有条件地缩小一个视图或扩大一个不同的视图?
【发布时间】:2017-08-24 22:47:29
【问题描述】:

我正在尝试布局一个包含两个视图的活动,如下所示。

蓝色视图:此视图始终是方形的。它的最大高度是窗口的宽度。需要时,它可以缩小,但始终保持方形。

绿色视图:此视图具有最小高度,但没有最大值。如果包含的窗口真的很高,这个视图的高度会增加。

有没有人知道在 android 的 xml 布局中处理这个问题?我已尝试使用 layout_weights,但无法使其双向工作(缩小和增长)。

如果有帮助的话,周围的 ViewGroup 是一个 LinearLayout。

【问题讨论】:

  • 你说蓝色方块的宽度总是与屏幕宽度相同,但在最后一张图片中我看到你没有全宽..
  • 没有简单的方法来实现你想要用 XML 布局做的事情,因为在 XML 中有两个条件不能同时满足。 1:薄荷高度,2平方。所以我的看法是你可以在代码中使用基于屏幕尺寸的条件来做到这一点,首先,从屏幕高度减去最小高度并比较剩余高度是否大于宽度,然后使蓝色视图的宽度和高度等于宽度和增加绿色视图的高度,否则保持绿色视图的高度等于最小高度,并使蓝色视图的宽度和高度等于剩余高度。
  • 太糟糕了,我希望我不必以编程方式进行。那好吧。谢谢!

标签: android android-layout


【解决方案1】:

首先以 dp 为单位获取屏幕宽度的值

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

然后将dp中的显示宽度设置为布局的高度

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(dpHeight, dpHeight);

无论设备屏幕如何,您都将始终拥有 squire 布局

这是实现布局最小高度的方法

SmartImageView siv = new SmartImageView(getActivity());
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, minHeight);
siv.setLayoutParams(params);

【讨论】:

    【解决方案2】:

    根据我收到的 cmets,我最终做了以下事情(为我的解决方案稍微定制,但包括代码以防它帮助其他人)。

    在layout.xml中

    <LinearLayout
            android:id="@+id/root"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <RelativeLayout
                android:id="@+id/blueWrapper"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1">
    
                <android.support.constraint.ConstraintLayout
                    android:id="@+id/blueSquare"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
    
                    <View
                        android:adjustViewBounds="true"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        app:layout_constraintBottom_toBottomOf="@id/blueSquare"
                        app:layout_constraintLeft_toLeftOf="@id/blueSquare"
                        app:layout_constraintRight_toRightOf="@id/blueSquare"
                        app:layout_constraintTop_toTopOf="@id/blueSquare"
                        app:layout_constraintDimensionRatio="w,1:1"/>
    
                </android.support.constraint.ConstraintLayout>
    
                <!--EXTRA ELEMENTS HERE-->
    
            </RelativeLayout>
    
            <!-- 100dp is the minHeight -->
            <RelativeLayout
                android:id="@+id/greenWrapper"
                android:layout_width="match_parent"
                android:layout_height="100dp" 
                android:background="@color/green" >
    
                <!--ELEMENTS HERE-->
    
            </RelativeLayout>
    </LinearLayout>
    

    在我的活动中:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_activity);
    
        // Other initialization stuff here
    
        final LinearLayout root = (LinearLayout) findViewById(R.id.root);
        final RelativeLayout blueWrapper = (RelativeLayout) findViewById(R.id.blueWrapper);
        final View blueSquare = (View) findViewById(R.id.blueSquare);
        final RelativeLayout greenWrapper = (RelativeLayout) findViewById(R.id.greenWrapper);
        ViewTreeObserver vto = root.getViewTreeObserver();
        vto.addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    
                int rootHeight = root.getHeight();
    
                if(blueWrapper.getHeight() > blueWrapper.getWidth()){
                    ViewGroup.LayoutParams layoutParams = greenWrapper.getLayoutParams();
                    layoutParams.height = rootHeight - blueSquare.getWidth();
                    greenWrapper.setLayoutParams(layoutParams);
                }
            }
        });
    }
    

    这背后的逻辑是:

    • 加载时,一切都会按预期工作,除非是高窗框。

    • 对于高窗框,蓝色将拉伸到比宽度更大的高度,以便于识别。

    • 发生这种情况时,只需计算 blueHeight 和 blueWidth 之间的差,并将其添加到绿色包装的原始高度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      相关资源
      最近更新 更多