应该支持纵向和横向模式的 ConstraintLayout - 带有一个按钮来切换全屏

Posted

技术标签:

【中文标题】应该支持纵向和横向模式的 ConstraintLayout - 带有一个按钮来切换全屏【英文标题】:ConstraintLayout that should support portrait and landscape modes -with a button to toggle full screen 【发布时间】:2019-11-28 04:20:56 【问题描述】:

我正在尝试实现图像的 4 种情况,但没有成功。 橙色方块为 40dp,用于切换全屏。 如您所见,在纵向\横向模式下:按下橙色按钮时,屏幕会在两种情况之间切换。请记住,我可以一直将智能手机转回纵向\横向,因此我认为 xml 约束并不是真正必要的。

我试过这段代码,但它不起作用:

private void updateViews() 
    // Sets the orientation
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) 
        mOrientation = Configuration.ORIENTATION_PORTRAIT;
    
    else mOrientation = Configuration.ORIENTATION_LANDSCAPE;

    if (mConstraintParent == null) mConstraintParent = findViewById(R.id.constraint_parent);
    if (mButtonOrangeToggleFullScreen == null) mButtonOrangeToggleFullScreen = findViewById(R.id.buttonToggleFullScreen);

    // Handles button to toggle full screen
    mButtonOrangeToggleFullScreen.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            mFullScreen = !mFullScreen;
            setViewsDimensions();
        
    );
    if (mGreen == null) mGreen = findViewById(R.id.green);
    if (mBlue == null) mBlue = findViewById(R.id.blue);
    if (mRed == null) mRed = findViewById(R.id.red);

    if (mOrientation == Configuration.ORIENTATION_PORTRAIT) 
        if (!mFullScreen) 
            ConstraintSet set = new ConstraintSet();
            set.clone(mConstraintParent);

            set.connect(mRed.getId(), ConstraintSet.TOP, mConstraintParent.getId(), ConstraintSet.TOP, 0);
            set.connect(mRed.getId(), ConstraintSet.BOTTOM, mBlue.getId(), ConstraintSet.TOP, 0);

            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.END, mRed.getId(), ConstraintSet.END, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.BOTTOM, mRed.getId(), ConstraintSet.BOTTOM, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.BOTTOM, mBlue.getId(), ConstraintSet.TOP, 0);

            set.connect(mBlue.getId(), ConstraintSet.LEFT, mConstraintParent.getId(), ConstraintSet.LEFT, 0);
            set.connect(mBlue.getId(), ConstraintSet.TOP, mRed.getId(), ConstraintSet.BOTTOM, 0);

            set.connect(mBlue.getId(), ConstraintSet.BOTTOM, mGreen.getId(), ConstraintSet.TOP, 0);
            set.connect(mGreen.getId(), ConstraintSet.BOTTOM, mConstraintParent.getId(), ConstraintSet.BOTTOM, 0);

            set.constrainPercentHeight(mRed.getId(), 0.7f);
            set.constrainPercentWidth(mRed.getId(), 1.0f);

            set.constrainPercentHeight(mBlue.getId(), 0.2f);
            set.constrainPercentWidth(mBlue.getId(), 1.0f);

            set.constrainPercentHeight(mGreen.getId(), 0.1f);
            set.constrainPercentWidth(mGreen.getId(), 1.0f);

            set.applyTo(mConstraintParent);

            mRed.setVisibility(View.VISIBLE);
            mBlue.setVisibility(View.VISIBLE);
            mGreen.setVisibility(View.VISIBLE);
        
        else  // full screen portrait
            ConstraintSet set = new ConstraintSet();
            set.clone(mConstraintParent);
            set.connect(mRed.getId(), ConstraintSet.TOP, mConstraintParent.getId(), ConstraintSet.TOP, 0);
            set.connect(mRed.getId(), ConstraintSet.BOTTOM, mConstraintParent.getId(), ConstraintSet.BOTTOM, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.END, mConstraintParent.getId(), ConstraintSet.END, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.BOTTOM, mConstraintParent.getId(), ConstraintSet.BOTTOM, 0);
            set.constrainPercentHeight(mRed.getId(), 1.0f);
            set.constrainPercentWidth(mRed.getId(), 1.0f);
            set.constrainPercentHeight(mBlue.getId(), 0);
            set.constrainPercentWidth(mBlue.getId(), 0);
            set.constrainPercentHeight(mGreen.getId(), 0);
            set.constrainPercentWidth(mGreen.getId(), 0);
            set.applyTo(mConstraintParent);
            mRed.setVisibility(View.VISIBLE);
            mBlue.setVisibility(View.GONE);
            mGreen.setVisibility(View.GONE);
        
    
    else  // LANDSCAPE
        if (!mFullScreen) 
            ConstraintSet set = new ConstraintSet();
            set.clone(mConstraintParent);
            set.clear(mRed.getId());
            set.clear(mBlue.getId());

            set.connect(mRed.getId(), ConstraintSet.TOP, mConstraintParent.getId(), ConstraintSet.TOP, 0);
            set.connect(mRed.getId(), ConstraintSet.RIGHT, mBlue.getId(), ConstraintSet.LEFT, 0);

            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.END, mRed.getId(), ConstraintSet.END, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.BOTTOM, mRed.getId(), ConstraintSet.BOTTOM, 0);

            set.connect(mBlue.getId(), ConstraintSet.LEFT, mRed.getId(), ConstraintSet.RIGHT, 0);
            set.connect(mBlue.getId(), ConstraintSet.TOP, mConstraintParent.getId(), ConstraintSet.TOP, 0);

            set.connect(mRed.getId(), ConstraintSet.BOTTOM, mGreen.getId(), ConstraintSet.TOP, 0);
            set.connect(mGreen.getId(), ConstraintSet.BOTTOM, mConstraintParent.getId(), ConstraintSet.BOTTOM, 0);

            set.constrainPercentHeight(mRed.getId(), 0.9f);
            set.constrainPercentWidth(mRed.getId(), 0.8f);

            mBlue.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT, ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT));
            set.constrainPercentHeight(mBlue.getId(), 0.9f);
            set.constrainPercentWidth(mBlue.getId(), 0.2f);

            set.constrainPercentHeight(mGreen.getId(), 0.1f);
            set.constrainPercentWidth(mGreen.getId(), 1.0f);

            set.applyTo(mConstraintParent);

            mRed.setVisibility(View.VISIBLE);
            mBlue.setVisibility(View.VISIBLE);
            mGreen.setVisibility(View.VISIBLE);
        
        else  // full screen landscape
            ConstraintSet set = new ConstraintSet();
            set.clone(mConstraintParent);
            set.connect(mRed.getId(), ConstraintSet.TOP, mConstraintParent.getId(), ConstraintSet.TOP, 0);
            set.connect(mRed.getId(), ConstraintSet.BOTTOM, mConstraintParent.getId(), ConstraintSet.BOTTOM, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.END, mConstraintParent.getId(), ConstraintSet.END, 0);
            set.connect(mButtonOrangeToggleFullScreen.getId(), ConstraintSet.BOTTOM, mConstraintParent.getId(), ConstraintSet.BOTTOM, 0);
            set.constrainPercentHeight(mRed.getId(), 1.0f);
            set.constrainPercentWidth(mRed.getId(), 1.0f);
            set.constrainPercentHeight(mBlue.getId(), 0);
            set.constrainPercentWidth(mBlue.getId(), 0);
            set.constrainPercentHeight(mGreen.getId(), 0);
            set.constrainPercentWidth(mGreen.getId(), 0);
            set.applyTo(mConstraintParent);
            mRed.setVisibility(View.VISIBLE);
            mBlue.setVisibility(View.GONE);
            mGreen.setVisibility(View.GONE);

        
    

