Android头部悬浮ListView第二种实现方式

52 篇文章 0 订阅
4 篇文章 0 订阅
本文介绍了一种不依赖SectionIndexer接口的通用ListView悬浮索引实现方法。通过自定义Adapter及OnScrollListener,使得ListView能够在各种分组条件下实现悬浮效果,并支持与其他开源库如PullToRefresh结合。
摘要由CSDN通过智能技术生成

上篇博客,根据几位大神的博客总结出了一篇ListView悬浮,快速索引。效果非常不错,而且易于扩展,可在实际项目中并不是很通用,因为总需要实现SectionIndexer接口,比较复杂而且不是所有的分且头部都是由A-Z 这种分组,也可能是以任意条件的分组,比如时间。这种情况下上一篇的方法就不能用了。本篇则是基于上一篇的代码修改,使的ListView不再去实现SectionIndexer.修改OnScrollListener中的监听,使得可悬浮ListView能够基本通用。
效果与上篇完全一样。
这里写图片描述
代码如下:
1.adapter代码

/** 
* @description 通用Adapter
* @author rzq
* @date 2015
*/
public class SortAdapter extends BaseAdapter
{
    private List<SortModel> list = null;
    private Context mContext;
    private SortModel country;
    private ViewHolder holder1, holder2;

    public SortAdapter(Context mContext, List<SortModel> list)
    {
        this.mContext = mContext;
        this.list = list;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        country = (SortModel) list.get(position);
        int type = getItemViewType(position);
        if (convertView == null)
        {
            switch (type)
            {
            case 0:
                holder1 = new ViewHolder();
                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_group, parent, false);
                holder1.tvTitle = (TextView) convertView.findViewById(R.id.catalog);
                convertView.setTag(holder1);
                break;
            case 1:
                holder2 = new ViewHolder();
                convertView = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
                holder2.tvTitle = (TextView) convertView.findViewById(R.id.title);
                convertView.setTag(holder2);
                break;
            }
        }
        else
        {
            switch (type)
            {
            case 0:
                holder1 = (ViewHolder) convertView.getTag();
                break;
            case 1:
                holder2 = (ViewHolder) convertView.getTag();
                break;
            }
        }

        switch (type)
        {
        case 0:
            holder1.tvTitle.setText(country.getSortLetters());
            break;
        case 1:
            holder2.tvTitle.setText(country.getName());
            break;
        }
        return convertView;
    }

    @Override
    public int getItemViewType(int position)
    {
        country = (SortModel) getItem(position);
        if (country.isGroup())
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }

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

    final static class ViewHolder
    {
        TextView tvTitle;
    }
}

上述代码是一个最普通的多布局Adapter写法,无需实现SectionIndex.

2.Activity代码:

public class MainActivity extends Activity
{
    private ListView sortListView;
    private SortAdapter adapter;

    private CharacterParser characterParser;
    private List<SortModel> SourceDateList;

    private PinyinComparator pinyinComparator;

    private LinearLayout titleLayout;
    private TextView title;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private void initViews()
    {
        titleLayout = (LinearLayout) findViewById(R.id.title_layout);
        title = (TextView) findViewById(R.id.title);
        characterParser = CharacterParser.getInstance();
        pinyinComparator = new PinyinComparator();

        sortListView = (ListView) findViewById(R.id.country_lvcountry);

        SourceDateList = filledData(getResources().getStringArray(R.array.date));

        Collections.sort(SourceDateList, pinyinComparator);
        adapter = new SortAdapter(this, SourceDateList);
        sortListView.setAdapter(adapter);

        sortListView.setOnScrollListener(new OnScrollListener()
        {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState)
            {
            }

            /**
             * AbsListView滑动时执行 
             */
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
            {
                /**
                 * 取出列表相临两项
                 */
                SortModel modelFirst = (SortModel) adapter.getItem(firstVisibleItem);
                SortModel modelSecond = (SortModel) adapter.getItem(firstVisibleItem + 1);

                if (firstVisibleItem != lastFirstVisibleItem)
                {
                    MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
                    params.topMargin = 0;
                    titleLayout.setLayoutParams(params);
                    if (modelFirst.getSortLetters() != null)
                    {
                        title.setText(modelFirst.getSortLetters());
                    }
                }

                /**
                 * 相临两组Data状态不同,且第一组数据的状态为普              通数据,第二组数据为Group,则符合悬浮的条件,开始进行判断部悬浮计算
                 */
                if (modelFirst.isGroup() == false && modelSecond.isGroup() == true)
                {
                    View childView = view.getChildAt(1);
                    if (childView != null)
                    {
                        int titleHeight = titleLayout.getHeight();

                        int top = childView.getTop();
                        MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
                        if (top <= titleHeight)
                        {
                            float pushedDistance = -(titleHeight - top);
                            params.topMargin = (int) pushedDistance;
                            titleLayout.setLayoutParams(params);
                        }
                    }
                }
                lastFirstVisibleItem = firstVisibleItem;
            }
        });
    }

    private int lastFirstVisibleItem = -1;

    private List<SortModel> filledData(String[] date)
    {
        List<SortModel> mSortList = new ArrayList<SortModel>();

        for (int i = 0; i < date.length; i++)
        {
            SortModel sortModel = new SortModel();
            sortModel.setName(date[i]);
            /**
             * 添加了Group数据,[A-Z]
             */
            if (date[i].matches("[A-Z]"))
            {
                sortModel.setSortLetters(date[i]);
                sortModel.setGroup(true);
            }
            else
            {
                String pinyin = characterParser.getSelling(date[i]);
                String sortString = pinyin.substring(0, 1).toUpperCase();

                if (sortString.matches("[A-Z]"))
                {
                    sortModel.setSortLetters(sortString.toUpperCase());
                }
                else
                {
                    sortModel.setSortLetters("#");
                }
                sortModel.setGroup(false);
            }
            mSortList.add(sortModel);
        }
        return mSortList;
    }
}
  通过上述代码可以看出,通过这訲方式实现的效果更加的通用,也是在研究了多位大神的博客后,自己有了改进的想法,编码实现了自己的想法。使用这訲不重写ListView的方式,我们还可以结合PullToRefresh做上下拉刷新,而如果你重定义ListView则很难再与其它开源库相结合。这是使用这一方式最大的优势。

DEMO下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值