前面我们学习了SimpleAdapter这个利用键值对把数据映射到控件上的这种适配器,但是在实际的安卓开发中更多的是用的下面要介绍的自定义适配器。因为SimpleAdapter不适合较为复杂的业务逻辑。
自定义Adapter的步骤
1.继承BaseAdapter:建立类,继承BaseAdapter,需要重写四个抽象方法,添加数据集合和反射器(inflater)实现构造器和setter方法(主要是传入数据);
2.实现getView方法(重要):实现四个抽象方法中的getView:首先反射行布局,获取各个布局,然后给布局赋值;
3.关联ListView:实例化适配器,关联ListView。
getView方法的含义:它是系统渲染时调用的方法。系统显示什么数据,就是看该方法返回什么样的View。然而这个View这个方法前面时没有了,这时候就要靠Inflater这个反射器,来将XML文件,转化成一个实际的View。
下面粘一下效果图:
下面粘一下Demo的代码,这里是在上一次的工程基础上操作的,所以只粘贴关键部分了
MyAdapter.java
package com.example.dreamcreationman.listview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import java.util.Map;
/**
* Created by Dream on 2017/2/21.
*/
public class MyAdapter extends BaseAdapter {
List<Map<String,Object>> list;
LayoutInflater inflater;
public MyAdapter(Context context) {
this.inflater=LayoutInflater.from(context);
}
public void setList(List<Map<String, Object>> list) {
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view= inflater.inflate(R.layout.ti,null);
ImageView logo= (ImageView) view.findViewById(R.id.logo);
TextView name = (TextView) view.findViewById(R.id.name);
TextView version = (TextView) view.findViewById(R.id.version);
TextView size = (TextView) view.findViewById(R.id.size);
Map map=list.get(position);
logo.setImageResource((Integer) map.get("logo"));
name.setText((String) map.get("name"));
version.setText((String) map.get("version"));
size.setText((String) map.get("size"));
return view;
}
}
MainActivity.java
package com.example.dreamcreationman.listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView= (ListView) findViewById(R.id.lv);
List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
Map<String,Object> map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","Android");
map.put("version","v1.0");
map.put("size","大小:11M");
list.add(map);
map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","Java");
map.put("version","v2.0");
map.put("size","大小:12M");
list.add(map);
map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","C++");
map.put("version","v3.0");
map.put("size","大小:13M");
list.add(map);
map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","C");
map.put("version","v4.0");
map.put("size","大小:14M");
list.add(map);
MyAdapter myAdapter=new MyAdapter(this);
myAdapter.setList(list);
listView.setAdapter(myAdapter);
}
}
中间有些采用到前面的内容,参见笔者以前的笔记ListView和简单适配器
ListView的常用事件
onItemClick:item项的点击事件
onItemLongClick:item项的长按事件
代码我也粘在这:
package com.example.dreamcreationman.listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView= (ListView) findViewById(R.id.lv);
List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
Map<String,Object> map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","Android");
map.put("version","v1.0");
map.put("size","大小:11M");
list.add(map);
map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","Java");
map.put("version","v2.0");
map.put("size","大小:12M");
list.add(map);
map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","C++");
map.put("version","v3.0");
map.put("size","大小:13M");
list.add(map);
map=new HashMap<String, Object>();
map.put("logo",R.mipmap.ic_launcher);
map.put("name","C");
map.put("version","v4.0");
map.put("size","大小:14M");
list.add(map);
MyAdapter myAdapter=new MyAdapter(this);
myAdapter.setList(list);
listView.setAdapter(myAdapter);
listView.setOnItemClickListener(this);
listView.setOnItemLongClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(this,"点击"+position,Toast.LENGTH_SHORT).show();
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(this,"长按"+position,Toast.LENGTH_SHORT).show();
return false;
}
}
这里有两个点需要注意:
1.长按和点击事件实现的接口不同;
2.长按实现的时候返回值True或者false可以简单理解为希望长按事件后不再触发点击事件,就将值设置为true。false代表不笑话事件,继续传事件;而true表示消化事件,当然设置true也会导致长按过久以后的背景色变化事件不再进行,这也是设置为true的副作用。
好了有关Android Studio里自定义适配器的分享就到这里了,欢迎在评论区留言指出错误,希望和大家一起进步!
谢谢观看。