如何使ScrollView滚动到指定TextView位置?Android开发求助
解决方案:分步实现滚动到指定TextView
没问题,这就帮你搞定这个滚动需求!既然你愿意为每个TextView写重复代码,那咱们就用最直接、不容易出错的方式来实现,不用搞复杂的反射或者动态查找,一步步来:
第一步:确认你的布局结构(参考示例)
先确保你的布局里各个控件的ID都正确设置,比如:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入数字(1-50)" android:inputType="number"/> <Button android:id="@+id/btn_scroll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="滚动到指定位置"/> <ScrollView android:id="@+id/scroll_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <LinearLayout android:id="@+id/ll_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 这里是你的50个TextView,示例前3个 --> <TextView android:id="@+id/tv_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="第1个TextView" android:padding="16dp"/> <TextView android:id="@+id/tv_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="第2个TextView" android:padding="16dp"/> <TextView android:id="@+id/tv_3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="第3个TextView" android:padding="16dp"/> <!-- ... 剩下的tv_4到tv_50依次类推 --> </LinearLayout> </ScrollView> </LinearLayout>
第二步:Java代码实现(直白的逐个判断)
在你的Activity或者Fragment里,直接通过ID获取所有TextView,然后在按钮点击事件里判断输入的数字,滚动到对应位置:
import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ScrollView; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private EditText etNumber; private ScrollView scrollView; // 提前声明所有TextView的引用 private TextView tv1, tv2, tv3, ..., tv50; // 这里把tv1到tv50都列出来 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化所有控件 etNumber = findViewById(R.id.et_number); scrollView = findViewById(R.id.scroll_view); Button btnScroll = findViewById(R.id.btn_scroll); // 逐个初始化TextView tv1 = findViewById(R.id.tv_1); tv2 = findViewById(R.id.tv_2); tv3 = findViewById(R.id.tv_3); // ... 一直到tv50 = findViewById(R.id.tv_50); // 设置按钮点击事件 btnScroll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String inputStr = etNumber.getText().toString().trim(); if (inputStr.isEmpty()) { // 输入为空的提示,可选 etNumber.setError("请输入数字"); return; } try { int targetNum = Integer.parseInt(inputStr); // 逐个判断数字,滚动到对应TextView switch (targetNum) { case 1: scrollToTarget(tv1); break; case 2: scrollToTarget(tv2); break; case 3: scrollToTarget(tv3); break; // ... 一直到case 50: scrollToTarget(tv50); break; default: etNumber.setError("请输入1-50之间的数字"); } } catch (NumberFormatException e) { etNumber.setError("请输入有效的数字"); } } }); } // 封装滚动方法,避免重复代码 private void scrollToTarget(TextView targetTv) { // smoothScrollTo会有平滑滚动效果,scrollTo是瞬间到位,选你喜欢的 scrollView.smoothScrollTo(0, targetTv.getTop()); } }
第三步:Kotlin代码实现(同样直白的方式)
如果用Kotlin开发,代码会更简洁一点,同样逐个处理:
import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.ScrollView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private lateinit var etNumber: EditText private lateinit var scrollView: ScrollView // 声明所有TextView private lateinit var tv1: TextView private lateinit var tv2: TextView private lateinit var tv3: TextView // ... 一直到tv50: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化控件 etNumber = findViewById(R.id.et_number) scrollView = findViewById(R.id.scroll_view) val btnScroll = findViewById<Button>(R.id.btn_scroll) // 逐个初始化TextView tv1 = findViewById(R.id.tv_1) tv2 = findViewById(R.id.tv_2) tv3 = findViewById(R.id.tv_3) // ... 一直到tv50 = findViewById(R.id.tv_50) btnScroll.setOnClickListener { val inputStr = etNumber.text.toString().trim() if (inputStr.isEmpty()) { etNumber.error = "请输入数字" return@setOnClickListener } val targetNum = inputStr.toIntOrNull() targetNum?.let { num -> when (num) { 1 -> scrollToTarget(tv1) 2 -> scrollToTarget(tv2) 3 -> scrollToTarget(tv3) // ... 一直到50 -> scrollToTarget(tv50) else -> etNumber.error = "请输入1-50之间的数字" } } ?: run { etNumber.error = "请输入有效的数字" } } } private fun scrollToTarget(targetTv: TextView) { scrollView.smoothScrollTo(0, targetTv.top) } }
为什么之前可能失败?
你之前没成功可能是这几个原因:
- 没有正确获取到TextView的引用,比如ID拼写错误
- 滚动坐标用错了,
targetTv.getTop()是相对于LinearLayout的顶部位置,而ScrollView的滚动正是基于这个坐标的,所以用smoothScrollTo(0, targetTv.getTop())是正确的 - 没有处理输入异常(比如输入非数字),导致代码崩溃
这个方法虽然需要写50次重复的case/when,但胜在简单直观,不容易出问题,完全符合你的需求~
内容的提问来源于stack exchange,提问作者Furqan Hussain
相关产品推荐
相关产品推荐

