ListView一般是展示图标、文字,用户点击Item后,触发某些事件响应,很少会使用EditText,刚使用了下,发现还是有一点小坑的,记录下来,防止以后再踩坑里。
具体的解释后面看看是不是需要补上,暂时把带有注释的完整代码放上,保证能够直接跑起来就好。
首先activity里面的布局如下activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
上面只是展示一个ListView,match_parent,这里没的说,比较简单。
然后是ListView中,每一个Item的布局my_item.xml:
<?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" > <ImageView android:id="@+id/my_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="image_desc"/> <TextView android:id="@+id/my_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="10dip" /> <EditText android:id="@+id/my_edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginRight="10dip" android:hint="input what you want" > </EditText> </LinearLayout>
item中,展示一个图标,一个TextView展示框,然后右边放一个能够编辑的输入框,也是比较简单的。
一个Item中,包含图片、Textview,EditText,放到一个类中来存储,MyItem.java定义如下:
package com.example.mylistview; public class MyItem { private int imageId;//图片展示 private String descItem;//item描述 private String editItem;//item编辑框 public MyItem(int id,String desc){ imageId=id; descItem=desc; } public int getImageId() { return imageId; } public void setImageId(int imageId) { this.imageId = imageId; } public String getDescItem() { return descItem; } public void setDescItem(String descItem) { this.descItem = descItem; } public String getEditItem() { return editItem; } public void setEditItem(String editItem) { this.editItem = editItem; } }
上面这个类,也是简单的很,上述的这些,都是最最简单的基础定义,下面是核心的adapter、activity。
首先是MainActivity.java文件
package com.example.mylistview; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { private List<MyItem> itemList = new ArrayList<MyItem>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);//加载布局文件 initMyItems();//初始化List // 自定义或者原有的适配器,其参数都是:上下文,布局ID,范型列表list MyAdapter adapter = new MyAdapter(MainActivity.this, R.layout.my_item, itemList); ListView listView = (ListView) findViewById(R.id.list_view); listView.setAdapter(adapter);//渲染展示adapter内容 } public void initMyItems() { MyItem a = new MyItem(R.drawable.ic_launcher, "a_item"); itemList.add(a); MyItem b = new MyItem(R.drawable.ic_launcher, "b_item"); itemList.add(b); MyItem c = new MyItem(R.drawable.ic_launcher, "c_item"); itemList.add(c); MyItem d = new MyItem(R.drawable.ic_launcher, "d_item"); itemList.add(d); MyItem e = new MyItem(R.drawable.ic_launcher, "e_item"); itemList.add(e); MyItem f = new MyItem(R.drawable.ic_launcher, "f_item"); itemList.add(f); MyItem g = new MyItem(R.drawable.ic_launcher, "g_item"); itemList.add(g); MyItem h = new MyItem(R.drawable.ic_launcher, "h_item"); itemList.add(h); MyItem i = new MyItem(R.drawable.ic_launcher, "i_item"); itemList.add(i); MyItem j = new MyItem(R.drawable.ic_launcher, "j_item"); itemList.add(j); MyItem k = new MyItem(R.drawable.ic_launcher, "k_item"); itemList.add(k); MyItem l = new MyItem(R.drawable.ic_launcher, "l_item"); itemList.add(l); MyItem m = new MyItem(R.drawable.ic_launcher, "m_item"); itemList.add(m); MyItem n = new MyItem(R.drawable.ic_launcher, "n_item"); itemList.add(n); MyItem o = new MyItem(R.drawable.ic_launcher, "o_item"); itemList.add(o); MyItem p = new MyItem(R.drawable.ic_launcher, "p_item"); itemList.add(p); MyItem q = new MyItem(R.drawable.ic_launcher, "q_item"); itemList.add(q); MyItem r = new MyItem(R.drawable.ic_launcher, "r_item"); itemList.add(r); MyItem s = new MyItem(R.drawable.ic_launcher, "s_item"); itemList.add(s); } }
下面是MyAdapter.java的内容
package com.example.mylistview; import java.util.List; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.View.OnTouchListener; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; public class MyAdapter extends ArrayAdapter<MyItem> { // 布局ID private int resourceId; // 点击过的item,用于焦点获取 private int touchItemPosition = -1; // 参数:上下文,布局ID,范型列表 public MyAdapter(Context context, int textViewResourceId, List<MyItem> objects) { super(context, textViewResourceId, objects); // 第二个参数很重要,是listview中每一个item的布局 resourceId = textViewResourceId; } @Override public View getView(int position, View convertView, ViewGroup parent) { // 通过position,来获取当前的范型,也就是MyItem,为的是获取内容,得到传递到adapter中的MyItem数组中的一个 MyItem myItem = getItem(position); View view; ViewHolder viewHolder; // 参数convertView其实时用来缓存View的,如果曾经加载过当前position的View,会缓存下来的,无需每次都去获取新的布局 // 该参数用于将之前加载好的布局进行缓存,便于之后进行重用 if (convertView == null) { // 通过LayoutInflater来加载传递到适配器中的布局,也就是每一项item包括什么东西 view = LayoutInflater.from(getContext()).inflate(resourceId, null); // 除了布局可以缓存处理,还可以将布局中的控件进行缓存处理,viewHolder就是用于缓存的 viewHolder = new ViewHolder(); viewHolder.my_image = (ImageView) view.findViewById(R.id.my_image); viewHolder.my_desc = (TextView) view.findViewById(R.id.my_desc); viewHolder.my_edit = (EditText) view.findViewById(R.id.my_edit); // 设置点击的监听,用于获取用户点击的是第几个item viewHolder.my_edit.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { touchItemPosition = (Integer) view.getTag(); return false; } }); viewHolder.myTextWatcher = new MyTextWatcher(); viewHolder.my_edit.addTextChangedListener(viewHolder.myTextWatcher); viewHolder.updatePosition(position); // 把查找的view缓存起来方便多次重用 view.setTag(viewHolder); } else { view = convertView; viewHolder = (ViewHolder) view.getTag(); viewHolder.updatePosition(position);//这行非常重要,如果不加,会导致输入到底X行,却展示到了Y行的输入框,也就是无论是初次设置View还是使用缓存的View,都要重新更新position信息 } // 向当前的view里面,塞入数据 viewHolder.my_image.setImageResource(myItem.getImageId()); viewHolder.my_desc.setText(myItem.getDescItem()); viewHolder.my_edit.setText(myItem.getEditItem()); // 将当前的position放到中,再EditText的touch响应事件中,取出来,赋值给touchItemPosition // 也就是,用户点击输入框时,需要获取点击的第几个item的框,怎么获取,从tag取出来,谁放进去,初始化的时候,这里放进去 viewHolder.my_edit.setTag(position); // 默认是-1,肯定不等于,无需有焦点,当点击过输入框时,会进行赋值说明用户点击的是第几个,这时候会调用清除焦点, // 然后唤起键盘,页面刷新时,每一个Item都刷新,就会重新进来,而touchItemPosition有值,就会执行下面的请求焦点的代码 if (touchItemPosition == position) { viewHolder.my_edit.requestFocus(); viewHolder.my_edit.setSelection(viewHolder.my_edit.getText() .length()); } else { viewHolder.my_edit.clearFocus(); } return view; } static final class ViewHolder { ImageView my_image; TextView my_desc; EditText my_edit; MyTextWatcher myTextWatcher; public void updatePosition(int myPosition) { myTextWatcher.updateWatcherPosition(myPosition); } } class MyTextWatcher implements TextWatcher { private int currentPosition; public void updateWatcherPosition(int myPosition) { currentPosition = myPosition; } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { MyItem myItem = getItem(currentPosition); myItem.setEditItem(s.toString());//每次变化,设置对应的类的editItem } } }
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