ListView之BaseAdapter的用法简单案例(四)

一个简单的BaseAdapter的用法简单案例,
我们想利用BaseAdapter达到下面图片的简单效果。
ListView之BaseAdapter的用法简单案例(四)_第1张图片

首先我们先将布局文件写出来如下


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <ImageView 
        android:id="@+id/hander"
        android:minHeight="50dp"
        android:layout_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="1dp"/>


    <LinearLayout android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_weight="8"
        android:layout_height="wrap_content" 
        android:layout_gravity="center_vertical">

        <LinearLayout android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

        <TextView android:id="@+id/money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:paddingLeft="10dp"/>

        <TextView  android:id="@+id/amount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:paddingLeft="10dp"
            android:textColor="#EC8B57"/>
        LinearLayout>

        <TextView  android:id="@+id/desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="10sp"
            android:textColor="#B4B1B1"
            android:paddingLeft="10dp"/>
    LinearLayout>
    <TextView android:id="@+id/end"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:layout_gravity="center_vertical"
        android:drawableEnd="@drawable/umeng_update_btn_check_on_focused_holo_light"
        android:textSize="5sp" />
LinearLayout>

其次是代码实现部分

package com.test.baseadapter02;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends ListActivity {
    //定义需要显示的数据 
    private String [][] datas = new String[][]{
            {"冲30","到账300V币","折合1毛钱/分钟,有效期三个月","¥30"},
            {"冲50","送20元,到账700V币","折合7分钱/分钟,有效期6个月","¥50"},
            {"冲100","送60元,到账1600V币","折合6分钱/分钟,有效期一年","¥100"},
            {"冲200","送200元,到账4000V币","折合5分钱/分钟,有效期两年","¥200"},
            {"冲300","送450元,到账7500V币","折合4毛钱/分钟,有效期两年","¥300"}
    };
    private int[] imageIds = new int[]{
            R.drawable.umeng_update_btn_check_on_focused_holo_light,
            R.drawable.umeng_update_btn_check_on_holo_light,
            R.drawable.umeng_update_btn_check_on_pressed_holo_light,
            R.drawable.umeng_update_close_bg_normal,
            R.drawable.umeng_update_close_bg_tap,
    };

    @Override
    protected void onCreate(Bundle savedInstanceState){     
        super.onCreate(savedInstanceState);
        //获取将要显示的数据并绑定在适配器adapter
        MyAdapter adapter = new MyAdapter(this,getdata());
        setListAdapter(adapter);
    }
    //要显示的数据 将其传入集合list中
    private List> getdata(){
        List> list = new ArrayList>();

        for(int i = 0;i map = new HashMap();
        map.put("header",imageIds[i]);
        map.put("money", datas[i][0]);
        map.put("amount", datas[i][1]);
        map.put("desc", datas[i][2]);
        map.put("end", datas[i][3]);
        list.add(map);
        }
        return list;
    }
    //ViewHolder静态类
    public final class ViewHolder{
        public ImageView header;
        public TextView money;
        public TextView amount;
        public TextView desc;
        public TextView end;
    }

    public class MyAdapter extends BaseAdapter{

        private LayoutInflater mInflater;
        private List> mData;

        public MyAdapter(Context context,List> mData){
            //根据context上下文加载布局
            this.mInflater = LayoutInflater.from(context);
            //将传入的数据保存在mData中
            this.mData=mData;
        }

        @Override
        public int getCount() {
            //在此适配器方法返回的是中所代表的数据集中的条目数,
            //我们可以获取数据的size()方法知道数据数量。从而决定需要多少列表项
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            //获取数据集中与指定索引对应的数据项
            return position;
        }

        @Override
        public long getItemId(int position) {
            //获取在列表中与指定索引对应的行id
            return position;
        }

在这里 下面我们要重点说一下getView后面几个参数的作用
第一个参数: int position,一般BaseAdapter都是很多类型一样的数据展示在界面,
该属性是判断显示在界面上的是第几个,通过position在BaseAdapter自定义的数组或者集合中取值。并展示在界面上。

第二个参数: View converView View converView是展示在界面上的一个item。因为手机屏幕就那么大,所以一次展示给用户看见的内容是固定的,如果你List中有1000条数据,不应该new1000个converView,那样内存肯定不足,应该学会控件重用,滑出屏幕的converView就在下面新进来的item中重新使用,只是修改下他展示的值。这样能减去很多消耗。
不过有的时候我们不能对其进行重构 比如带CheckBox的item,如果你使用判断,在你选中某个item的CheckBox时滑动时会出现混乱,这时你就必须去掉判断对其进行重构。

第三个参数:ViewGroup parent 这个属性是加载xml视图时使用。

所以在下面的代码中我们为了提高性能会先判定converView是否为空,为空的话猜重新创建并且后面选择保存布局到缓存,

        @Override
        //获取一个在数据集中指定索引的视图来显示数据
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder = null;
            //如果缓存convertView为空,则需要创建View
            if(convertView == null){

                //自定义的一个类用来缓存convertview
                holder=new ViewHolder(); 

                //根据自定义的Item布局加载布局
                convertView = mInflater.inflate(R.layout.activity_main, null);
                /*这里在提一下ViewHolder的作用与用法
                ViewHolder只是将需要缓存的那些view封装好,
                convertView的setTag才是将这些缓存起来供下次调用
                当你的listview里布局多样化的时候 viewholder的作用就有比较明显的体现了。
                当然了,单一模式的布局一样有性能优化的作用 只是不直观。 
                假如你2种模式的布局 当发生回收的时候 你会用setTag分别记录是哪两种   
                这两种模式会被封装到viewholder中进行保存方便你下次使用。
                 VH就是个静态与缓存无关的
                 这里只是简单介绍,具体的可以看
                 http://blog.csdn.net/bill_ming/article/details/8817172
                 这篇*/
                holder.header = (ImageView)convertView.findViewById(R.id.hander);
                holder.money = (TextView)convertView.findViewById(R.id.money);
                holder.amount = (TextView)convertView.findViewById(R.id.amount);
                holder.desc = (TextView)convertView.findViewById(R.id.desc);
                holder.end = (TextView)convertView.findViewById(R.id.end);
                //将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
                convertView.setTag(holder);
            }else{
                holder = (ViewHolder)convertView.getTag();
            }
            holder.header.setBackgroundResource((Integer)mData.get(position).get("header"));
            holder.money.setText((String)mData.get(position).get("money"));
            holder.amount.setText((String)mData.get(position).get("amount"));
            holder.desc.setText((String)mData.get(position).get("desc"));
            holder.end.setText((String)mData.get(position).get("end"));
            return convertView;
        }

    }
}

