PinnedSectionListView详细介绍(android开源项目)
2016-07-09 11:50
501 查看
我在之前的博客http://blog.csdn.net/lxj1137800599/article/details/51752970 介绍过PinnedSectionListView。但是对于PinnedSectionListView.java 这个文件没有细讲。由于研究源码也是程序猿的一种能力,所以我专门研究了这个java文件。
现在我已经重新输入了adapter中的数据。界面如下:
![](https://img-blog.csdn.net/20160709111105908)
listview里面主要处理滑动时究竟是哪个item要被pin在屏幕的最顶端(上图是绿色的北京字样,itemType属于SECTION)以及滑动时是否会有shadow
那么,我重点介绍一下onScroll这个函数
这个函数重点在这里
首先先要说明firstVisibleItem可不是简简单单的指代最上面的绿色北京字样。那么firstVisibleItem究竟指代什么呢?我们可以先这么看,把所有的颜色去掉,字符要保留,那么就变成两个白底的北京字样。firstVisibleItem就是指第一个白底的北京字样。我们可以将这个listview看成一个普通的listview加上一个放在listview头部的textView,这样就好理解了。(这个函数对应的两个分函数我也在代码里面注释了,这里就不贴出来了)
另外,新建工程来粗略实现一下我刚才的“将这个listview看成一个普通的listview加上一个放在listview头部的textView”的设想
先来activity_main.xml
注意次序,textview要覆盖listview的一部分,所以要放在布局文件的下面
listview里面的item布局:item.xml
为每个条目新建一个类:Item.java
还要自定义一个adapter:MyAdapter.java
最后是MainActivity.java
效果图
![](https://img-blog.csdn.net/20160709113516583)
PinSectionDemo代码地址:http://download.csdn.net/detail/lxj1137800599/9571494
现在我已经重新输入了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
相关文章推荐
- Android的几种通讯方式
- Android开发中结束所有Activity的方法
- Android 程序启动另一个程序
- AndroidStudio创建带有toolbar的模板
- Android的事件分发与消费机制
- Android Service
- android开发之R文件报错
- Android弹出式菜单-一种简单的实现方式
- android ViewPager在拖拽到左边和右边的时候,禁止显示黄色或者蓝色的渐变图片的解决方法
- Handler消息传递机制
- android之timer和timertask是否运行在主线程中解答
- EventBus(二)------从register这条线分析EventBus
- Android中的画廊(Gallery)
- Android开发相关的Blog推荐
- Android Volley框架使用(三)
- Android学习笔记
- android之postDelayed是否运行在主线程中解答
- Android Volley框架使用(二)
- Android环境变量的设置
- android 之MTV