Android一个ListView/GridView顶部新增一个View,滑动ListView/GridView,顶部View跟着滑动

释放双眼,带上耳机,听听看~!
需求说明

1、如下面的图片所示,右边是一个GridView+轮播图,我们需要滚动GridView,然后顶部的轮播图跟着滚动

移动前.jpg
移动后.jpg
遇到的问题
问题现象.jpg

1、最开始,我是把轮播图,放到这个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也会跟着移动

 

人已赞赏
iOS文章

iOS-拨打电话代码

2019-10-17 17:18:24

iOS文章

iOS-使用QMUITheme实现换肤并适应iOS 13黑暗模式

2019-10-18 7:28:09

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索