1. 程式人生 > >Android頭部懸浮ListView第二種實現方式

Android頭部懸浮ListView第二種實現方式

上篇部落格,根據幾位大神的部落格總結出了一篇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則很難再與其它開源庫相結合。這是使用這一方式最大的優勢。