这是我使用的 xml(不确定是否相关,因为我在代码中覆盖了它)

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:id="@+id/constraint_parent">

    <ImageView
        android:id="@+id/red"
        android:layout_
        android:layout_
        ads:layout_constraintTop_toTopOf="@+id/constraint_parent"
        ads:layout_constraintEnd_toEndOf="@+id/constraint_parent"
        ads:layout_constraintStart_toStartOf="@id/constraint_parent"
        android:background="@color/custom_red"
        ads:layout_constraintBottom_toTopOf="@+id/blue"
        app:layout_constraintHeight_percent=".7"
        app:layout_constraintWidth_percent="1.0"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintWidth_default="percent"
        tools:layout_editor_absoluteX="5dp" />

    <ImageButton
        android:layout_
        android:layout_
        android:layout_marginRight="5dp"
        android:layout_marginLeft="5dp"
        android:layout_marginBottom="5dp"
        android:background="@android:color/holo_orange_dark"
        ads:layout_constraintEnd_toEndOf="@+id/red"
        ads:layout_constraintBottom_toBottomOf="@+id/red"
        android:id="@+id/buttonToggleFullScreen"/>

    <ImageView
        android:id="@+id/blue"
        android:layout_
        android:layout_
        android:background="#550000ff"
        app:layout_constraintHeight_percent=".2"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintWidth_default="percent"
        ads:layout_constraintLeft_toLeftOf="@+id/constraint_parent"
        ads:layout_constraintTop_toBottomOf="@+id/red"
        ads:layout_constraintBottom_toTopOf="@+id/green"/>

    <LinearLayout
        android:layout_
        android:layout_
        app:layout_constraintHeight_percent=".1"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintWidth_default="percent"
        android:background="@color/green_shiny"
        android:orientation="vertical"
        ads:layout_constraintBottom_toBottomOf="@+id/constraint_parent"
        android:id="@+id/green">
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

