ListView

ListView

ListView是一种使数据一条条的显示的像一个空架子一样的东西。主要用于MVc设计模式中,M为数据,V为View及显示在界面中,C为controll控制M以什么样的形式显示在View中。
数据想放到ListView上必须经过适配器,将数据转化成规定的形式。
ListView就是一种控件,只不过它的数据加载需要适配器adapter才可以
ListView常用的适配器有ArrayAdapter,simpleAdapter,自定义适配器。

ArrayAdapter

ArrayAdapter的数据源是数组或者是集合。显示类型为系统默认的,在建立ArrayAdapter的时候有三个参数:


ArrayAdapter arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,array);

第一个参数为context上下文。
第二个参数为 数据显示的方式,一般用:android.R.layout.simple_list_item_1
第三个参数为数据源,一般为数组获得集合。

代码如下:

public class mListView extends Activity {
    private ListView mListView;
    String [] array ={"张三","李四","王五"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nlist);
        mListView= (ListView) findViewById(R.id.mListist);
//        ArrayAdapter<String> adapter =new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,array);
        ArrayAdapter<String> adapter =new ArrayAdapter<String>(this,R.layout.item_list,array);
        mListView.setAdapter(adapter);
    }
}

在XML中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/mListist"
        ></ListView>
</LinearLayout>

simpleAdapter

simpleAdapter一般加载一些比较复杂的文件,一般有图像的就可以用这个适配器,它的数据来源是List,只不过这种List的数据必须是map类型的。
simpleAdapter的建立有5个参数。

 simpleAdapter = new SimpleAdapter(this,ppp(),R.layout.simple_view,new String[]{"image","text"},new int[]{R.id.image,R.id.text});

1.为上下文
2.为data数据源
3.resource :列表的布局文件ID
4.from:map中的键名,用String数组写出
5.to:布局文件中的每个组件的ID

完整的代码如下:
在代码中:

public class MainActivity extends Activity {
    private ListView listView;
    private ArrayAdapter<String> arrayAdapter;
    private SimpleAdapter simpleAdapter;
    private ImageView imageView;
    private TextView textView;
    private String []array = new String[]{"第一条","第二条","第三条","第四条"};
    private List<Map<String,Object>> data;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.mylistview);
        imageView = (ImageView) findViewById(R.id.image);
        textView = (TextView) findViewById(R.id.text);
//        arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,array);
//       listView.setAdapter(arrayAdapter);
        simpleAdapter = new SimpleAdapter(this,ppp(),R.layout.simple_view,new String[]{"image","text"},new int[]{R.id.image,R.id.text});

        listView.setAdapter(simpleAdapter);
    }

   public  List<Map<String,Object>> ppp(){
        data = new ArrayList<>();
       Map<String,Object> map1= new HashMap<>();
       map1.put("image",R.mipmap.ic_launcher);
       map1.put("text","hhehe");
       data.add(map1);
        return data;
    }
}

在Xml中文件名为:simple_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

第二个例子的代码:

public class mListView extends Activity {
    private ListView mListView;
    ArrayList<Map<String,String >> mDate;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.item_list);
        setContentView(R.layout.nlist);
        mListView= (ListView) findViewById(R.id.mListist);
        inidate();
        SimpleAdapter eAdapter= new SimpleAdapter(this,mDate,R.layout.item_simpleview,new String[]{"name","age","sex","hobby"},
                new int[]{R.id.name,R.id.age,R.id.sex,R.id.hobby} );
        mListView.setAdapter(eAdapter);

        //android.R.layout.simple_list_item_1是一种格式,这种格式是将数据放入ListView中的格式
