android ListView与EditText共存错位

在一个ListView中,如果里面有EditText会很麻烦,因为修改EditText里面的数据会发生错位现象.

这时候,需要在适配器BaseAdapter的getView中设置setTag(),将position缓存起来.

下面来解决这个问题.

1.打开activity_main.xml .

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.example.listviewdemo1.MainActivity" >

<Button

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:id="@+id/btn_addRow"

android:text="增加一行"

/>

<ListView

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:id="@+id/lv"

android:cacheColorHint="@android:color/transparent"

></ListView>

</LinearLayout>

在这个布局中,只有一个简单的Button和一个ListView,Button是用来动态添加  一行记录的.

2.新建一个item.xml,作为listView的子布局.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:descendantFocusability="beforeDescendants"

android:orientation="horizontal" >

<TextView

android:layout_width="10dp"

android:layout_height="wrap_content"

android:id="@+id/tv_position"

/>

<Spinner

android:layout_width="100dp"

android:layout_height="wrap_content"

android:id="@+id/sp_type"

/>

<EditText

android:layout_width="100dp"

android:layout_height="wrap_content"

android:id="@+id/et_number"

/>

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/btn_delete"

android:text="删除"

/>

</LinearLayout>

子布局元素也只有四个, 一个TextView用来放索引位置,  Spinner用来显示一个下拉窗口  , 还有一个EditText和一个Button.

3.新建一个NumberInfo.java,用来存储数据的javaBean.

public class NumberInfo {

private String type;

private String number;

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public String getNumber() {

return number;

}

public void setNumber(String number) {

this.number = number;

}

}

只有简单的两个属性

4.新建一个MyAdapter.java 适配器, 用来展示ListView的数据, 解决混乱的重点.

public class MyAdapter extends BaseAdapter {

private List<NumberInfo> list=new ArrayList<NumberInfo>();

private Context context;

private OnListRemovedListener mListener;

//下拉列表的适配器

private ArrayAdapter<String> arrayAdapter;

//下拉列表的选项

private static final String[] SPINNER_TIME = {"手机","住宅","其他"};

public void setOnListRemovedListener(OnListRemovedListener listener){

this.mListener=listener;

}

public MyAdapter(List<NumberInfo> list,Context context) {

this.context=context;

this.list=list;

arrayAdapter=new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item, SPINNER_TIME);

arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

}

@Override

public int getCount() {

return list.size();

}

@Override

public Object getItem(int arg0) {

return null;

}

@Override

public long getItemId(int arg0) {

return 0;

}

@Override

public View getView(int position, View convertView, ViewGroup arg2) {

ViewHolder holder=null;

if(convertView==null){

convertView=LayoutInflater.from(context).inflate(R.layout.item, null);

holder=new ViewHolder();

holder.tv_position=(TextView) convertView.findViewById(R.id.tv_position);

holder.sp_type=(Spinner) convertView.findViewById(R.id.sp_type);

holder.sp_type.setOnItemSelectedListener(new MySpinnerListener(holder) {

@Override

public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,

long arg3, ViewHolder holder) {

TextView tv=(TextView) arg1;

int position=(Integer) holder.et_number.getTag();

NumberInfo n=list.get(position);

n.setType(tv.getText().toString());

list.set(position, n);

}

});

holder.et_number=(EditText) convertView.findViewById(R.id.et_number);

holder.et_number.setTag(position);

holder.et_number.addTextChangedListener(new MyTextWatcher(holder) {

@Override

public void afterTextChanged(Editable s, ViewHolder holder) {

int position=(Integer) holder.et_number.getTag();

NumberInfo n=list.get(position);

n.setNumber(s.toString());

list.set(position, n);

}

});

holder.btn_delete=(Button) convertView.findViewById(R.id.btn_delete);

holder.btn_delete.setOnClickListener(new MyOnClickListener(holder) {

@Override

public void onClick(View v, ViewHolder holder) {

if(mListener!=null){

int position=(Integer) holder.et_number.getTag();

list.remove(position);

mListener.onRemoved();  //通知主线程更新Adapter

}

}

});

convertView.setTag(holder);

}

else{

holder=(ViewHolder) convertView.getTag();

holder.et_number.setTag(position);

}

NumberInfo n=list.get(position);

holder.tv_position.setText(position+1+"");

holder.sp_type.setAdapter(arrayAdapter);

holder.et_number.setText(n.getNumber());

int p=getPositionForAdapter(position);

holder.sp_type.setSelection(p,true);

return convertView;

}

private int getPositionForAdapter(int po){

NumberInfo  t = list.get(po);

int p = 0;

for(int i=0;i<SPINNER_TIME.length;i++){

if(t.getType().equals(SPINNER_TIME[i])){

p = i;

}

}

return p;

}

//动态添加List里面数据

public void addItem(NumberInfo n){

list.add(n);

}

private abstract class MySpinnerListener implements OnItemSelectedListener{

private ViewHolder holder;

public MySpinnerListener(ViewHolder holder) {

this.holder=holder;

}

@Override

public void onNothingSelected(AdapterView<?> arg0) {

}

@Override

public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,

long arg3) {

onItemSelected(arg0, arg1, arg2, arg3, holder);

}

public abstract void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,long arg3,ViewHolder holder);

}

private abstract class MyTextWatcher implements TextWatcher{

private ViewHolder mHolder;

public MyTextWatcher(ViewHolder holder) {

this.mHolder=holder;

}

@Override

public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,

int arg3) {

}

@Override

public void onTextChanged(CharSequence arg0, int arg1, int arg2,

int arg3) {

}

@Override

public void afterTextChanged(Editable s) {

afterTextChanged(s, mHolder);

}

