本人水平有限,文章中如果出现什么不正确或者模糊的地方,还请各位小伙伴留下评论,多多指教 : )
概述
本栗子通过对EditText监听,根据用户输入的数据,动态地改变ListView的内容。
效果图
主要类说明:
这个栗子只有3个类:
Bean:是一个封装类,用于封装基本的数据。
MainActivity:主程序
UserListViewAdapter:看名字也知道,是继承自BaseAdapter的listView适配器
思路
整体思路如下图所示:
为一个ListView设置2个Adapter,并为EditText设置输入的事件监听。
当用户无输入时,listView加载hintAdapter;
当用户输入时,listView加载autoAdapter;
在这里需要注意 一下,关于Adapter的notifyDataSetChanged()方法。在改变ListView的数据源时,不能改变Adapter的引用,否则notifyDataSetChanged()将无法成功。
代码
布局文件:
activity_main
<?xml version="1.0" encoding="utf-8"?>
<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_parent"
android:paddingLeft="5dp"
android:paddingRight="5dp"
tools:context="com.example.dell.imooc_listviewtest.MainActivity">
<LinearLayout
android:id="@+id/ly_top"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ImageView
android:src="@drawable/search_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/id_editText"/>
<EditText
android:id="@+id/id_editText"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:hint="input"/>
<ImageView
android:id="@+id/id_img_delete"
android:src="@drawable/iv_delete_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ListView
android:id="@+id/id_listView"
android:layout_below="@+id/ly_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
主页面的布局文件,主要就是EditText和ListView
list_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/id_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/id_item_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="@+id/id_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
自定义Adapter中item的外观
class Bean
public class Bean {
private int num;
private String name;
public Bean(int num, String name) {
this.num = num;
this.name = name;
}
public int getNum() {
return num;
}
public String getName() {
return name;
}
public void setNum(int num) {
this.num = num;
}
public void setName(String name) {
this.name = name;
}
}
数据封装类
自定义的适配器UserListViewAdapter
public class UserListViewAdapter extends BaseAdapter {
private List<Bean> mDatas;
private LayoutInflater mInflater;
public UserListViewAdapter(Context context, List<Bean> datas) {
mInflater=LayoutInflater.from(context);
mDatas=datas;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object getItem(int i) {
return mDatas.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder=new ViewHolder();
if(view==null){
view =mInflater.inflate(R.layout.list_item,null);
viewHolder.imageView= (ImageView) view.findViewById(R.id.id_img);
viewHolder.name= (TextView) view.findViewById(R.id.id_item_name);
viewHolder.id= (TextView) view.findViewById(R.id.id_item_id);
view.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) view.getTag();
}
viewHolder.name.setText(mDatas.get(i).getName());
viewHolder.id.setText(mDatas.get(i).getNum()+" ");
return view;
}
private class ViewHolder{
ImageView imageView;
TextView name;
TextView id;
}
}
MainActivity代码
public class MainActivity extends AppCompatActivity {
private List<Bean> hintLists=new ArrayList<>();
private List<Bean> autoLists=new ArrayList<>();
private UserListViewAdapter autoAdapter;
private UserListViewAdapter hintAdapter;
private ListView mListView;
private EditText mEditText;
private ImageView img_delete;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDatas();
initViews();
}
private void initDatas() {
//初始化数据
Bean b1=new Bean(1,"NO12123");
hintLists.add(b1);
Bean b2=new Bean(2,"NO12143");
hintLists.add(b2);
Bean b3=new Bean(3,"NO12145");
hintLists.add(b3);
Bean b4=new Bean(4,"NO22123");
hintLists.add(b4);
Bean b5=new Bean(5,"NO22323");
hintLists.add(b5);
Bean b6=new Bean(6,"NO32123");
hintLists.add(b6);
//初始化适配器
hintAdapter=new UserListViewAdapter(MainActivity.this,hintLists);
autoAdapter=new UserListViewAdapter(MainActivity.this,autoLists);
}
private void initViews() {
mListView= (ListView) findViewById(R.id.id_listView);
mEditText= (EditText) findViewById(R.id.id_editText);
img_delete= (ImageView) findViewById(R.id.id_img_delete);
//让删除图片显示不可见
img_delete.setVisibility(View.INVISIBLE);
img_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mEditText.setText("");
}
});
mEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mEditText.getText().toString().equals("")&&mListView.getAdapter()==null){
mListView.setAdapter(hintAdapter);
Log.d("----","editText is click & mListView.setAdapter(hintAdapter);");
}
}
});
mEditText.addTextChangedListener(new TextWatcher(){
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(charSequence.toString().equals("")){
//无输入时,隐藏删除按钮
img_delete.setVisibility(View.INVISIBLE);
mListView.setAdapter(hintAdapter);
Log.d("----", "adapter :"+mListView.getAdapter().toString());
}else{
//有输入时,显示删除文字按钮
img_delete.setVisibility(View.VISIBLE);
mListView.setAdapter(autoAdapter);
//模拟数据变化
autoLists.clear();
for(int j=0;j<hintLists.size();j++){
if(hintLists.get(j).getName().contains(charSequence)){
autoLists.add(hintLists.get(j));
}
}
//更新listView
autoAdapter.notifyDataSetChanged();
Log.d("----", "adapter :" + mListView.getAdapter().toString());
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
}
最后在强调一下关于ListView的数据更新,如果更新无效,往往是如下几个问题:
1、数据源没有更新,调用notifyDataSetChanged无效。
2、数据源更新了,但是它指向新的引用,调用notifyDataSetChanged无效。比如原来Adapter绑定是数据是arrayList1,后来绑定为arrayList2,那么当arrayList2的数据发送变化后,notifyDataSetChanged无效,因为Adapter的引用依然在arrayList1上。
3、数据源更新了,但是adpter没有收到消息通知,无法动态更新列表。
至此,一个简单的EditText实现输入搜索就完成了,只不过在实际开发当中,我的数据不会是实现就写好了的,可能会从服务器获取数据,然后在加载到适配器当中。