ListView的多种item的实现方式

KelvinWalke 8年前
   <p>使用ListView一般步骤:</p>    <ol>     <li>设置显示的ListView,设置显示的每一项item的view布局文件</li>     <li>设置每个item显示的数据</li>     <li>将数据显示的View中,继承BaseAdapter,重写 <strong>getCount()</strong> , <strong>getItemId()</strong> , <strong>getItem()</strong> , <strong>getView()</strong> 这个四个方法;</li>    </ol>    <p>如果实现ListView的多种类型item的显示,那么就要再重写两个方法</p>    <p>getViewTypeCount():得到总共item的显示的种类数,</p>    <p>getItemViewType():得到每个item显示的类型;为整型数据;</p>    <p>实现的效果如下:</p>    <p><img src="https://simg.open-open.com/show/c3ac1511397fc69260605e831d1ff3b7.png"></p>    <p>ListView的多种item实现.png</p>    <h2>一、准备填充的数据模型</h2>    <p>1、解析json数据源</p>    <p>json数据放在res下的raw文件夹下:</p>    <pre>  <code class="language-java">[    {      "letter": "A",      "cities": [        "安庆",        "安徽",        "安全"      ]    },    {      "letter": "B",      "cities": [        "包头",        "宝钢",        "渤海",        "本溪",        "蚌埠"      ]    },    {      "letter": "C",      "cities": [        "长春",        "长城",        "长沙",        "常州",        "郴州",        "重庆"      ]    },    {      "letter": "D",      "cities": [        "东莞",        "东山",        "大连",        "大庆"      ]    }  ]</code></pre>    <p>2、建立数据对象</p>    <p>可以看到这个ListView有两种类型,一个是显示字母,一个是显示内容,所以数据模型的建立如下,使用int型的type对数据类型进行标识;标识的值必须从0开始计数,有两种类型,那么就取 <strong>0,1</strong> 这两个值;</p>    <pre>  <code class="language-java">public class StringBean {      String letter;      String city;      int type;      public String getLetter() {          return letter;      }      public void setLetter(String letter) {          this.letter = letter;      }      public String getCity() {          return city;      }      public void setCity(String city) {          this.city = city;      }      public int getType() {          return type;      }      public void setType(int type) {          this.type = type;      }      @Override      public String toString() {          return "StringBean{" +                  "letter='" + letter + '\'' +                  ", city='" + city + '\'' +                  ", type=" + type +                  '}';      }  }</code></pre>    <p>解析json数据填充成集合数据源这里就不提供了</p>    <h2>二、准备两种item类型的布局文件</h2>    <p>1、显示字母的type_layout.xml的布局文件</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:orientation="vertical">      <TextView          android:id="@+id/tvType"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:background="#999"          android:text="A"          android:textSize="20sp" />  </LinearLayout></code></pre>    <p>2、显示城市city_layout.xml的布局文件</p>    <pre>  <code class="language-java"><?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">      <TextView          android:id="@+id/tvCity"          android:layout_width="match_parent"          android:layout_height="wrap_content"           android:textSize="20sp"          />  </LinearLayout></code></pre>    <h2>三、设置显示ListView的数据和布局的适配器</h2>    <p>这里的ListView的item有两种类型,所以 <strong>getViewTypeCount()</strong> 返回2;</p>    <p>在 <strong>getItemViewType()</strong> 返回的是每次绘制每一个item的view显示的是何种类型,在数据模型StringBean有设置;</p>    <p>关于类型的整型设置,可能有很多人认为只要是任意的整型数字就可以了,其实不是这样</p>    <p>item类型标识值 <strong>必须从0开始</strong> 计数,如果item有两种类型,那么类型标识值就是 <strong>0,1</strong></p>    <p>如果是不从0开始标识,那么会报ArrayIndexOutOfBoundsException数组下标越界的异常</p>    <pre>  <code class="language-java">public class ListAdapter extends BaseAdapter {      ArrayList<StringBean>list;      Context context;      LayoutInflater inflater;      ListAdapter(ArrayList<StringBean>list,Context context){          this.list=list;          this.context=context;          inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);      }      @Override      public int getCount() {          return list.size();      }      @Override      public Object getItem(int i) {          return list.get(i);      }      @Override      public long getItemId(int i) {          return i;      }      @Override      public View getView(int position, View converView, ViewGroup viewGroup) {          View view=converView;          StringBean bean=list.get(position);          int type=bean.getType();          if(type==0){              if(view==null){                  view=inflater.inflate(R.layout.type_layout,viewGroup,false);              }              TextView type_text= (TextView) view.findViewById(R.id.tvType);              type_text.setText(bean.getLetter());          }else if (type==1){              if(converView==null){                  view=inflater.inflate(R.layout.city_layout,viewGroup,false);              }              TextView city_text= (TextView) view.findViewById(R.id.tvCity);              city_text.setText(bean.getCity());          }          return view;      }      @Override      public int getItemViewType(int i) {          return list.get(i).getType();      }      @Override      public int getViewTypeCount() {          return 2;      }  }</code></pre>    <h2>四、设置ListView</h2>    <p>ListView的布局文件,在这里就不给出了</p>    <pre>  <code class="language-java">public class MainActivity extends AppCompatActivity {      ArrayList<StringBean> list;      ListView listView;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          initBean();          initView();      }      public void initBean(){          UserDao dao=new UserDao(this);          list=dao.getList();      }      public void initView(){          listView= (ListView) findViewById(R.id.listView);         ListAdapter adapter=new ListAdapter(list,this);          listView.setAdapter(adapter);      }  }</code></pre>    <p> </p>    <p>来自:http://www.jianshu.com/p/dd34306e9cb1</p>    <p> </p>