自定义adapter是最常使用的,也是功能很强大的一种adapter,可以对每一个控件进行操作,也没有simpleadapter的map对象
存储那样复杂。。通过每一个对象,每一个JavaBean对象,里面存放每一行控件的内容,即每一个item。
先来看一下效果图。
一个item由2个TextView和1个ImageView组成。
自定义adapter的使用需要另外创建Javabean对象和子布局item的xml。
JavaBean:
package com.example.zdyadapter;
public class JBean {
private String xuhao;
private String name;
private int iv;
public JBean(String xuhao, String name, int iv) {
super();
this.xuhao = xuhao;
this.name = name;
this.iv = iv;
}
public JBean() {
super();
}
public String getXuhao() {
return xuhao;
}
public void setXuhao(String xuhao) {
this.xuhao = xuhao;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIv() {
return iv;
}
public void setIv(int iv) {
this.iv = iv;
}
@Override
public String toString() {
return "JBean [xuhao=" + xuhao + ", name=" + name + ", iv=" + iv + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + iv;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((xuhao == null) ? 0 : xuhao.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
JBean other = (JBean) obj;
if (iv != other.iv)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (xuhao == null) {
if (other.xuhao != null)
return false;
} else if (!xuhao.equals(other.xuhao))
return false;
return true;
}
}
Javabean用来填充内容。
自定义adapter的创建,需要继承BaseAdapter,重写里面的所有方法。
自定义adapter:
package com.example.zdyadapter;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class Zdyadapter extends BaseAdapter {
private MainActivity main;
private List datas;
public Zdyadapter(MainActivity main, List datas) {
super();
this.main = main;
this.datas = datas;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return datas.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return datas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = null;
ViewHolder vh = null;
JBean jb = datas.get(position);
if (convertView == null) {
vh = new ViewHolder();
v = main.getLayoutInflater().inflate(R.layout.item, null);
vh.tv = (TextView) v.findViewById(R.id.main_tv);
vh.tv1 = (TextView) v.findViewById(R.id.main_tv1);
vh.iv = (ImageView) v.findViewById(R.id.mian_iv);
v.setTag(vh);
} else {
v = convertView;
vh = (ViewHolder) v.getTag();
}
vh.tv.setText(jb.getXuhao());
vh.tv1.setText(jb.getName());
vh.iv.setImageResource(jb.getIv());
return v;
}
private static class ViewHolder {
public TextView tv, tv1;
public ImageView iv;
}
}
自定义adapter是重头戏,重写里面的方法有getCount,getItem,getItemId,getView,
其中getCount用来统计容器的大小,这里需要定义datas,是用List存放的,用datas.size来作为返回值。
getItem是用来获取每一个item,由于每一个item(行)中的控件都会被add到datas容器当中,所以datas.get(position)来获
取对应的item,作为返回值。。
getItemId用参数中的position作为返回值就可以了。
至于getView是需要注意的,里面的参数position不用多说,是对应的item位置, convertView是一种回收机制,大家想想,
item可以有成千上万个的时候,手机屏幕一次假如最多显示10个item,那么当下滑出现下一个也就是第11个item的时候,第一个
会被挡住滑出屏幕外面,手机需要再次重新绘制所有item么,那样岂不是太繁琐了,这个convertView其实就是最关键的部分 ,
原理上讲 当ListView滑动的过程中 会有item被滑出屏幕 而不再被使用 这时候Android会回收这个条目的view 这个view也就是这
里的convertView,所有convertView就是被回收的那个item,并不需要对所有的item进行操作。
JBean jb = datas.get(position);每一个Javabean对象即jb都被存放在datas这个容器,因为本身datas中就是List装的
JBean的类型,。
每一个item中的控件单独封装成了一个类(ViewHolder),便与优化-
v = main.getLayoutInflater().inflate(R.layout.item, null);
这个是用来获得子布局视图,通过v就可以操作对控件的初始化,获得子布局你得先通过Mainactivity,所以你得定义一个
Mainactivity,通过构造方法将Mainactivity传入,才可以在自定义的adapter这个页面中操作。。
v.setTag(vh);是将vh这个对象和v进行绑定,当convertView==null,也就是没有出现被回收的item时候,每一个item控件和被封
装在vh这个对象里,将v和vh绑定,如果出现convertView!=null,有item被回收时候,新出现的v将代替回收的item,之前绑定
的vh中的控件也通过gettag来再次已经初始化完毕。
当每一个item被绘制出来之后便可以settext或者图片资源等进行Javabean对象的内容添加进去。
不要忘记最后要return v;
这个也是一种套路,记住就可以了,不用每次来思考它。。。
item的xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal" >
<TextView
android:id="@+id/main_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/main_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<ImageView
android:id="@+id/mian_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
LinearLayout>
Mainactivity:
package com.example.zdyadapter;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView lv;
private List datas;
private Zdyadapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDatas();
initViews();
}
private void initViews() {
// TODO Auto-generated method stub
lv = (ListView) findViewById(R.id.main_lv);
adapter = new Zdyadapter(this, datas);
lv.setAdapter(adapter);
}
private void initDatas() {
// TODO Auto-generated method stub
datas = new ArrayList();
datas.add(new JBean("1", "剪刀", R.drawable.a));
datas.add(new JBean("2", "八叉", R.drawable.b));
datas.add(new JBean("3", "问号", R.drawable.c));
datas.add(new JBean("4", "与", R.drawable.d));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
里面的图片a,b,c,d也是提前放进res下面的drawable-hdpi中的。
activity_main的xml中只存放的一个ListView,这里就不上图了。