//        ArrayAdapter<String> adapter =new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,array);


    }
    public void inidate(){
        mDate=new ArrayList<>();
        HashMap<String,String> zhangsan=creatHashMap("张三","20","男","打球");
        mDate.add(zhangsan);

        HashMap<String,String> lisi=creatHashMap("李四","20","男","打球");
        mDate.add(lisi);

        HashMap<String,String> wangwu=creatHashMap("王五","20","男","打球");
        mDate.add(wangwu);

    }
    public HashMap<String,String> creatHashMap(String name,String age,String sex,String hobby){
        HashMap<String,String> hashMap = new HashMap<>();
        hashMap.put("name",name);
        hashMap.put("age",age);
        hashMap.put("sex",sex);
        hashMap.put("hobby",hobby);
        return hashMap;
    }
}

在item_simpleview的XML中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    >
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="name"
        />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >
        <TextView
            android:id="@+id/age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="age"
            />
        <TextView
            android:id="@+id/sex"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="sex"
            />

    </LinearLayout>
    <TextView
        android:id="@+id/hobby"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hobby"
        />

</LinearLayout>

自定义Adapter

建立一个类继承自BaseAdapter并复写其中的方法;具体的操作见下面:

避免滚动变黑

在LisetView中滑动时有时会变黑,为了避免这种状况的发生在ListView的XML中加入以下一行代码:

android:cacheColorHint="#00000000"

这样就避免这种状况的发生了。

View之间的分割线

在ListView中的各个View之间可以加分割线,既可以设置其颜色,也可以设置其宽度;代码如下:

android:divider="@color/red"
android:dividerHeight="1dp"

这样View之间就出现了颜色为red,宽度为1dp的分割线了。

背景

设置View之间的背景需要下XMl中调用background来设置。

加头与尾

在ListView中可以在开头加一个头,在结尾加一个尾。
这个头与尾必须自己写XML布局。并用inflater.inflate(R.layout.myhead,null);这样的代码将这个布局实例化,这个实例是View类型的,然后再代用listView的mListView.addHeaderView(all);
mListView.addFooterView(fan);
这种代码将这个view加入ListView中。
这样LiseView中就有头与尾了。

注意

在ListView中如果其View中有Button、CheckBox等按键的时候再去设置ListView的点击事件是不可以的,这是因为按键机制的原因,所以必须在按键的XML中加入一条代码,这样才能成功:

android:focusable="false"

这样按键就不会抢夺点击事件了,ListView的点击事件也就成功了。

下面是一个显示水果的代码。是运用了自定义Adapter的适配器,有头与尾,头是一个全选的按键,尾是一个选反的按键。代码如下:
在主Activity中:

public class FruitMactivity extends Activity {
    ListView mListView;
    ArrayList<Fruit> mDate;
    FruitAdapter adapter;
    Button allChecked;
    Button fanChecked;
    LayoutInflater inflater;
    View all;
    View fan;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_fruit);
        mListView= (ListView) findViewById(R.id.listview_fruit);
        inflater =getLayoutInflater();
        all=inflater.inflate(R.layout.myheader,null);//将头的布局实例化。
        fan = inflater.inflate(R.layout.myfoot,null);//将尾的布局实例化
        fanChecked = (Button) fan.findViewById(R.id.fanchecked);//引入尾的按键
        allChecked = (Button) all.findViewById(R.id.allchecked);//引入头的按键


        //给头加点击事件,调用adapter的自定义方法,使乘有数据的CheckBox状态的数组全都变成true
        allChecked.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.allChecked();
            }
        });
        //给尾加点击事件,调用adapter的自定义方法,使乘有数据的CheckBox状态的数组全都变成相反的
        fanChecked.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.allfan();
            }
        });
        mListView.addHeaderView(all);//将表头布局加入ListView
        mListView.addFooterView(fan);//将表尾布局加入ListView

        indata();//数据初始化
        adapter =new FruitAdapter(mDate,inflater);
        mListView.setAdapter(adapter);
        //这个点击事件是在用户点击View时,使CheckBox这个按键的状态发生变化。
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                adapter.item(position-1);//在有表头时这里的position一定要减一,其他地方不需要。
            }
        });
    }

    private void indata() {
        mDate=new ArrayList<>();

        for(int i =0;i<30;i++){
            Fruit putao=new Fruit(R.mipmap.putao,"葡萄");
            Fruit li=new Fruit(R.mipmap.pair,"梨");
            Fruit caomei=new Fruit(R.mipmap.caomei,"草莓");
            Fruit chengzi=new Fruit(R.mipmap.chengzi,"橙子");
            Fruit orange=new Fruit(R.mipmap.orange,"橘子");
            Fruit mangguo=new Fruit(R.mipmap.mangguo,"芒果");
            mDate.add(putao);
            mDate.add(li);
            mDate.add(caomei);
            mDate.add(chengzi);
            mDate.add(orange);

            mDate.add(mangguo);
        }

    }
}

