一个ListView/GridView顶部新增一个View,滑动
需求说明
1、如下面的图片所示,右边是一个GridView+轮播图,我们需要滚动GridView,然后顶部的轮播图跟着滚动
移动前.jpg
移动后.jpg
遇到的问题
问题现象.jpg1、最开始,我是把轮播图,放到这个GridView的Header里面,控制GridView隐藏和显示(说明:这个GridView是一个封装好的GridView
,如图所示,手机通讯,运输商,这些都是一个Header,剩下部分就是9宫格),由于Adapter有回收机制的存在,轮播图,会开启多个线程,所以这套方案完全不行。
2、快速滚动,会出现如上图问题现象.jpg
问题解决思路
1、将轮播图与右侧的GridView并存的形式存放,此时我们轮播图肯定是在上层,GridView是在下层,高度相差100dp,为了解决这个高度差的问题,我们需要在adapter里面,对headerView添加一个100dp的空TextView
2、快速滑动,会出现如上图问题现象.jpg的原因是,没有针对textView不可见的时候,没有去立即隐藏轮播图
<FrameLayout
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_toRightOf="@id/left_cai"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--GridView-->
<com.tonicartos.widget.stickygridheaders.StickyGridHeadersGridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray"
android:numColumns="3"
android:scrollbars="none" />
<!--轮播图-->
<com.bigkoo.convenientbanner.ConvenientBanner
android:layout_width="match_parent"
android:layout_height="@dimen/dp_100"
android:background="#ffffff"
app:canLoop="true" />
</FrameLayout>
这里我们定义了轮播图的高度是100dp,接下来看GridView的item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--这里是一个空白的100dp高度-->
<TextView
android:id="@+id/tvitem_empty"
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_height="@dimen/dp_100" />
<!--这里是一个标题-->
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical|left"
android:textColor="#222222"
android:textSize="14sp" />
</LinearLayout>
记住,需要做一个判断,只有header的position == 0的时候,才显示TextView : tvitem_empty的空视图,毕竟我们只有在顶部才会显示轮播图。OK,到这里我们就可以看到移动前.jpg的样式了。
现在我们需要操作滚动的监听,我们通过 View chiView = absListView.getChildAt(0) 获取到界面上第一个视图View,我们需要判断当前获取的chiView 是否为LinearLayout,因为我们的Header布局是LinearLayout,我们通过LinearLayout父容器,再去找到子TextView,如果找到,就是我们需要控制的布局,我们再通过chiView.getTop()控制轮播图的滚动
gridView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
switch (scrollState) {
// 滚动之前,手还在屏幕上 记录滚动前的下标
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
break;
default:
break;
}
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
View chiView = absListView.getChildAt(0);//第一个View
if (chiView.getTag() instanceof LinearLayout) {
LinearLayout linearLayout = (LinearLayout) chiView.getTag();
TextView textView = linearLayout.findViewById(R.id.tv_category_grid_ad_title_item_empty);
if (textView != null && textView.getVisibility() == View.VISIBLE) {
int top = chiView.getTop();
if (Math.abs(top) == textView.getHeight()){
top = -homeCBanner.getHeight();
}
Log.i(TAG, "top:" + top);
FrameLayout.LayoutParams frlayout = (FrameLayout.LayoutParams) homeCBanner.getLayoutParams();
frlayout.setMargins(frlayout.leftMargin,top,frlayout.rightMargin,frlayout.bottomMargin);
homeCBanner.setLayoutParams(frlayout);
/*int scrollDirection = SCROLL_STOP;
if (firstVisibleItem > mLastTopIndex) {
scrollDirection = SCROLL_UP;
} else if (firstVisibleItem < mLastTopIndex) {
scrollDirection = SCROLL_DOWN;
} else {
if (top < mLastTopPixel) {
scrollDirection = SCROLL_UP;
} else if (top > mLastTopPixel) {
scrollDirection = SCROLL_DOWN;
}
}
mLastTopIndex = firstVisibleItem;
mLastTopPixel = top;
if (scrollDirection == SCROLL_DOWN) {//界面往下移动
} else if (scrollDirection == SCROLL_UP) {//界面往上移动
}*/
}else {
//解决快递滑动,没有立即隐藏轮播图问题
FrameLayout.LayoutParams frlayout = (FrameLayout.LayoutParams) homeCBanner.getLayoutParams();
frlayout.setMargins(frlayout.leftMargin, -homeCBanner.getHeight(),frlayout.rightMargin,frlayout.bottomMargin);
homeCBanner.setLayoutParams(frlayout);
}
}else {
FrameLayout.LayoutParams frlayout = (FrameLayout.LayoutParams) homeCBanner.getLayoutParams();
frlayout.setMargins(frlayout.leftMargin, -homeCBanner.getHeight(),frlayout.rightMargin,frlayout.bottomMargin);
homeCBanner.setLayoutParams(frlayout);
}
}
});
总结
1、针对这样要控制视图移动的,最好是使用FrameLayout,如使用Linlayout,1、会出现卡顿 2、会让GlidView也会跟着移动