这篇文章主要是总结ListView的使用:
首先来说说ListView,几乎所有的app都在使用listview,所以熟练使用ListView是作为Android移动开发必不可少的。
- Adapter
- ViewHolder
- setEnpty()
- 自动隐藏,显示的ListView
- 聊天界面的ListView
Adapter
对于ListView而言,Adapter就是“弹夹”,給ListView添加数据和视图,这里只讲解继承自BaseAdapter的自定义Adapter。模版代码如下:
public class ViewHolderAdapter extends BaseAdapter {
private List<String> list;
private LayoutInflater inflater;
public ViewHolderAdapter(Context context, List<String> list) {
this.list = list;
inflater = LayoutInflater.from(context);
}
//返回item个数
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
//返回position对应的数据
@Override
public Object getItem(int position) {
return list.get(position);
}
//返回position
@Override
public long getItemId(int position) {
return position;
}
//返回item的视图View
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_itm, null);
viewHolder = new ViewHolder();
viewHolder.iv = (ImageView)
convertView.findViewById(R.id.list_iv);
viewHolder.tv = (TextView)
convertView.findViewById(R.id.list_tv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.iv.setText(list.get(position));
viewHolder.tv.setImageResource(R.mipmap.ic_launcher);
return convertView;
}
public final class ViewHolder {
private ImageView iv;
private TextView tv;
}
ViewHolder
如上代码中ViewHolder可以提高视图的重复利用,提高效率。通常都是在adapter中创建内部类。参数就是我们item view中的对应的控件。
setEnpty()
在实际开发中,我们都知道,当网络不好的时候,我们的app是无法从服务端获取数据的,那么这时就需要加载不同的布局給用户。
这里就需要到setEnpty(),使用代码如下
adapter = new ViewHolderAdapter(this, dataList);
lv.setAdapter(adapter);
lv.setEmptyView(findViewById(R.id.empty_view));
添加我们要展示的控件,当然这里可以自定控件来实现布局的加载。
处理没有数据时应该加载的布局
自动隐藏,显示的ListView
这里在Activity上实现View.OnTouchListener,然后重写onTouch方法,在方法中我们判断ActionBar的显示和隐藏。把如下代码中的bin换为,你想隐藏,显示的控件。
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mFirstY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
mCurrentY = (int) event.getY();
if (mCurrentY - mFirstY > mTouchSlop) {
direction = 0;//down
} else if (mFirstY - mCurrentY > mTouchSlop) {
direction = 1;//up
}
Log.e(TAG, "direction==" + direction);
if (direction == 0) {
if (btn.getVisibility() != View.VISIBLE) {
btn.setVisibility(View.VISIBLE);
}
}
if (direction == 1) {
if (btn.getVisibility() != View.GONE) {
btn.setVisibility(View.GONE);
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
return false;//这里必须返回false,不然listView的基本功能都没有了
}
然后就是在onCreate中使用listview的setonTouchListener.
//获取系统认为的最低滑动距离 mTouchSlop==36
mTouchSlop = ViewConfiguration.get(this).getScaledEdgeSlop();
lv.setOnTouchListener(this);
聊天界面的ListView
最后再实现一个类似于聊天界面,简单实现一下。
首先我们需要两个itemViewLayout.代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/icon_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/text_in"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/icon_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@android:color/black"
android:textColor="@android:color/white"
android:textSize="20sp" />
</RelativeLayout>
因为两个除位置不同其它都相同,所以这里只贴出一个的代码。
然后,就是Adapter的实现,与我们以往的同这里需要多实现两个方法,
//获取listView中position的布局类型
@Override
public int getItemViewType(int position) {
return data.get(position).getType();
}
//获取listView中的布局类型个数
@Override
public int getViewTypeCount() {
return 2;
}
在getView中做相应的改变,我们的Adapter中代码如下:
public class ChartListAdapter extends BaseAdapter {
private List<ChartBean> data;
private LayoutInflater inflater;
public ChartListAdapter(Context context, List<ChartBean> list) {
this.data = list;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return data == null ? 0 : data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=null;
if (convertView == null) {
if (getItemViewType(position)==0){
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item_itemin, null);
ImageView iv = (ImageView) convertView.findViewById(R.id.icon_in);
TextView tv = (TextView) convertView.findViewById(R.id.text_in);
viewHolder.setIv(iv);
viewHolder.setTv(tv);
}
if (getItemViewType(position)==1){
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.chat_item_itemout, null);
ImageView iv = (ImageView) convertView.findViewById(R.id.icon_out);
TextView tv = (TextView) convertView.findViewById(R.id.text_out);
viewHolder.setIv(iv);
viewHolder.setTv(tv);
}
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setText(data.get(position).getText());
viewHolder.iv.setImageBitmap(data.get(position).getIcon());
return convertView;
}
//获取listView中position的布局类型
@Override
public int getItemViewType(int position) {
return data.get(position).getType();
}
//获取listView中的布局类型个数
@Override
public int getViewTypeCount() {
return 2;
}
public final class ViewHolder {
ImageView iv;
TextView tv;
public ImageView getIv() {
return iv;
}
public void setIv(ImageView iv) {
this.iv = iv;
}
public TextView getTv() {
return tv;
}
public void setTv(TextView tv) {
this.tv = tv;
}
}
}
如果你已经看完上面的代码,会发现有一个ChartBean,这是什么呢?实际上这就是一个模拟聊天信息中的数据的一个基本类,
public class ChartBean {
int type;
private String text;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Bitmap getIcon() {
return icon;
}
public void setIcon(Bitmap icon) {
this.icon = icon;
}
private Bitmap icon;
}