您的位置:首页 > 其它

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

2011-10-14 15:28 525 查看
最近在写点菜项目的时候,碰到个关于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;
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: