说实话这个标题的博文都是被大家写透了的。但是我依然是相信只有自己总结的才是自己的。所以还是要留下笔记。
首先来说,在安卓开发中很多时候都需要将一些内容以列表的形式表现出来。所以列表listview是必不可少的,但是用listview又必须注意的是数据绑定问题,这就是本文的核心,listview的万用数据绑定。
首先来看下什么是listview,他是:以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。
列表的显示需要三个元素:
1.ListVeiw 用来展示列表的View。
2.适配器(adapter) 用来把数据映射到ListView上的中介。
3.数据 具体的将被映射的字符串,图片,或者基本组件。
具体listview有什么分类,都不是本文要阐述的,需要这些知识的请百度listview,第一篇博文就很不错。
下面开始本文干货:
首先咱先看看别人的项目(下载地址:http://download.csdn.net/detail/qq_22603017/8816531),我们可以看到这个项目运行的效果如图。确实运行后 我们发现我们的listview和系统的默认效果不一样。而且最重要的是我们发散性的想一下,既然这里的后面能实现按钮,那肯定也能实现其他的。
首先咱先分解下他的布局,顾名思义我们只需拿到他的listview_item.xml就明白,如下:
根据这个布局文件,咱可以看到,我们的listview的变化,就是listview_item的多重排列和组合。
既然我们已经明白了listview的变化,追本朔源就是我辈本则。
打开安卓代码,
package com.example.onclicklistviewitem;
import java.util.ArrayList;
import android.os.Bundle;
import android.widget.ListView;
import android.app.Activity;
public class MainActivity extends Activity implements AdpterOnItemClick{
private ListView listView;
private ListViewAdpter myAdpter;
private ArrayList<PerSon> arrayPerson = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.setIntView();
}
/**
* 初始化
*/
private void setIntView() {
listView = (ListView) findViewById(R.id.listview);
arrayPerson = new ArrayList<PerSon>();
for (int i = 0; i < 10; i++) {
PerSon person = new PerSon();
person.setName("张"+i);
person.setAge(20+i);
person.setSex("男");
arrayPerson.add(person);
}
myAdpter = new ListViewAdpter(this, arrayPerson);
myAdpter.onListener(this);
listView.setAdapter(myAdpter);
}
@Override
public void onAdpterClick(int which,final int postion) {
switch (which) {
case R.id.btAdd:
PerSon person = arrayPerson.get(postion);
person.setAge(person.getAge()+1);
//myAdpter.notifyDataSetChanged();这里如果点击速度过快的话,getView重绘时会使数据加载混乱,所以不能用myAdpter.notifyDataSetChanged();
//应该写一个独立的方法 局部刷新
break;
case R.id.btReduce:
PerSon person1 = arrayPerson.get(postion);
person1.setAge(person1.getAge()-1);
break;
case R.id.btKey:
final DialogNumberInput dlg = new DialogNumberInput(MainActivity.this, R.style.DialogFloating, getString(R.string.strtitle));
dlg.mSureListener = new DialogNumberInput.OnSureListener() {
@Override
public void onSure(String input) {
String strAge = input;
PerSon person1 = arrayPerson.get(postion);
person1.setAge(Integer.parseInt(strAge));
myAdpter.notifyDataSetChanged();
dlg.dismiss();
}
};
dlg.show();
break;
default:
break;
}
}
}
我们发现在oncreat()方法里面调用了个setIntView()方法,仔细剖析setIntView方法发现,这里无外乎就是初始化listview控件(给listview设定adapter)。既然我们这里发现初始化控件并无变化,那么说明listview是没变化的,变化的是adapter(适配器)。
要明白这里的变化我们只有对adapter的变化穷究到底。
继续代码走起:
package com.example.onclicklistviewitem;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
interface AdpterOnItemClick{
void onAdpterClick(int which,int postion);
}
public class ListViewAdpter extends BaseAdapter{
private ArrayList<PerSon> arrayPerson;
private LayoutInflater inflater;
private AdpterOnItemClick myAdpterOnclick;
Button bt =null;
int p = 0;
public ListViewAdpter(Context context,ArrayList<PerSon> arrayPerson) {
this.arrayPerson = arrayPerson;
inflater = LayoutInflater.from(context);
}
public void onListener(AdpterOnItemClick listener){
this.myAdpterOnclick = listener;
}
@Override
public int getCount() {
return arrayPerson.size();
}
@Override
public Object getItem(int position) {
return arrayPerson.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
Holder holder = null;
if (view == null) {
holder = new Holder();
view = inflater.inflate(R.layout.listview_item, null);
holder.txName = (TextView) view.findViewById(R.id.txName);
holder.txAge = (TextView) view.findViewById(R.id.txAge);
holder.btAdd = (Button) view.findViewById(R.id.btAdd);
holder.btReduce = (Button) view.findViewById(R.id.btReduce);
holder.btKey = (Button) view.findViewById(R.id.btKey);
view.setTag(holder);
}else {
holder = (Holder) view.getTag();
}
holder.txName.setText(arrayPerson.get(position).getName());
holder.txAge.setText(String.valueOf(arrayPerson.get(position).getAge()));
/**
* 这里作标志
*/
holder.btAdd.setTag(position);
holder.btReduce.setTag(position);
holder.btKey.setTag(position);
final int fpostion = position;
final Holder fholder = holder;
holder.btAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (myAdpterOnclick != null) {
int which = v.getId();
myAdpterOnclick.onAdpterClick(which, fpostion);
showAge(fpostion, fholder);
}
}
});
holder.btReduce.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (myAdpterOnclick != null) {
int which = v.getId();
myAdpterOnclick.onAdpterClick(which, fpostion);
showAge(fpostion, fholder);
}
}
});
holder.btKey.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (myAdpterOnclick != null) {
if (myAdpterOnclick != null) {
int which = v.getId();
myAdpterOnclick.onAdpterClick(which, fpostion);
}
}
}
});
return view ;
}
public static class Holder{
TextView txName;
TextView txAge;
Button btAdd ;
Button btReduce ;
Button btKey ;
}
/**局部刷新
* 刷新年龄
*/
public void showAge(int index ,Holder holder){
if (holder!=null) {
int age = arrayPerson.get(index).getAge();
holder.txAge.setText(String.valueOf(age));
}
}
}
首先咱可以从上面看到,很多关于事件响应的的东西我们可以忽略不看,咱只看上下文传送,毕竟只有上下文才是安卓各个东西之间的连接点。
可以看到我们的context是给了我们的inflater,从安卓的界面布局生效规则来看,我们这里重写的getView实在构造方法中被调用的。重点又在于,我们在getView中实例化的view为空,所以我们为了实现布局,只有将view设定为我们的布局文件(view = inflater.inflate(R.layout.listview_item, null);),当我们的view获得布局的时候,我们将view返回给getview方法,我们的布局就生效了。
由于今晚暂忙,咱先匆忙结束,明晚再来详细剖析,并将他用到我们的项目中。
view = inflater.inflate(R.layout.listview_item, null);