【发布时间】:2019-10-21 02:50:13
【问题描述】:
TL;DR
我想在ScrollView 中居中对齐ImageButton,我对纵向模式下的结果非常满意。但是,我不能对横向模式说同样的话,我们将不胜感激。
让我解释一下
我在这里使用了两个布局文件;第一个是我用于MainActivity 类的,称为activity_main.xml。当MainActivity 加载MainFragment 时,第二个(称为fragment_main.xml)嵌套到activity_main.xml 中。
fragment_main.xml 的预览在纵向和横向模式下看起来很有希望:
fragment_main.xml in landscape
fragment_main.xml in portrait
activity_main.xml 在纵向模式下的渲染看起来正是我想要的样子:
activity_main.xml in portrait
但是,activity_main.xml 在横向模式下看起来很奇怪,我不知道为什么:
activity_main.xml in landscape
这是activity_main.xml 的XML,其中fragment_main.xml 作为ScollView 的子项合并到其中:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:titleTextAppearance="@style/Toolbar.TitleText"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ScrollView
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<!-- Content of fragment_main.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingStart="50dp"
android:paddingEnd="50dp"
tools:context=".MainFragment">
<ImageButton
android:id="@+id/overlay_button"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@null"
android:contentDescription="@string/start_speedometer"
android:scaleType="fitCenter"
android:src="@drawable/btn_circle_green"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/overlay_button_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:text="@string/start_speedometer"
android:textColor="@color/white"
android:textSize="40sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="false"
app:menu="@menu/nav_drawer_view"
app:headerLayout="@layout/nav_drawer_header"
app:itemIconTint="@drawable/nav_drawer_item_icon_color"
app:itemTextColor="@drawable/nav_drawer_item_text_color" />
</androidx.drawerlayout.widget.DrawerLayout>
我正在寻找一种解决方案,我只需对fragment_main.xml(即ScollView 内的所有内容)进行更改。解决方案应该只涉及 XML。
我尝试过的
我试过摆弄app:layout_constraintDimensionRatio(W,1:1,H,1:1),app:layout_constrainedHeight,app:layout_constraintHeight_max,layout_constraintHeight_min,许多其他约束,甚至尝试在其他布局中嵌套fragment_main.xml的内容,从ConstraintLayout 移动到RelativeLayout、LinearLayout 和FrameLayout,但它们都没有给我想要的结果,而ConstraintLayout 是最接近的。
可能的解决方案
目前唯一有效的解决方案是使用 app:layout_constraintWidth_default="percent" 和 app:layout_constraintWidth_percent="0.5" 导致
desired look of activity_main.xml in landscape
虽然这在 16:9 手机上看起来不错,但在具有不同纵横比的手机上可能会导致与以前相同的问题。所以我正在寻找一种更通用的方法。
其他细节
这是我用于按钮的可绘制btn_circle_green.xml 的内容:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/ic_circle_green_pressed" />
<item android:state_focused="true" android:drawable="@drawable/ic_circle_green_focused" />
<item android:state_selected="true" android:drawable="@drawable/ic_circle_green_focused" />
<item android:drawable="@drawable/ic_circle_green_default" />
</selector>
每个ic_circle_green_* 都是像这样具有不同颜色的矢量资产:
<vector
android:viewportWidth="300"
android:viewportHeight="300"
android:height="120dp"
android:width="120dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/green"
android:pathData="M150,150m-140,0a140,140 0,1 1,280 0a140,140 0,1 1,-280 0"
android:strokeWidth="5"
android:strokeColor="@color/green_light"/>
</vector>
非常感谢!
【问题讨论】:
-
可绘制的圆的尺寸是多少?
-
由于您的片段的
layout_width设置为match_parent,它将扩展以填充横向模式下的可用水平空间。您的ImageButton将依次填充可用空间,并且由于它的比率设置为 1:1,因此您会得到不希望的结果。我的问题是.. 如果您希望将ImageButton限制在可用的垂直空间中,为什么片段必须位于ScrollView中? -
@glucaio 我已经添加了drawable。我猜 120dp x 120dp 是您正在寻找的答案,对吧?
-
@glucaio 该片段位于
ScrollView中,因为ScrollView及其父母定义了我的MainActivity。当用户从菜单/NavigationView中点击另一个项目时,我将fragment_main替换为其他片段。该项目可能不适合屏幕。因此,我不想在需要的地方放置ScrollView,而是将它用于所有片段。这是个坏主意吗?你有没有ScrollView的解决方案? -
在这种情况下,尝试使用
FrameLayout代替ScrollView,如果任何其他片段需要滚动,您可以实现ScrollView(或其他一些机制,如RecyclerView) 在这些特定布局中。
标签: android xml android-constraintlayout android-scrollview android-imagebutton