Fruit类

public class Fruit {

    int image;
    String name;
    boolean ischecked;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;

    }



    public int getImage() {
        return image;
    }


    public void setImage(int image) {
        this.image = image;
    }



    public void setIschecked(boolean ischecked) {
        this.ischecked = ischecked;
    }


    public boolean ischecked() {
        return ischecked;
    }

    public Fruit( int image, String name) {

        this.image = image;
        this.name = name;

    }
}

在FruitAdapter适配器中

public class FruitAdapter extends BaseAdapter {
    LayoutInflater inflater;
    List<Fruit> mdata;
    boolean []allCheckbox;//用于存放数据中的CheckBox的状态
    public FruitAdapter(List<Fruit> mdata, LayoutInflater inflater) {
        this.mdata = mdata;
        this.inflater = inflater;
       allCheckbox=new boolean[mdata.size()];//设置数组的长度
    }

    /**
     * 在点击View时调用这个方法
     * @param position
     */
    public void item(int position){
        allCheckbox[position]=!allCheckbox[position];
        notifyDataSetChanged();
    }

    /**
     * 在全选的按键事件中调用这个方法
     */
    public void allChecked(){
        for(int i=0;i<allCheckbox.length;i++){
            allCheckbox[i]=true;

        }
        notifyDataSetChanged();
    }

    /**
     * 在选反的按键事件中调用这个方法
     */
    public void allfan(){
        for(int i=0;i<allCheckbox.length;i++){
            allCheckbox[i]=!allCheckbox[i];
        }
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mdata.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder vh;
        final Fruit fruit =mdata.get(position);
        //converView主要用于避免重复建立View
        if(convertView==null) {
            vh=new ViewHolder();
            convertView = inflater.inflate(R.layout.fruits, null);
            vh.imageView= (ImageView) convertView.findViewById(R.id.downlod_fruit);
            vh.checkBox= (CheckBox) convertView.findViewById(R.id.select_fruiut);

            vh.textView_name= (TextView) convertView.findViewById(R.id.fruit_name);

            convertView.setTag(vh);
        }else{
            vh= (ViewHolder) convertView.getTag();
        }

        vh.imageView.setImageResource(fruit.getImage());
        vh.textView_name.setText(fruit.getName());
        /**
         * 这是CheckBox的一个点击事件,当CheckBox按键状态发生变化时这个变化的状态会直接传入
         * 数据中,这样Checked的状态就可以直接从数据中获取
         */
        vh.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//                mdata.get(position).setIschecked(isChecked);
                allCheckbox[position]=isChecked;

            }
        });
//        vh.checkBox.setChecked(fruit.ischecked());
        vh.checkBox.setChecked(allCheckbox[position]);

        return convertView;
    }
    //主要用于避免重复使用findViewById
    class ViewHolder{
        CheckBox checkBox;
        ImageView imageView;
        TextView textView_name;
    }
}

XML布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:background="@drawable/item_background"

    >
    <CheckBox
        android:id="@+id/select_fruiut"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:text="选择水果"
        />
    <ImageView
        android:id="@+id/downlod_fruit"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@mipmap/apple"
        />
    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="水果的名称"
        />

</LinearLayout>

myHeader.XML的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/allchecked"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="全选"
        />
</LinearLayout>

myFoot.XML的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/fanchecked"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="反选"
        />
</LinearLayout>

