如果开发同学的项目使用的布局是在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就可以了,负值是向下滚,正值是向上滚。
网友评论