PinnedHeaderLetterListView

Introduction: PinnedHeaderLetterListView 提供一个类似通讯录列表的组件,具备两个主要功能点,1、滑动时首字母会定在顶端,2、右侧有个字母列表,滑动这个列表时,显示选中的字母,同时将列表定位到相应的位置上
More: Author   ReportBugs   DemoAPK   
Tags:
letter-pin-

PinnedHeaderLetterListView 提供一个类似通讯录列表的组件,具备两个主要功能点,1、滑动时首字母会定在顶端,2、右侧有个字母列表,滑动这个列表时,显示选中的字母,同时将列表定位到相应的位置上

##效果图

项目简介

lib包为最终提供的公共库
test包为测试用例
其中 lib 里面引用了一个开源库相关代码PinnedHeaderListView,这个开源库已经实现将列表 title 定在顶端的功能,具体介绍可前往查阅

主要类介绍

PinnedHeaderLetterListView.java

PinnedHeaderLetterListView.java为最终提供的组件,继承了PinnedHeaderListView,本质上就是一个 ListView,只不过是在 ListView 的基础上添加了一下操作,在具体使用的时候,跟 ListView 基本一致

 private void initAttrs(AttributeSet attrs) {
     TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.pin_letter_list_view);
     mAlphaTextSize = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_alphaTextSize, 16);
     mAlphaTextColor = typedArray.getColor(R.styleable.pin_letter_list_view_alphaTextColor, Color.BLACK);
     mAlphaBackgroudNormalColor = typedArray.getColor(R.styleable.pin_letter_list_view_alphaBackgroundNormalColor, Color.TRANSPARENT);
     mAlphaBackgroudPressedColor = typedArray.getColor(R.styleable.pin_letter_list_view_alphaBackgroundPressedColor, Color.GRAY);
     mAlphaBackgroudColor = mAlphaBackgroudNormalColor;
     mAlphaPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_alphaPaddingLeft, 0);
     mAlphaPaddingRight = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_alphaPaddingRight, 0);
     mAlphaPaddingTop = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_alphaPaddingTop, 5);
     mAlphaPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_alphaPaddingBottom, 5);
     String alphaStr = typedArray.getString(R.styleable.pin_letter_list_view_alphaArrays);
     initAlphaList(alphaStr);

     mOverlayTextColor = typedArray.getColor(R.styleable.pin_letter_list_view_overlayTextColor, Color.WHITE);
     mOverlayTextSize = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_overlayTextSize, 40);
     mOverlaySize = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_overlaySize, 80);
     mOverlayColor = typedArray.getColor(R.styleable.pin_letter_list_view_overlayColor, Color.BLACK);
     mOverlayRadius = typedArray.getDimensionPixelSize(R.styleable.pin_letter_list_view_overlayRadius, 10);

     typedArray.recycle();

 }

提供了一些可定制项,例如,选中后提示的字体大小、颜色、弹框的大小、颜色、右侧字母表的相关的定制,对于字母表的数据,用户可直接用 alphaArrays 指定,缺省值为 Adapter 里面获取

PinLetterBaseAdapter.java

继承了SectionedBaseAdapter,扩展了两个方法,用于获取用户滑动字母表时对应的字母在 ListView 中的 postion,使用的时候不需要理会,只要继承这个 PinLetterBaseAdapter 实现自己的 Adapter 就可以了

/**
  * for locate the position in the whole listview,
  * this index doesn't include with headViewCount
  *
  * @param section
  * @return
  */
 public int getWholePosition(int section) {
     if (section <= 0) {
         return section;
     }
     int index = 0;
     for (int i = 0; i < section; i++) {
         index += getCountForSection(i) + 1;
     }
     return index;
 }

 public int getWholePosition(String letter) {
     if (TextUtils.isEmpty(letter)) {
         return -1;
     }
     int section = -1;
     for (int i = 0, size = list.size(); i < size; i++) {
         if (letter.equals(list.get(i).getLetter())) {
             section = i;
             break;
         }
     }
     return getWholePosition(section);
 }

SectionBaseAdapter.java