listfruit.XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<ListView
    android:id="@+id/listview_fruit"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    ></ListView>
</LinearLayout>

这里重点说明一下FruitAdapter的getView方法中的代码。
这里运用了convertView去避免重复多次的创建view来节省时间和内存。用ViewHolder类去避免重复的findViewById,也节省了时间和内存。
当有View划出屏幕时convertView就不会是null,这个划出去的View会被复用到即将划入屏幕的View,以此达到View复用的目的。ViewHolder是存放各种控件实例的(其实就是变量)这个类的实例是与convertView的创建一一是对应的。并将ViewHolder放入convertView中: convertView.setTag(vh);这样可以通过convertView实例得到ViewHolder的实例。

ListView加载不同类型的Item:

在adapter中重写onItemViewType( )和onTypecount()方法,在getView方法中调用onItemViewType( )方法判断每个item的类型,根据类型不同加载不同的布局。adapter的代码如下:

package com.ultrapower.android.wo.adapter;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.example.snall2.R;
import com.ultrapower.android.wo.BaseApplication;
import com.ultrapower.android.wo.bean.ListContentBean;


import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainFragmentListViewAdapter extends BaseAdapter  {

    private ArrayList<ListContentBean> mDate;
    private LayoutInflater inflater;


    public MainFragmentListViewAdapter(ArrayList<ListContentBean> mDate,
            LayoutInflater inflater) {
        super();
        this.mDate = mDate;
        this.inflater = inflater;
    }

    @Override
    public int getCount() {

        return mDate.size();
    }

    @Override
    public Object getItem(int position) {

        return mDate.get(position);
    }

    @Override
    public long getItemId(int position) {

        return position;
    }


    @Override
      public int getItemViewType(int position) {
        if(position==3){
            return 1;
        }
        return 0;
      }
      @Override
      public int getViewTypeCount() {
        return 2;
      }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

//      ListContentBean listContentBean = mDate.get(position);
        View viewItem1 = null;
        View viewItem2 = null;
        ViewHolder1 viewHolder1 = null;
        ViewHolder2 viewHolder2 = null;
        int itemType = this.getItemViewType(position);

        if(itemType == 1){
          //第一种item
//        ViewHolder1 viewHolder1 = null;
          if(convertView == null){
            //没有缓存过
            viewHolder1 = new ViewHolder1();
              viewItem1 =inflater.inflate(R.layout.now_title, null);

            viewItem1.setTag(viewHolder1);
              convertView = viewItem1;
          }else {
              viewHolder1 = (ViewHolder1) convertView.getTag();
          }

          }else if(itemType == 0){

              if(convertView==null) {
                  viewHolder2 = new ViewHolder2();
                  viewItem2 = inflater.inflate(R.layout.hot_list_content, null);
                  viewHolder2.style_item_image = (ImageView) viewItem2.findViewById(R.id.style_item_image);
                  viewHolder2.title_item_text = (TextView) viewItem2.findViewById(R.id.title_item_text);
                  viewHolder2.guocheng_item_text = (TextView) viewItem2.findViewById(R.id.guocheng_item_text);
                  viewHolder2.person_item_text = (TextView) viewItem2.findViewById(R.id.person_item_text);
                  viewHolder2.time_item_text = (TextView) viewItem2.findViewById(R.id.time_item_text);
                  viewHolder2.state_item_image = (ImageView) viewItem2.findViewById(R.id.state_item_image);
                  convertView = viewItem2;
                viewItem2.setTag(viewHolder2);
                 } else {
                    viewHolder2 = (ViewHolder2) convertView.getTag();
                 }

//               ListContentBean listContentBean = mDate.get(position);



          }

        return convertView;
    }

     class ViewHolder1 {
         ImageView iv1;


         }

     class ViewHolder2 {
         ImageView style_item_image;
         ImageView state_item_image;

         TextView title_item_text;
         TextView guocheng_item_text;
         TextView  person_item_text;
         TextView  time_item_text;

         }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值