PinnedSectionListView详细介绍(android开源项目)

2019-02-21 11:21:54 浏览数 (1)

我在之前的博客http://blog.csdn.net/lxj1137800599/article/details/51752970 介绍过PinnedSectionListView。但是对于PinnedSectionListView.java 这个文件没有细讲。由于研究源码也是程序猿的一种能力,所以我专门研究了这个java文件。 现在我已经重新输入了adapter中的数据。界面如下:

listview里面主要处理滑动时究竟是哪个item要被pin在屏幕的最顶端(上图是绿色的北京字样,itemType属于SECTION)以及滑动时是否会有shadow 那么,我重点介绍一下onScroll这个函数 这个函数重点在这里

代码语言:javascript复制
/** 判断列表第一个item是否属于SECTION */
            final boolean isFirstVisibleItemSection = isItemViewTypePinned(
                    adapter, adapter.getItemViewType(firstVisibleItem));

            if (isFirstVisibleItemSection) {
                // 当前SECTION下第一个item处于滑动中
                View sectionView = getChildAt(0);
                if (sectionView.getTop() == getPaddingTop()) {
                    // 此item完全显示。只执行一次
                    destroyPinnedShadow();
                } else {
                    ensureShadowForPosition(firstVisibleItem, firstVisibleItem,
                            visibleItemCount);
                }
            } else {
                int sectionPosition = findCurrentSectionPosition(firstVisibleItem);
                // Log.i("sectionPosition", sectionPosition   "");
                if (sectionPosition > -1) {
                    ensureShadowForPosition(sectionPosition, firstVisibleItem,
                            visibleItemCount);
                } else {
                    destroyPinnedShadow();
                }
            }

首先先要说明firstVisibleItem可不是简简单单的指代最上面的绿色北京字样。那么firstVisibleItem究竟指代什么呢?我们可以先这么看,把所有的颜色去掉,字符要保留,那么就变成两个白底的北京字样。firstVisibleItem就是指第一个白底的北京字样。我们可以将这个listview看成一个普通的listview加上一个放在listview头部的textView,这样就好理解了。(这个函数对应的两个分函数我也在代码里面注释了,这里就不贴出来了)

另外,新建工程来粗略实现一下我刚才的“将这个listview看成一个普通的listview加上一个放在listview头部的textView”的设想 先来activity_main.xml 注意次序,textview要覆盖listview的一部分,所以要放在布局文件的下面

代码语言:javascript复制
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@ id/FrameLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.listheaderdemo.MainActivity" >

    <ListView
        android:id="@ id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@ id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</FrameLayout>

listview里面的item布局:item.xml

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@ id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

为每个条目新建一个类:Item.java

代码语言:javascript复制
package com.example.listheaderdemo;

public class Item {
    /**
     * item里面的字符串
     */
    private String content;
    /**
     * item的类型(可取值SECTION,ITEM)
     */
    private int type;

    public Item(String content, int type) {
        this.content = content;
        this.type = type;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

还要自定义一个adapter:MyAdapter.java

代码语言:javascript复制
package com.example.listheaderdemo;

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

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {
    private static final int SECTION = 0;
    //private static final int ITEM = 1;

    private List<Item> array = new ArrayList<Item>();
    private Context context;

    public void addItem(Item item) {
        array.add(item);
        notifyDataSetChanged();
    }

    public MyAdapter(Context context) {
        this.context = context;
    }

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

    @Override
    public Item getItem(int position) {
        return array.get(position);
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).getType();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item,
                    null);
        }
        TextView textView = (TextView) convertView.findViewById(R.id.textView1);
        // 如果item属于SECTION,背景为红色,否则默认白色
        if (getItem(position).getType() == SECTION) {
            textView.setBackgroundColor(Color.RED);
        }
        textView.setText(getItem(position).getContent());
        return convertView;
    }
}

最后是MainActivity.java

代码语言:javascript复制
package com.example.listheaderdemo;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnScrollListener {
    private static final int SECTION = 0;
    private static final int ITEM = 1;

    private ListView listView;
    private TextView textView;
    private MyAdapter adapter;

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

        // 新建adapter并输入数据
        adapter = new MyAdapter(this);
        for (int i = 0; i < 5; i  ) {
            Item item = new Item(i   "", SECTION);
            adapter.addItem(item);
            for (int j = 0; j < 10; j  ) {
                Item item2 = new Item(i   "-"   j, ITEM);
                adapter.addItem(item2);
            }
        }

        listView = (ListView) findViewById(R.id.listView1);
        listView.setAdapter(adapter);
        textView = (TextView) findViewById(R.id.tv);
        listView.setOnScrollListener(this);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        // 从firstVisibleItem往上找到最近的SECTION,设置textView的颜色为绿色
        for (int position = firstVisibleItem; position >= 0; position--) {
            int viewType = adapter.getItemViewType(position);
            if (viewType == SECTION) {
                textView.setBackgroundColor(Color.GREEN);
                textView.setText(adapter.getItem(position).getContent());
                textView.setGravity(Gravity.CENTER);
                break;
            }
        }
    }
}

效果图

PinSectionDemo代码地址:http://download.csdn.net/detail/lxj1137800599/9571494

0 人点赞