关于listview中某行的button事件触发当前行Textview的改变的研究

最近在写点菜项目的时候,碰到个关于listview的问题:当listview有几行数据的时,点击某行中的button按钮,想改变当前行中的textview中的值,但发现不管点击哪行的button,最终改变的textview都不是当前行,而是listview中的最后一行。附上代码如下:

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;
	}
}


评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值