这个类是属于 PinnedHeaderListView 开源项目的,在 BaseAdapter 的基础上进行了扩展,将顶部和具体内容的 itemView 分离,让用户自行去实现相应的 View

entity

这里对放进 ListView 的数据结构做了一些约束

PinLetterBaseEntity.java

所有的 item 的最外层数据继承该类 ####PinLetterBaseItemEntity.java 所有 letter 里面的子 item 数据继承该类

使用方式

在 values.xml 中新建 att.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="pin_letter_list_view">
     <attr name="alphaTextColor" format="color"/>
     <attr name="alphaTextSize" format="dimension"/>
     <attr name="alphaBackgroundNormalColor" format="color"/>
     <attr name="alphaBackgroundPressedColor" format="color"/>
     <attr name="alphaPaddingLeft" format="dimension"/>
     <attr name="alphaPaddingRight" format="dimension"/>
     <attr name="alphaPaddingTop" format="dimension"/>
     <attr name="alphaPaddingBottom" format="dimension"/>
     <attr name="overlaySize" format="dimension"/>
     <attr name="overlayColor" format="color"/>
     <attr name="overlayTextSize" format="dimension"/>
     <attr name="overlayTextColor" format="color"/>
     <attr name="overlayRadius" format="dimension"/>
     <attr name="alphaArrays" format="string"/>
 </declare-styleable>
</resources>

在 layout.xml 文件中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:pinletter="http://schemas.android.com/apk/res/com.ulex.apps.pinnedheaderletterlistview"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 >

 <com.ulex.apps.pinnedheaderletterlistview.lib.PinnedHeaderLetterListView
     android:id="@+id/pinned_indicated_listView"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:listSelector="@null"
     android:cacheColorHint="@android:color/transparent"
     pinletter:overlayTextColor="@android:color/holo_red_dark"
     pinletter:overlayColor="@android:color/holo_blue_bright"
     pinletter:alphaArrays="#ABCDEFGHIJKLMNOPQRSTUVWXYZ"/>

</RelativeLayout>

编写实体类

继承 PinLetterBaseEntity.java、PinLetterBaseItemEntity.java 实现相应的实体类

继承PinLetterBaseAdapter实现 Adapter 类

  public class ContactsPinLetterListAdapter extends PinLetterBaseAdapter {

 public ContactsPinLetterListAdapter(List<ContactsPinLetterEntity> list) {
     super(list);
 }

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

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

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

 @Override
 public int getCountForSection(int section) {
     return list.get(section).getItemEntityList().size();
 }

 @Override
 public View getItemView(int section, int position, View convertView, ViewGroup parent) {
     ItemViewHolder viewHolder;
     if (convertView == null) {
         viewHolder = new ItemViewHolder(parent);
         convertView = viewHolder.getView();
         convertView.setTag(viewHolder);
     } else {
         viewHolder = (ItemViewHolder) convertView.getTag();
     }
     ContactsPinLetterItemEntity entity = (ContactsPinLetterItemEntity) list.get(section).getItemEntityList().get(position);
     viewHolder.render(entity.getName());
     return convertView;
 }

 @Override
 public View getSectionHeaderView(int section, View convertView, ViewGroup parent) {
     HeaderViewHolder viewHolder;
     if (convertView == null) {
         viewHolder = new HeaderViewHolder(parent);
         convertView = viewHolder.getView();
         convertView.setTag(viewHolder);
     } else {
         viewHolder = (HeaderViewHolder) convertView.getTag();
     }
     ContactsPinLetterEntity entity = (ContactsPinLetterEntity) list.get(section);
     viewHolder.render(entity.getLetter());
     return convertView;
 }

最后

   List<ContactsPinLetterEntity> list = ContactsPinLetterModel.getContactsList();
       ContactsPinLetterListAdapter listAdapter = new ContactsPinLetterListAdapter(list);
       TextView textView = new TextView(this);
       textView.setText("This is a headerView...");
       AbsListView.LayoutParams params = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200);
       textView.setLayoutParams(params);
       listView.addHeaderView(textView);
       listView.setAdapter(listAdapter);
       ```

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools