Xamarin Android中如何点击动态添加的TextView?点击仅显示最后一项文本
嘿,这个问题我之前也踩过坑!咱们先搞清楚问题出在哪,再给你修复方案:
问题核心原因
你在foreach循环里只声明了一次TextView txt变量,每次循环都是给同一个变量重新赋值新的TextView实例。而绑定的Txt_Click事件处理程序,实际上捕获的是这个变量的引用,不是每次循环创建的具体TextView对象。等循环跑完,这个变量指向的是最后一个创建的TextView,所以不管你点哪个,都会拿到最后一项的文本。
修复步骤
- 把TextView的声明移到循环内部:这样每次循环都会生成一个独立的局部变量,事件处理程序会正确捕获当前循环的那个TextView实例。
- 在点击事件里用sender获取控件:别直接用全局的
txt变量,而是通过触发事件的sender参数拿到被点击的TextView,这才是最可靠的方式。
修改后的完整代码
TableRow row; LinearLayout tl = FindViewById<LinearLayout>(Resource.Id.tableLayout); var servicesData = DataServices.GetAllServices(); try { foreach (var item in servicesData) { // 关键:把txt的声明放到循环内部,每次循环都创建新的局部变量 TextView txt = new TextView(this) { Id = item.ServiceId }; row = new TableRow(this); ImageButton imgBtn = new ImageButton(this); Button btntxt = new Button(this); String imgUrl = "https://careservicesapi.boffincoders.com/Images/" + item.ServiceIcon; var imageBmp = GetImageBitmapFromUrl(imgUrl); Drawable drawable = new BitmapDrawable(Resources, imageBmp); Drawable drawable1 = new BitmapDrawable(); drawable.SetBounds(0, 0, 50, 40); txt.SetMinimumHeight(100); txt.SetMinimumWidth(100); txt.SetHeight(100); txt.TextSize = 10; txt.Gravity = GravityFlags.Center; txt.Text = item.ServiceName; txt.Tag = item.ServiceId; txt.Click += Txt_Click; txt.SetCompoundDrawablesWithIntrinsicBounds(drawable1, drawable, drawable1, drawable1); txt.Clickable = true; // 调整顺序:先把TextView加到TableRow,再把TableRow加到LinearLayout row.AddView(txt); tl.AddView(row); } } private void Txt_Click(object sender, EventArgs e) { // 通过sender获取被点击的TextView,安全又准确 if (sender is TextView clickedTextView) { var clickedText = clickedTextView.Text; // 额外:你还能直接拿到之前存的ServiceId var serviceId = clickedTextView.Tag; // 这里写你的业务逻辑就行 } }
额外小提示
- 循环里的控件尽量都在内部声明,避免变量复用导致的引用问题,这是动态创建控件的常见坑。
- 用
Tag属性存额外数据(比如你的ServiceId)是个好做法,点击时可以直接取出来用,不用再额外查找。
内容的提问来源于stack exchange,提问作者Tony Chatha
相关产品推荐
相关产品推荐

