3.3 ImageView、进度条与ScrollView


3.3 ImageView、进度条与 ScrollView

本节摘要:ImageView 的核心难题是"一张图怎么塞进一个框",scaleType 七种策略各有取舍;进度指示分确定与不确定两形态;ScrollView 则把超长内容装进可滚动容器。本节给猜数字 App 加上表情图、剩余次数进度条与可滚动战绩列表,基本组件三课到此收束。

一张图和一个框的博弈

猜数字 App 想在结果区放一张表情图:猜小时笑脸、接近时皱眉。图片是 512×512 的正方形,而界面留给它的区域是 96dp 的圆角方块。任何一个 ImageView 使用问题,本质都是"图片尺寸 ≠ 控件尺寸时怎么办",答案全部浓缩在 scaleType 里:

<ImageView android:id="@+id/iv_face" android:layout_width="96dp" android:layout_height="96dp" android:scaleType="centerCrop" android:contentDescription="猜题反馈表情" android:src="@drawable/ic_face_smile" />

高频取值只有四个,记住它们的取舍就够了:fitCenter 完整显示整图、可能留白;centerCrop 填满控件、可能裁边——头像、封面首选;fitXY 强行拉伸、比例变形,基本只用于背景纹理;center 原尺寸居中、不缩放,适合图标对位。代码里随猜测结果换图:

val face = when { diff == 0 -> R.drawable.ic_face_win diff <= 5 -> R.drawable.ic_face_close else -> R.drawable.ic_face_far } binding.ivFace.setImageResource(face)

contentDescription 别偷懒删掉:2.3 节讲过,读屏用户靠它知道这张图是什么;纯装饰图则显式设为 null 让读屏跳过。

进度:确定的与不确定的

猜数字有"最多七次"的规则,剩余次数天然适合 ProgressBar。先分清两种形态:**确定进度(determinate)**知道走到哪了,用 style 进度条;**不确定进度(indeterminate)**只知道"在忙",用转圈。加载下一局题目时界面要等网络,那就是转圈;展示已用掉几次机会,那是有刻度的:

<ProgressBar android:id="@+id/pb_tries" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="7" android:progress="2" />
binding.pbTries.progress = game.usedTries // 平滑动画版本:从 2 走到 3 有过渡 binding.pbTries.setProgress(game.usedTries, true)

一个易错点:progress 的类型是 Int,若要显示"0.5 次半步"这类进度就得放大十倍存整数再换算,别指望它支持小数。另外 Material 组件库的 LinearProgressIndicator 提供了带间隙的现代样式,原理相同,学会原生 ProgressBar 再迁移是顺水的。

图:scaleType 四策略与两种进度形态

图:scaleType 四策略与两种进度形态

ScrollView:给界面装上滚轮

历史战绩一局一局累积,竖屏空间迟早不够。ScrollView 的用法一句话就说完——把超长内容整个包起来

<ScrollView android:layout_width="match_parent" android:layout_height="0dp" android:fillViewport="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_history_1" ... /> <TextView android:id="@+id/tv_history_2" ... /> </LinearLayout> </ScrollView>

三条铁律:其一,ScrollView 只能有一个子 View——它是"可滚动的单个孩子",超长内容先装进 LinearLayout 再放进 ScrollView。其二,不要把 ListView/RecyclerView 再塞进 ScrollView,嵌套滚动会让内存里同时持有全部条目,第 7 章讲 RecyclerView 时会回到这个禁令。其三,内容不满一屏却想撑满时用 fillViewport="true",否则 ScrollView 会收缩成 wrap_content,底部的"清空记录"按钮吊在半空。

代码里滚动到底部看最新战绩:

binding.scrollView.post { binding.scrollView.fullScroll(View.FOCUS_DOWN) }

post 把动作排到下一帧布局完成之后执行,直接调用会滚不到底——这是新手高频翻车点。

本节要点回顾

  • scaleType 四选一:fitCenter 保完整、centerCrop 保填满、fitXY 保尺寸弃比例、center 不缩放。
  • contentDescription 是无障碍门票:内容图必填,装饰图显式 null。
  • 进度两形态:知道多少用 determinate,只在忙用 indeterminate;progress 是整数。
  • ScrollView 单子 View:先包 LinearLayout;禁与列表控件嵌套;不满屏用 fillViewport。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U