请帮助我达到预期的效果。

【问题讨论】:

【参考方案1】:

这可以相当简单地使用纵向和横向的 XML 布局并使用权重来定义视图的相对大小。当按下切换按钮时,您可以根据全屏状态制作蓝/绿视图VISIBLEGONE。然后红色视图调整大小以填充蓝色/绿色视图腾出的空间。

注意使用onSaveInstanceState 来保留配置更改时的全屏状态。

MainActivity.java:

package com.example.test;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity 

    private boolean mFullScreen = false;
    private ImageView mBlue;

    private ImageView mGreen;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageButton toggleButton = findViewById(R.id.toggle_button);
        mBlue = findViewById(R.id.blue);
        mGreen = findViewById(R.id.green);
        if (savedInstanceState != null) 
            setFullScreen(savedInstanceState.getBoolean("mFullScreen", false));
        
        toggleButton.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                setFullScreen(!mFullScreen);
            
        );
    

    @Override
    protected void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);
        outState.putBoolean("mFullScreen", mFullScreen);
    

    private void setFullScreen(boolean fullScreen) 
        mFullScreen = fullScreen;
        mBlue.setVisibility(mFullScreen ? View.GONE : View.VISIBLE);
        mGreen.setVisibility(mFullScreen ? View.GONE : View.VISIBLE);
    

res/layout/activity_main.xml(纵向):

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/red"
        android:layout_
        android:layout_
        android:background="#ffff0000"
        app:layout_constraintBottom_toTopOf="@+id/blue"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_weight="0.7" />

    <ImageView
        android:id="@+id/blue"
        android:layout_
        android:layout_
        android:background="#ff0000ff"
        app:layout_constraintBottom_toTopOf="@+id/green"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/red"
        app:layout_constraintVertical_weight="0.2" />

    <ImageView
        android:id="@+id/green"
        android:layout_
        android:layout_
        android:background="#ff00ff00"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/blue"
        app:layout_constraintVertical_weight="0.1" />

    <ImageButton
        android:id="@+id/toggle_button"
        android:layout_
        android:layout_
        android:layout_margin="15dp"
        android:background="#ffffa000"
        app:layout_constraintBottom_toBottomOf="@id/red"
        app:layout_constraintEnd_toEndOf="@id/red"/>

</android.support.constraint.ConstraintLayout>

res/layout-land/activity_main.xml:(横向)

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/red"
        android:layout_
        android:layout_
        android:background="#ffff0000"
        app:layout_constraintBottom_toTopOf="@+id/green"
        app:layout_constraintEnd_toStartOf="@+id/blue"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_weight="0.9"
        app:layout_constraintHorizontal_weight="0.8"/>

    <ImageView
        android:id="@+id/blue"
        android:layout_
        android:layout_
        android:background="#ff0000ff"
        app:layout_constraintBottom_toTopOf="@+id/green"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/red"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_weight="0.9"
        app:layout_constraintHorizontal_weight="0.2"/>

    <ImageView
        android:id="@+id/green"
        android:layout_
        android:layout_
        android:background="#ff00ff00"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/red"
        app:layout_constraintVertical_weight="0.1" />

    <ImageButton
        android:id="@+id/toggle_button"
        android:layout_
        android:layout_
        android:layout_margin="15dp"
        android:background="#ffffa000"
        app:layout_constraintBottom_toBottomOf="@id/red"
        app:layout_constraintEnd_toEndOf="@id/red"/>

</android.support.constraint.ConstraintLayout>

【讨论】:

以上是关于应该支持纵向和横向模式的 ConstraintLayout - 带有一个按钮来切换全屏的主要内容,如果未能解决你的问题,请参考以下文章

视图控制器处于横向模式,但我从纵向模式获取框架?

如何使用 phonegap 构建同时支持纵向和横向启动屏幕?

支持 UIDocumentInteractionController 的横向和纵向

如何设置纵向和横向约束

如何将视图从纵向模式旋转到横向模式

如何根据手机方向(横向,纵向)绘制画布?