前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PinnedSectionListView详细介绍(android开源项目)

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

作者头像
提莫队长
发布2019-02-21 11:21:54
6750
发布2019-02-21 11:21:54
举报
文章被收录于专栏:刘晓杰刘晓杰

我在之前的博客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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年07月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档