在一个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再也不会错乱.
- [问题]Android listView item edittext 不能调用软键盘输入法
android listview item edittext not softkeyboard edittext可以获取焦点, 可以触发事件, 但是就是不能调用输入法, 不知道为什么? 难道不能在i ...
- 解决Android ListView 和 ScrollView 共存时冲突 问题 方法其一
转载请注明出处: http://www.goteny.com/articles/2013/11/8.html http://www.cnblogs.com/zjjne/p/3428480.html 当 ...
- Android ListView用EditText实现搜索功能
前言 最近在开发一个IM项目的时候有一个需求就是,好友搜索功能.即在EditText中输入好友名字,ListView列表中动态展示刷选的好友列表.我把这个功能抽取出来了,先贴一下效果图: 分析 在查阅 ...
- 【转】Android开发之ListView+EditText-要命的焦点和软键盘问题解决办法
Android开发之ListView+EditText-要命的焦点和软键盘问题解决办法 [原文链接] 这篇文章完美的解决了我几个月没结论的bug... 感谢热爱分享的技术达人~ 我是怎么走进这个大坑的 ...
- Android ListView getView()方法重复调用导致position错位
问题现状:Android ListView getView()方法重复调用导致position错位 解决办法:把ListView布局文件的layout_height属性改为fill_parent或者m ...
- [Android分享] 【转帖】Android ListView的A-Z字母排序和过滤搜索功能
感谢eoe社区的分享 最近看关于Android实现ListView的功能问题,一直都是小伙伴们关心探讨的Android开发问题之一,今天看到有关ListView实现A-Z字母排序和过滤搜索功能 ...
- 【转】android ListView 几个重要属性
android ListView 几个重要属性 分类: Android2012-03-08 19:25 19324人阅读 评论(5) 收藏 举报 listviewandroid活动javalistnu ...
- android ListView 中getview学习总结
最近在做android相关的开发,ListView中有一个图片错位的问题,今天查了很多人写的一些东西,所以记录下来,算是一种加深理解吧. ListView是一个非常常用的控件,功能可以扩展的很丰富,而 ...
- android ListView的介绍和优化
xml设计 <?xml version="1.0"?> -<RelativeLayout tools:context=".MainActivity&qu ...
随机推荐
- CDH4.5.0下安装snappy
编译源代码 http://www.cnblogs.com/chengxin1982/p/3862289.html 测试参考 http://blog.jeoygin.org/2012/03/java-c ...
- Git笔记(pull/push)
一.从远程服务器上获取分支 git pull <远程主机名> <远程分支>:<本地分支> 例如 git pull origin master:loacal_bran ...
- 第一个C#程序Hello World
一.编写第一个C#程序——Hello World1. 启动Microsoft Visual Studio 2010.2. 点击“文件”菜单,选择“新建”项,在弹出的子菜单中选择“项目”命令.3. 弹出 ...
- 开发SDK注意事项
1. 修改类别文件名及类别方法. 开发SDK时通常会用到比较多的第三方的类别方法, 这样的话, 开发者在使用你的SDK时, 因为他可能也会加一些第三方的开源库, 比如都使用了NSString的md5类 ...
- 用IDEA搭建基于maven的springboot项目
第一步:新建一个Project 第二步:选择Spring Initializr和SDK 然后next 第三步:修改Group和Artifact 第四步:按自己的需求选,这里我选的是Web,然后ne ...
- Fetch 头像剪切修改
前言:通过Input file upload 图片到canvas 中进行剪裁,react 可以引入react-avatar-editor对图片进行剪裁 react-avatar-editor的使用 & ...
- 洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)
题目背景 提示:原 P1829 半数集问题 已经迁移至 P1028 数的计算 题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a ...
- 用servlet设计OA管理系统时遇到问题
如果不加单引号会使得除变量和int类型的值不能传递 转发和重定向的区别 转发需要填写完整路径,重定向只需要写相对路径.原因是重定向是一次请求之内已经定位到了服务器端,转发则需要两次请求每次都需要完整的 ...
- 给网站添加icon图标
只需制成ico结尾的图片即可
- linux 开机自启动 Tomcat
1.修改脚本文件rc.local:vim /etc/rc.d/rc.local 这个脚本是使用者自定的开机启动程序,可以在里面添加想在系统启动之后执行的脚本或者脚本执行命令 2.添加如下内容: exp ...