listview的分组挤压效果实现

1适配器实现SectionIndexer接口

@Override
        public Object[] getSections() {
            return new Object[0];
        }

//此方法是通过字母的Ascii码,与集合里的元素拼音的首字母的Ascii码做比较,返回第一个相同的索引位置(即分组位置)
        @Override
        public int getPositionForSection(int sectionIndex) {
            for (int i = 0; i < friends.size(); i++) {
                if (sectionIndex == friends.get(i).pinyin.toUpperCase().charAt(0)) {
                    return i;
                }
            }
            return 0;
        }

//此方法是通过索引位置,获取到此索引所属的分组字母
        @Override
        public int getSectionForPosition(int position) {
            return friends.get(position).pinyin.toUpperCase().charAt(0);
        }


2在XML文件里放置一个伪item,遮挡住listview的第一个item,它用来做碰撞位移  

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    >


    <ListView
        android:id="@+id/listview_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
    <LinearLayout
        android:id="@+id/title_layout"
        android:layout_width="fill_parent"
        android:layout_height="30dp"
        android:layout_gravity="right|top"
        android:background="#ff303030"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/title_layout_catalog"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="22sp"
            android:textColor="@android:color/white"
            android:background="@android:color/holo_green_light"
            android:gravity="center"
            />
    </LinearLayout>

    <com.explam.slidelayoutdemo.QuickIndexBar
        android:id="@+id/quick_index"
        android:background="#f00"
        android:layout_width="30dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"/>

    <TextView
        android:id="@+id/tv_letter"
        android:visibility="invisible"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/quick_index"
        />
</RelativeLayout>
3在代码里设置listview的滚动监听,通过firstVisibleItem去判断所属分类,当(firstVisibleItem + 1 == nextSectionPosition)第一个可见条目的下一个item与判断出来的下一个分类的位置相同的时候,就要开始进行碰撞效果实现  

//设置滚动监听,去实现挤压效果
        mLv_main.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                                 int totalItemCount) {
                //通过第一个可见条目索引拿到这个位置的Ascii码,即字母A的Ascii码
                int section = adapter.getSectionForPosition(firstVisibleItem);
                //获取第二个可见条目位置的Ascii码,可能是A,也可能是其他
                int nextSection = adapter.getSectionForPosition(firstVisibleItem + 1);
                //通过第二个可见条目的Ascci码,拿到它的字母的位置
                int nextSectionPosition = adapter.getPositionForSection(nextSection);
                System.out.println("next:"+(+nextSection));
                float titleY = view.getY();//获取listview在容器里的Y坐标(其实就是0)
                //如果上次记录的可见条目索引不等于现在的滚动到的可见条目索引
                if (lastVisibleIndex != firstVisibleItem) {
                    //就将固定在顶部的伪item布局的文本设置为当前可见条目的分类名
                    mTitle.setText((char) section + "");
                }

                //如果当前可见条目的下一个条目就是下一个分组字母的位置
                if (firstVisibleItem + 1 == nextSectionPosition) {
                    View firstView = view.getChildAt(0);//获取listview当前显示的第一个孩子
                    int bottom = firstView.getBottom();//得到第一个孩子当前的底部bottom
                    int titleLayoutHeight = titleLayout.getHeight();

                    //如果bottom小于伪item的容器高度,说明要开始进行挤压碰撞了
                    if (bottom < titleLayoutHeight) {
                        //求出差值,即需要设置给伪容器的y坐标,实现碰撞效果
                        titleY = bottom - titleLayoutHeight;
                    }
                }
                //未满足上面的条件,就将伪容器的y坐标设置的和listview一样,满足了就设置计算的值
                titleLayout.setY(titleY);
                lastVisibleIndex = firstVisibleItem;
            }
        });



猜你喜欢

转载自blog.csdn.net/qq_35213388/article/details/53167334
今日推荐