关于listview中某行的button事件触发当前行Textview的改变的研究
2011-10-14 15:28
525 查看
最近在写点菜项目的时候,碰到个关于listview的问题:当listview有几行数据的时,点击某行中的button按钮,想改变当前行中的textview中的值,但发现不管点击哪行的button,最终改变的textview都不是当前行,而是listview中的最后一行。附上代码如下:
list_row.xml
后来发现之所以只更改最后一行是因为在每次调用Adapter中的getviwe方法得到一行数据时,引用的Textview的对象都是同一个,都是hodle.text,因为我这里传进Adapter的list的大小为4,所以在第四次调用完getview后,此时hodle.text对象所指向的地址是第四行的textview的地址。所以造成了上述的现象。
问题是知道了,但解决方法还是想不出来,在网上查资料查了N久,也找不到解决方法,在google和baidu没用的时候,无奈,只有向他人请教了。。。起初得到的一个解决思路是:可以通过点击button触发一个事件,找到传入的数据list中的button所在行的数据,并进行相应的更改,然后在调用Adapter的notifyDataSetChanged方法(这里我的Adapter当然是extends BaseAdapter了)。但我认为,这个方法是不是效率太低了,如果我的数据有上百乃至上千行,每次点击一次Button都进行一次Listview的重新绘制,是不是有点小题大作?虽然问题可以得到暂时解决,但我不认为这是个好方法。
后来继续研究,在一位群友的提点下,我忽然想到是否可以在重写的Adapter中建立一个中间缓冲区,把每次getview中的textview的地址以position为标识保存下来,后来通过实践,发现这种想法是正确的。附上解决问题后的源码:
package com.droid; import android.app.Activity; import android.os.Bundle; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { /** Called when the activity is first created. */ ListView listView; Adapter adapter; Button button1, button2; TextView textView; String[] str1 = { "数组1-1", "数组1-2", "数组1-3", "数组1-4" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView)findViewById(R.id.title); listView = (ListView) findViewById(R.id.listView1); adapter = new Adapter(this); adapter.setList(str1); listView.setAdapter(adapter); textView.setText("数据源1"); } }重写的适配器
package com.droid; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.TextView; public class Adapter extends BaseAdapter { String[] list; Context context; LayoutInflater inflater; Hodle hodle; public Adapter(Context context) { // TODO Auto-generated constructor stub this.context = context; inflater = LayoutInflater.from(context); } public void setList(String[] list){ this.list = list; } @Override public int getCount() { // TODO Auto-generated method stub return list.length; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return list[arg0]; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int position, View convertView, ViewGroup arg2) { final int positionTemp = position; if(convertView == null){ convertView = inflater.inflate(R.layout.list_row, null); hodle = new Hodle(); hodle.text = (TextView) convertView.findViewById(R.id.textView1); hodle.btn= (Button) convertView.findViewById(R.id.btn_change); convertView.setTag(hodle); }else{ hodle = (Hodle) convertView.getTag(); } hodle.text.setText(list[position]); hodle.btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { hodle.text.setText(String.valueOf(positionTemp)); } }); return convertView; } class Hodle{ TextView text; Button btn; } }main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView"></TextView> <ListView android:id="@+id/listView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"></ListView> </LinearLayout>
list_row.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:text="TextView" android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" ></TextView> <Button android:text="change" android:id="@+id/btn_change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true"/> </RelativeLayout>
后来发现之所以只更改最后一行是因为在每次调用Adapter中的getviwe方法得到一行数据时,引用的Textview的对象都是同一个,都是hodle.text,因为我这里传进Adapter的list的大小为4,所以在第四次调用完getview后,此时hodle.text对象所指向的地址是第四行的textview的地址。所以造成了上述的现象。
问题是知道了,但解决方法还是想不出来,在网上查资料查了N久,也找不到解决方法,在google和baidu没用的时候,无奈,只有向他人请教了。。。起初得到的一个解决思路是:可以通过点击button触发一个事件,找到传入的数据list中的button所在行的数据,并进行相应的更改,然后在调用Adapter的notifyDataSetChanged方法(这里我的Adapter当然是extends BaseAdapter了)。但我认为,这个方法是不是效率太低了,如果我的数据有上百乃至上千行,每次点击一次Button都进行一次Listview的重新绘制,是不是有点小题大作?虽然问题可以得到暂时解决,但我不认为这是个好方法。
后来继续研究,在一位群友的提点下,我忽然想到是否可以在重写的Adapter中建立一个中间缓冲区,把每次getview中的textview的地址以position为标识保存下来,后来通过实践,发现这种想法是正确的。附上解决问题后的源码:
package com.droid; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.TextView; public class Adapter extends BaseAdapter { String[] list; Context context; LayoutInflater inflater; Hodle hodle; TextView[] textViewsCanche; public Adapter(Context context) { // TODO Auto-generated constructor stub this.context = context; inflater = LayoutInflater.from(context); } public void setList(String[] list) { this.list = list; textViewsCanche = new TextView[list.length]; } @Override public int getCount() { // TODO Auto-generated method stub return list.length; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return list[arg0]; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int position, View convertView, ViewGroup arg2) { System.out.println("getView!!"); final int positionTemp = position; if (convertView == null) { convertView = inflater.inflate(R.layout.list_row, null); hodle = new Hodle(); hodle.text = (TextView) convertView.findViewById(R.id.textView1); textViewsCanche[positionTemp] = hodle.text; hodle.btn = (Button) convertView.findViewById(R.id.btn_change); convertView.setTag(hodle); } else { hodle = (Hodle) convertView.getTag(); } hodle.text.setText(list[position]); hodle.btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { hodle.text = textViewsCanche[positionTemp]; hodle.text.setText(String.valueOf(positionTemp)); } }); return convertView; } class Hodle { TextView text; Button btn; } }
相关文章推荐
- 关于TextView中,设置指定部分文字改变颜色,和指定部分文字点击事件
- android selector(改变button,textview,listview的背景图片)
- Android 关于TextView中,设置指定部分文字改变颜色,和指定部分文字点击事件
- 请记住: i AM SoLiD. (关于View的事件触发顺序)
- jquery textlimit.js显示TEXTAREA中剩余字符(不支持光标位置改变时触发事件)
- Android手势研究(textview及listview对比验证)
- GridView, ListView的item中嵌入button或其他view导致item点击失效的研究
- ListView Item 选中时 改变 TextView 的字体颜色
- ListView的item中有button ImageButton CheckBox EditText等时 点击事件失效问题的解决
- ListView的item中有button ImageButton CheckBox EditText等时 点击事件失效问题的解决
- 设置TextView 的URL链接地址颜色以及触发事件方法
- Android:一个TextView分段改变样式、添加监听事件的实现方式(类似朋友圈评论)
- 通过Button改变TextView文字颜色
- 关于在tableview的footerView上添加button的点击不响应事件
- PopupWindow内ListView无法接受点击事件 原因之:TextView的clickable属性
- listview中textview响应部分文本点击事件
- OPhone/Android的学习(1)—初步知识,TextView,Button,Layout及事件响应
- 关于重新实现TextView 的超链接点击事件
- 关于在listview中checkbox的触发事件
- 关于DataGridView中当前行改变的事件