为了账号安全,请及时绑定邮箱和手机立即绑定

android:ListView中使用EditText,遇到的坑,获取点击焦点、保存输入文本的demo

标签:
Android

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

}


原文链接:http://www.apkbus.com/blog-894806-63273.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消