ListView

  • 1.ListView和Adapter

    • 1)ListView就是一个能数据集合以动态滚动的方式展示到用户界面上的View,即:以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。
    • 2)ListView和数据是分开的,不直接接触。而是通过Adapter(适配器)加载到屏幕。也就是说Adapter相当于是数据和View之间的桥梁。Adapter负责为每一个数据项制作View。
  • 2.ListView工作原理

    • 1)在运行时ListView会针对数据项向Adapter要View,从而来加载到界面上,那么,难道每一个item,Adapter都会重新创建一个视图吗?答案很明显是不可能的。
    • 2)为了能够更快更省空间的显示,Android准备了一个叫做Recycler(循环)的组件。假如你的屏幕只能显示七个item。那么ListView只会创建八个item的视图。当第一个item出去,离开屏幕的时候,这个item的view就会被拿来重用,显示下一个item的内容。
  • 3.继承BaseAdapter来使用ListView

    • 1)BaseAdapter是个抽象类,继承它能很方便的来使用ListView
      步骤:
    • 2)MyDataAdapter extends BaseAdapter继承适配器类
    • 3)添加数据源引用
      计数器:counter = 0
      数据源:List mData = null;
//上下文:Context mContext = null
//构造函数,两个参数一个上下文,一个数据源,一个计数器设置
//覆写如下回调函数
//1.数据源中的数据对象个数
public int getCount() {
    return mData.size();
}
//2.指定位置处的具体数据源对象
public Object getItem(int position) {
    return mData.get(position);
}
//3.数据源对象的Id,如果数据源对象自己没有定义Id,则可以简单地返回其在数据源中的位置
public long getItemId(int position) {
    return position;
}
//4.每当Android ListView需要显示一行时,它会调用此方法,这里面存在四个逻辑
public View getView(int position, View convertView, ViewGroup parent) {
        Log.d(TAG, "显示:" + position + "行,调用getView()" + "参数convertView==null?" + (convertView == null));

        View rootView = null;
        //1)如果没有可以重用的控件,convertView为空,加载布局创建View,convertView 本质就是一个View缓冲器
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(mContext);
            rootView = inflater.inflate(R.layout.my_list_item, parent, false); //加载布局,创建View
            rootView.setTag(position);
            Log.d(TAG, "实例化rootView,保存到Tag中的值为:" + position);
            counter++;
            Log.d(TAG, "控件实例化个数:" + counter);
        } else {
            //2)控件己经被创建过,直接重用,若不空,则直接通过position,获取list中的item,直接替换view中的内容。
            rootView = convertView;
        }

        //3)依据位置提取相应的数据源对象
        MyDataClass item = mData.get(position);

        //4)获取用于显示内容的控件的引用,findViewById()这个函数执行代价很大。所以不建议用这种方式,每次都加载控件
        TextView titleTextView = (TextView) rootView.findViewById(R.id.tvTitle);
        TextView detailTextView = (TextView) rootView.findViewById(R.id.tvDetail);

        //5)设置显示内容
        titleTextView.setText(item.getTitle());
        detailTextView.setText(item.getDetail() + " 本行Tag中保存的值为:" + rootView.getTag());

        return rootView;
    }
}
  • 4.优化之ViewHolder设计模式
    • 1)创建一个内部类ViewHolder保存控件 holder view inside,只加载View的时候使用findViewById()方法
    • 2)Tags can also be used to store data within a view without
      resorting to another data structure.使用View的setTag()方法保存ViewHolder。当convertView不为空的时候,直接取出来即可.
public View getView(int position, View convertView, ViewGroup parent) { //1.回调方法中创建一个ViewHolder内部类,其外部方法体中获取其引用
        ViewHolder holder=null;
        View rootView=convertView;
        if(convertView==null){
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        rootView = layoutInflater.inflate(R.layout.phoneinfo_item, parent, false);
    //2.加载新布局,初始化ViewHolder,并保存控件
        holder=new ViewHolder();
        holder.nameText= (TextView) rootView.findViewById(R.id.nameText);
        holder.numberText= (TextView) rootView.findViewById(R.id.numberText);
    //3.ViewHolder缓存控件数据引用,也是数据,控件类型的,需要view.setTag设置
        rootView.setTag(holder);
        }
        else {
        holder= (ViewHolder) rootView.getTag();
        }
        PhoneInfo phoneInfo = phoneInfoList.get(position);
    //4.使用ViewHolder中保存的控件类 进行操作
        holder.nameText.setText(phoneInfo.getPhoneName());
        holder.numberText.setText(phoneInfo.getPhoneNumber());

        return rootView;
        }
// 写一个私有ViewHolder类,里面存放控件签名
private static class ViewHolder {
    public TextView nameText =null;
    public TextView numberText=null;
}
  • 5.含有多种视图的布局ListView
    • 1)如果你要加载多种布局那么首先你一定重写这两个方法,注意!type一定要从0开始!!
@Override
public int getItemViewType(int position) {
        BaseModel baseModel=models.get(position);
        int type=baseModel.getType();
        return type;
 }
@Override
public int getViewTypeCount() {
        return 2;
}

2)有几个布局,就定义几个布局类,一个基类,弄多个ViewHolder保存即可。

  • 6.ListView的属性
    http://blog.youkuaiyun.com/p106786860/article/details/10596339
    原图,不添加任何属性:

    • 1)属性一:android:stackFromBottom=”true”//在ListView和GridView中使用,使它们的内容从底部开始显示。

    • 2)属性二:
      android:stackFromBottom=”true”
      android:transcriptMode=”alwaysScroll”
      android:transcriptMode属性:设置列表的transcriptMode模式,该模式指定列表添加新的选项的时候,是否自动滑动到底部,显示新的选项。
      disabled:取消transcriptMode模式,默认的
      normal:当接受到数据集合改变的通知,并且仅仅当最后一个选项已经显示在屏幕的时候,自动滑动到底部。
      alwaysScroll:无论当前列表显示什么选项,列表将会自动滑动到底部显示最新的选项。

    • 3)属性三:android:divider属性:列表之间绘制的颜色或者图片。一般开发中用于分隔表项。
      在实际开发过程中,如果你不想要列表之间的分割线,可以设置属性为@null
      android:divider=”@null”
    • 4)属性四:
      android:fadingEdge属性:设置列表的阴影
      android:cacheColorHint属性:该属性在官方文档和个资料中找不到比较好的描述;根据实际的体验,当你设置的ListView的背景时,应该设置该属性为“#00000000”(透明),不然在滑动的时候,列表的颜色会变黑或者背景图片小时的情况!
1.          android:cacheColorHint="#000000ff"   
2.      android:fadingEdge="vertical"    
3.      android:fadingEdgeLength="40dp"

5)属性五:fastScrollEnabled属性:启用快速滑动条,它能快速的滑动列表。但在实际的测试中发现,当你的数据比较小的时候,是不会显示快速滚动条。
android:fastScrollEnabled=”true”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值