您的位置:首页 > 移动开发 > Android开发

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

2016-07-09 11:50 501 查看
我在之前的博客http://blog.csdn.net/lxj1137800599/article/details/51752970 介绍过PinnedSectionListView。但是对于PinnedSectionListView.java 这个文件没有细讲。由于研究源码也是程序猿的一种能力,所以我专门研究了这个java文件。

现在我已经重新输入了adapter中的数据。界面如下:



listview里面主要处理滑动时究竟是哪个item要被pin在屏幕的最顶端(上图是绿色的北京字样,itemType属于SECTION)以及滑动时是否会有shadow

那么,我重点介绍一下onScroll这个函数

这个函数重点在这里

/** 判断列表第一个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的一部分,所以要放在布局文件的下面

<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

<?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

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

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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: