ListView 节头制作

    主要用到了稀疏数组,SparseArray是 Android框架独有的类,在标准的JDK中不存在这个类。它要比 HashMap 节省内存,某些情况下比HashMap性能更好,而且不会进行自动装箱操作。
制作listview节头主要是通过自定系adapter结合SparseArray来完成,将每一个分类都当成一个列表存储在系数数组中,其类似与多为数组,其中只在关键节点上存储节头,节头下的内容由每一小节自行管理。显示效果如下:

这里写图片描述

代码如下:

package com.example.mhyuam.listtviewheader;

import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by mhyuam on 2016/7/10.
 */
abstract class  MyAdapter extends BaseAdapter implements AdapterView.OnItemClickListener{

    private  static final int TYPE_HEAD = 1;
    private  static final int TYPE_ITEM = 2;

    private LayoutInflater layoutInflater;
    private int HEADER_RES,ITEM_RES;

    private List<Section> sections;
    private SparseArray<Section> keySctions;

    MyAdapter(ListView listView,int HEADER_RES,int ITEM_RES){
        layoutInflater = LayoutInflater.from(listView.getContext());
        this.HEADER_RES = HEADER_RES;
        this.ITEM_RES = ITEM_RES;

        sections = new ArrayList();
        keySctions = new SparseArray();
        listView.setOnItemClickListener(this);

    }

  public void addSections(String title,String[] array){
      Section item = new Section(title,array);
      int index = sections.indexOf(item);
      if(index >= 0){
          sections.remove(index);
          sections.add(index,item);
      }else {
          sections.add(item);
      }

      reOrder();
      notifyDataSetChanged();
  }

    private void reOrder(){
        keySctions.clear();
        int startPosition = 0;
        for (Section item:sections) {
            keySctions.put(startPosition,item);
            startPosition +=item.getCount();
        }
    }

    @Override
    public int getCount() {
        int count = 0;
        for (Section item:sections){
            count += item.getCount();
        }
        return count;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        Log.i("123","getItemViewType position = " +position);
        if (isHeaderAtPosition(position)){
            return TYPE_HEAD;
        }else {
            return TYPE_ITEM;
        }
        //Log.i("123","getItemViewType position = " +position);
        //return position;
    }

    private boolean isHeaderAtPosition(int position) {
        for (int i=0; i < keySctions.size(); i++) {
            //If this position is a key value, it's a header position
            if (position == keySctions.keyAt(i)) {
                Log.i("123","---------i = ------- "+i+" -----position---- = "+position +" ----  keySctions  = "+keySctions.get(i));
                return true;
            }
        }

        return false;
    }

    @Override
    public Object getItem(int position) {
        return findSectionItemAtPosition(position);
    }
    private Object findSectionItemAtPosition(int position){
        int firstpsition,lastposition;
        for (int i = 0;i<keySctions.size();i++){
            firstpsition = keySctions.keyAt(i);
            lastposition = firstpsition + keySctions.valueAt(i).getCount();

            if (position >= firstpsition && position < lastposition){
                int sectionposition = position - firstpsition -1;
                return keySctions.valueAt(i).getItem(sectionposition);
            }
        }
        return null;
    }


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

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {

        switch (getItemViewType(position)) {
            case TYPE_HEAD:
                return getHeaderView(position,view,viewGroup);
            case TYPE_ITEM:
                return getItemView(position,view,viewGroup);
            default:
                return view;
        }
    }
    @Override
    public boolean isEnabled(int position) {
        return !isHeaderAtPosition(position);
    }
    public View getHeaderView(int position,View view,ViewGroup viewGroup){
        if(view == null){
            view = layoutInflater.inflate(HEADER_RES,viewGroup,false);
        }
        Section item = keySctions.get(position);

        TextView tv = (TextView) view.findViewById(R.id.text1);

        tv.setText(item.getTitle());
        return view;
    }

    public View getItemView(int position,View view,ViewGroup viewGroup){
        if(view == null){
            view = layoutInflater.inflate(ITEM_RES,viewGroup,false);
        }
        Object item = findSectionItemAtPosition(position);
        TextView tv = (TextView) view.findViewById(android.R.id.text1);
        tv.setText(item.toString());
        return view;
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
        Object item = findSectionItemAtPosition(position);
        if (item != null){
            ItemClick(item);
        }
    }

    abstract void  ItemClick(Object item);
}
package com.example.mhyuam.listtviewheader;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import android.widget.ListView;

public class ListHeader extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        ListView listView = new ListView(this);

        MyAdapter adapter = new MyAdapter(listView,R.layout.header_layout,android.R.layout.simple_list_item_1) {
            @Override
            void ItemClick(Object item) {
                Log.i("123","您选择了" + item.toString());
            }
        };

        adapter.addSections("水果" ,new String[]{"苹果","香蕉","橘子"});
        adapter.addSections("蔬菜" ,new String[]{"白菜","萝卜","黄瓜","西红柿"});
        adapter.addSections("肉类" ,new String[]{"猪肉","牛肉"});
        listView.setAdapter(adapter);
        setContentView(listView);
    }
}

package com.example.mhyuam.listtviewheader;

/**
 * Created by mhyuam on 2016/7/10.
 */
public class Section {
    private String title;
    private String[] list;
    public Section(String title,String[] list){

        this.title = title;
        this.list = list;
    }
    public String getTitle(){
        return title;
    }
    public String getItem(int posiion){
        return list[posiion];
    }

    public int getCount(){
        return list == null?1:list.length +1;
    }

    public boolean equals(Object object){
        if((object != null) && (object instanceof Section)){
            return ((Section) object).getTitle().equals(title);
        }
        return false;
    }
}

note: SparseArray有类似于HashMap或者多维数组的性质,其脚标问题十分关键,一不注意就有可能搞错,且不便排查,如果在使用出现了莫名其妙的问题,那可能是脚标那里出错了。同时也要注意 SparseArray.get(index)以及SparseArray.value(index)的差别。

    /**
     * Gets the Object mapped from the specified key, or <code>null</code>
     * if no such mapping has been made.
     */
    public E get(int key) {
        return get(key, null);
    }
    /**
     * Given an index in the range <code>0...size()-1</code>, returns
     * the value from the <code>index</code>th key-value mapping that this
     * SparseArray stores.
     *
     * <p>The values corresponding to indices in ascending order are guaranteed
     * to be associated with keys in ascending order, e.g.,
     * <code>valueAt(0)</code> will return the value associated with the
     * smallest key and <code>valueAt(size()-1)</code> will return the value
     * associated with the largest key.</p>
     */
    @SuppressWarnings("unchecked")
    public E valueAt(int index) {
        if (mGarbage) {
            gc();
        }

        return (E) mValues[index];
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值