public abstract void afterTextChanged(Editable s,ViewHolder holder);

}

private abstract class MyOnClickListener implements OnClickListener{

private ViewHolder mHolder;

public MyOnClickListener(ViewHolder holder) {

this.mHolder=holder;

}

@Override

public void onClick(View v) {

onClick(v, mHolder);

}

public abstract void onClick(View v,ViewHolder holder);

}

private class ViewHolder{

TextView tv_position;

Spinner sp_type;

EditText et_number;

Button btn_delete;

}

//删除操作回调

public interface OnListRemovedListener{

public void onRemoved();

}

}

仔细看,其实只是对每一个可点击的事件重写了一遍,与原来不同的是,这里多了一个ViewHolder,为什么需要这个,因为这里面存储了每一个Item的Position信息.这样,就可以对item进行准确操作.从而不会发生错乱.

5.打开MainActivity.java

public class MainActivity extends ActionBarActivity implements OnClickListener,OnItemSelectedListener,OnListRemovedListener {

private List<NumberInfo> list=new ArrayList<NumberInfo>();

ListView lv;

Button btn_addRow;

MyAdapter mAdapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn_addRow=(Button) findViewById(R.id.btn_addRow);

btn_addRow.setOnClickListener(this);

lv=(ListView) findViewById(R.id.lv);

NumberInfo n=new NumberInfo();

n.setNumber("1");

n.setType("其他");

list.add(n);

mAdapter=new MyAdapter(list, this);

lv.setAdapter(mAdapter);

mAdapter.setOnListRemovedListener(this);

}

@Override

public void onClick(View v) {

if(v.getId()==R.id.btn_addRow){

NumberInfo n=new NumberInfo();

n.setNumber("");

n.setType("手机");

mAdapter.addItem(n);

mAdapter.notifyDataSetChanged();

}

}

@Override

public void onRemoved() {

mAdapter.notifyDataSetChanged();

}

@Override

public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,

long arg3) {

}

@Override

public void onNothingSelected(AdapterView<?> arg0) {

}

}

运行结果:



从此ListView再也不会错乱.

来自为知笔记(Wiz)

时间: 2025-01-08 13:04:05

android ListView与EditText共存错位的相关文章

android Listview 与 Scrollview 共存的一个较优良的解决方法

最近因为一个项目需要在Scrollview里面嵌套一个Listview,如果只是用android提供的ListView是什么效果大家肯定都已经知道了,经过摸索,自己找到了一个还算可以的解决方法,如下所示: 首先时自定义一个MyListview继承Listview ,重写他的onMeasure方法 ,让它不能滚动,代码如下: 基本这样就解决了它俩共存的问题,但是新问题来了,每次加载时,都是MyListview优先显示(而且好像是从MyListview底部向上开始显示的,因为我的测试数据太少,可能说

android listview滚动 edittext 数据就变了

可以明确,现在没有直接方法可以获得ListView中每一行EditText的值. 解决方案:重写BaseAdapter,然后自行获取ListView中每行输入的EditText值.     大概算法:重写BaseAdapter.getView函数,用一个数组存储EditText中的值,根据position即数组下标,在getView中动态更新EditText和动态获取EditText中的值.因为ListView中的item是复用的,如果不动态清空或动态获取EditText中值,就会出现数据紊乱,

android ListView中CheckBox错位的解决

貌似已经很晚了,但是还是想记下笔记,想让今天完满. 在ListView中加了checkBox,可是发现点击改变其选中状态的时候,发现其位置错乱.状态改变的并不是你选中的,百思不得其解.后面通过上网查资料,可是个说纷纭,但是我还是找到了解决办法. 在自定义的适配器中,对checkBox的设置如下: 记住两者的顺序,先对checkBox进行事件监听,再设置其状态.前提在布局中对checkBox的状态设为false. android ListView中CheckBox错位的解决,布布扣,bubuko.

android listview 异步加载图片并防止错位

网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertView 但没有异步操作也不会有问题. 我简单分析一下: 当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView. 当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Ite

Android ListView getView()方法重复调用导致position错位

问题现状:Android ListView getView()方法重复调用导致position错位 解决办法:把ListView布局文件的layout_height属性改为fill_parent或者match_parent. <ListView android:id="@+id/myphoto_listview" android:layout_width="match_parent" android:layout_height="match_pare

android listview 异步加载图片并防止错位+双缓存

网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertView 但没有异步操作也不会有问题. 我简单分析一下: 当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView. 当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Ite

【转】Android开发之ListView+EditText-要命的焦点和软键盘问题解决办法

Android开发之ListView+EditText-要命的焦点和软键盘问题解决办法 [原文链接] 这篇文章完美的解决了我几个月没结论的bug... 感谢热爱分享的技术达人~ 我是怎么走进这个大坑的..... 需求: 在listview中出一个EditText 接受用户输入消息. 前期解决方案: 给这个EditText绑定焦点事件.... 悲剧就开始了... 知道吗?当这个EditTextView被点了下,它的焦点就不断的获取,失去,获取,失去...  只点一下... 就频繁的重复..最后大部

android listview 每一项都是edittext 导致的坑爹问题 内容的保存和焦点,光标位置的设置

activity布局:布局很简单,只有一个listview <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_

Android: ListView与Button的共存问题解决

ListView 和 其它能触发点击事件的widget无法一起正常工作的原因是加入其它widget后,ListView的itemclick事件将无法触发,被其它widget的click事件屏蔽. 首先,说明一下,ListView中每一行包括以下三项: 一个ImageView, 一个TextView,一个ImageButton,依次排开. 以下是layout的内容,分为两部分: res/layout/main.xml <?xml version="1.0" encoding=&qu