上面inflate()的作用就是将一个用xml定义的布局文件查找出来,注意与findViewById()的区别,inflate是加载一个布局文件,而findViewById则是从布局文件中查找一个控件。
比如 :
如果你的Activity里用到别的layout,比如对话框layout,你还要设置这个layout上的其他组件的内容,你就必须用inflate()方法先将对话框的layout找出来,然后再用findViewById()找到它上面的其它组件。


View view1=View.inflate(this,R.layout.dialog_layout,null);
  
  TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
  
  dialogTV.setText("abcd");
注:R.id.dialog_tv是在对话框layout上的组件,而这时若直接用this.findViewById(R.id.dialog_tv)肯定会报错。

1.获取LayoutInflater对象有三种方法
LayoutInflater inflater=LayoutInflater.from(this);
LayoutInflater inflater=getLayoutInflater();
LayoutInflater inflater=(LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);

2:关于LayoutInflater类inflate(int resource, ViewGroup root, boolean attachToRoot)方法三个参数的含义
resource:需要加载布局文件的id,意思是需要将这个布局文件中加载到Activity中来操作。
root:需要附加到resource资源文件的根控件,什么意思呢,就是inflate()会返回一个View对象,如果第三个参数attachToRoot为true,就将这个root作为根对象返回,否则仅仅将这个root对象的LayoutParams属性附加到resource对象的根布局对象上,也就是布局文件resource的最外层的View上,比如是一个LinearLayout或者其它的Layout对象。
attachToRoot:是否将root附加到布局文件的根视图上

3:int position位置,一般BaseAdapter都是很多类型一样的数据展示在界面,该属性是判断显示在界面上的是第几个,通过position在BaseAdapter自定义的数组或者集合中取值。并展示在界面上。
View converView 展示在界面上的一个item。因为手机屏幕就那么大,所以一次展示给用户看见的内容是固定的,如果你List中有1000条数据,不应该new1000个converView,那样内存肯定不足,应该学会控件重用,滑出屏幕的converView就在下面新进来的item中重新使用,只是修改下他展示的值

你可能感兴趣的:(android学习笔记)