临近年终了,来了新需求,博主无奈啊,花了点时间搞出了下图效果
思路分析
上图效果大致分为两部分组成:横向ScrollView+ListView.由于本人对于开源项目了解比较多,滑动悬停效果的PinnedSectionListView(任玉刚)有这个开源库可以实现,可以down 下来加以修改源码。scrollview部分只能自己写了,自定义一个容器inflater下面布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<HorizontalScrollView
android:id="@+id/chainTabView"
android:layout_width="match_parent"
android:scrollbars="none"
android:fadingEdge="none"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/tabParent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<idea.analyzesystem.hover.pinnedsection.PinnedSectionListView
android:id="@+id/pinnedSectionListView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:scrollbars="none" />
</LinearLayout>
构造函数初始化控件,在使用时候通过一个方法传入参数,让PinnedSectionListView绑定adapter,这里adapter使用到洪洋的BaseAdapter库ViewHolder。大致业务逻辑如下
- 添加Tab
- 移除点击以后的tab
- 刷新Tab
- 滑动到ScrollView底部
- ListView滑动到顶部
- PinnedSectionListView源码改造
- Adapter适配器改造
- 数据源包装
首先根据以前玩过PinnedSectionListView的经验,修改源码如下
void createPinnedShadow(int position) {
//layoutParams = (LayoutParams) generateDefaultLayoutParams();
layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
pinnedView.setLayoutParams(layoutParams);
}
接着改造Adapter(其他方法大致相同)
@Override
public View getView(int position, View converView, ViewGroup viewGrop) {
ViewHolder viewHolder = null ;
if (converView == null)
{
View itemView = LayoutInflater.from(context).inflate(setLayoutRes(), viewGrop,false);
viewHolder = new ViewHolder(context, itemView, viewGrop, position);
viewHolder.mLayoutId = setLayoutRes();
} else {
viewHolder = (ViewHolder) converView.getTag();
viewHolder.mPosition = position;
}
T itemBean = getItem(position);
if (itemBean.getType()== T.SECTION) {
convertSection(viewHolder, getItem(position), position);
}else{
convertItem(viewHolder, getItem(position), position);
}
return viewHolder.getConvertView();
}
protected abstract void convertSection(ViewHolder viewHolder, T item, int position);
protected abstract void convertItem(ViewHolder viewHolder, T item, int position);
经过简单改造后测试滑动悬停基本搞定,剩下的就是与ScrollView的联动。在PinnedSectionListView setAdapter同时需要添加第一个tab,此处我们需要一个数据集合用于存放。当我们点击了Item 不同类型有不同响应,如果是组类型需要请求网络数据,返回后ScrollView的LinearLayout动态添加tab。而点击了每个Tab需要刷新ListView以及刷新Tab的UI,并调整Tab和ListView的位置。
listView滑动到顶部只需要设置setSection(0),而ScrollView 这里有个小知识点,ScrollView自带fullScroll方法,调用时最好延时操作(可能你add 、remove childView还没结束)
private void compileScroll() {
postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_RIGHT);
}
}, 100);
}
至于其他的方法都比较简单了,这里不逼逼叨叨了,源码和调用实例都比较简单,喜欢的朋友可以看看。
代码托管地址: