美文网首页
解决ListView的scrollListBy()方法不生效问题

解决ListView的scrollListBy()方法不生效问题

作者: 小智在不在 | 来源:发表于2017-05-23 22:29 被阅读0次

    如果开发同学的项目使用的布局是在ListView添加头部Item显示细分条目并且头布局中放置指示器的布局可能会出现这种问题,一旦你将ListView的的Select条目选中第一个就会出现指示器被遮挡的问题,当你满心欢喜找到ListView的scrollListBy()方法以为不用在你的Adapter中加入一个Type而使代码变得复杂时却发现调用这个方法之后不生效,WTF! 明明这个API是这样用的啊,不要着急,其实不是这个方法没用,而是因为在ListView没有布局完成时是不知道自己的位置的,此时调用scrollListBy()必然不生效,我们可以通过延时的方式来调用这个方法

    mListView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (mListView != null) {
                        mListView.scrollListBy(-height);
                    }
                }
            }, 100);
    

    但是用之后可能会发现在低版本上失效或者直接报错显示需要API19以上,大多数的应用是需要做向下兼容的,所以这个方法无法完全满足我们的需求,但是ListViwe的父类AbsListView提供一个trackMotionScroll()方法,这是一个private方法,但是我们可以通过反射调用,因为是AbsListView的方法所以我们不能反射ListView而是应该反射AbsListView,那么做判断,API19以上用现有方法,API19以下反射调用

    //让listView下滑一定距离露出“全部评论  赞”的头部,免去在adapter中加入一个类型
        private void trackMotionScroll() {
            final int height = mDivAllCommentsAndPraise.getHeight();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                mListView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                            if (mListView != null) {
                                mListView.scrollListBy(-height);
                            }
                        }
                    }
                }, 100);
            } else {
                mListView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            if (mListView != null) {
                                ReflectUtil.invokeMethod(mListView, "trackMotionScroll", new Object[]{height, height}, new Class[]{int.class, int.class});
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }, 100);
            }
        }
    
    

    这里是我的反射工具类

    public class ReflectUtil {
        /**
         * 遍历当前类以及父类去查找并执行方法
         *
         * @param targetObject
         * @param methodName
         * @param params
         * @param paramTypes
         * @return
         */
        public static Object invokeMethod(Object targetObject, String methodName, Object[] params, Class[] paramTypes) {
            Object returnObj = null;
            if (targetObject == null || TextUtils.isEmpty(methodName)) {
                return null;
            }
            Class cls = targetObject.getClass();
            Method method = null;
            for (; cls != Object.class; cls = cls.getSuperclass()) {
                try {
                    method = cls.getDeclaredMethod(methodName, paramTypes);
                    break;
                } catch (Exception e) {
                    return null;
                }
            }
            if (method != null) {
                method.setAccessible(true);
                try {
                    returnObj = method.invoke(targetObject, params);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return returnObj;
        }
    }
    

    基本可以直接拿来用,将里面获取View高度的地方换成你想要滚动相当高度的View就可以了,负值是向下滚,正值是向上滚。

    相关文章

      网友评论

          本文标题:解决ListView的scrollListBy()方法不生效问题

          本文链接:https://www.haomeiwen.com/subject/lxogxxtx.html