最近自己编写下拉刷新的时候,发现了一个问题,就是有一个需求是这样的:要求页面中是一个Tab切换界面,一个界面有底部操作栏,不可下拉刷新,另一个界面没有底部操作栏,但可以下拉刷新。

按照平常的做法,我在xml文件中使用了RelativeLayout,声明下拉刷新组件的layout_above为底部操作栏,然后在测试的时候发现一个奇怪的现象:如果一开始设置底部操作栏可见,在另一个运行下拉刷新的界面在下拉的时候就会出现和底部操作栏同样位置,同样大小,但颜色采用系统默认的布局,如果设置为不可见,则不会出现这个问题。

<BottomView
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"/>
<RefreshListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/bottom" />

经过调试,底部操作栏的确是在下拉刷新的时候被设为不可见,所以这个迷之物体并不是底部操作栏。

查了一些资料,虽然并没有找到和我一样的问题,但最大的可能就是在RelativeLayout中,如果layout_above对应的组件被gone掉,有可能产生布局错乱的问题。

既然这样,就换一种写法:声明底部操作栏的layout_bellow为下拉刷新组件。可惜,同样的问题还是会产生。

好吧,既然有可能是因为组件的相对关系产生问题,那么思考是否能够动态的添加对应关系。

Android依然可以提供这种方案,可以通过view.getLayoutParams来获取组件的LayoutParams,然后通过addRule和removeRule方法来动态的添加和删除相对关系。但可惜的是,removeRule和addRule这两个方法并不是成套出售的,removeRule需要更高的API才能支持。

想想,为了考虑兼容性问题,还是放弃这种做法。

结合现象,可能的问题就是下拉刷新需要一个下拉区域,而这个区域在View刚被绘制的时候就已经确定好,如果后面的对应关系被打乱了,可能系统也会产生默认的布局来明确这个区域。

更好的解决方法就出来了:将底部操作栏也作为下拉刷新的区域,也就是和下拉刷新组件一起作为一个布局。

问题是解决了,但我觉得不是很舒服:我的 下拉刷新组件是通用的,只要不启动下拉刷新这个功能,它完全就是一个ListView,并且还可以自由的配置没有数据时候的界面。现在因为一个需求,就加入一个特化的底部操作栏,即使可以控制它的可见性一定程度上还是可以保证它是可用的,但如果我要替换底部操作栏呢?

所以我开始把底部操作栏也可以封装进来。

一开始想到的解决方法就是利用面向对象的继承关系,声明一个基类组件,但实际上,Android的xml文件并不能识别组件的继承关系,不能让子类组件用在基类组件声明的地方。

既然继承行不通,就利用组合。

声明一个类,持有自定义布局底部操作栏的引用,就可以对它进行控制。

public class ContactBottomOperation {
private BaseBottomOperation bottomOperation; ...
}

但要想做到自由替换布局,就必须传入layout的id,然后由该类对布局的渲染进行控制。

 public BaseBottomOperation initBottom(int id) {
bottomOperation.setVisibility(View.VISIBLE);
bottomOperation.init(id);
return bottomOperation;
}
public class BaseBottomOperation{
... public void init(int id) {
LayoutInflater.from(context).inflate(id, this);
}
}

问题是解决了,但还是发现一个不舒服的地方:点击事件呢?

因为我只是持有布局的引用,所以我不能让该类实现onItemClickListener,无法监听点击事件,而自定义的底部操作栏也只有在渲染的时候才知道自己的控件到底是啥。

其实,这个问题根本就不是问题,我完全可以在控制类中获取到底部操作栏的控件,然后设置相应的事件,但无法使用ButterKnife这样的工具来简化代码。

rlSave = (RelativeLayout)bottom.findViewById(R.id.rl_save);
rlSave.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onClick(...){
save();
}
}
}

想到ButterKnife原本就是利用反射的原理,于是我也开始思考反射能否解决我的困扰。

这样就可以解决问题了,我只要传入需要监听的View和调用的方法,就可以完成View和事件的绑定。

bottomOperation.setItemClick(rlFav, this, "favorite");
public void setItemClick(View view, final Object object, final String methodName) {
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Class classObj = object.getClass();
try {
Method method = classObj.getMethod(methodName, null);
method.invoke(object, null);
} catch (NoSuchMethodException e) {
LogUtil.e(e.toString());
} catch (InvocationTargetException e) {
LogUtil.e(e.toString());
} catch (IllegalAccessException e) {
LogUtil.e(e.toString());
}
}
});

实际编码中总会遇到各种奇葩的问题,但问题并不是解决了就完事了,往往问题的解决才是真正的开始。

Android下拉刷新底部操作栏的隐藏问题的更多相关文章

  1. 【原创】窥视懒人的秘密---android下拉刷新开启手势的新纪元

    小飒的成长史原创作品:窥视懒人的秘密---android下拉刷新开启手势的新纪元转载请注明出处 **************************************************** ...

  2. Android 下拉刷新上拉载入 多种应用场景 超级大放送(上)

    转载请标明原文地址:http://blog.csdn.net/yalinfendou/article/details/47707017 关于Android下拉刷新上拉载入,网上的Demo太多太多了,这 ...

  3. 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)

    前言 近期在做项目时,使用了一个开源的下拉刷新ListView组件.极其的不稳定,bug还多.稳定的组件又写得太复杂了,jar包较大.在我的一篇博客中也讲述过下拉刷新的实现,即Android打造(Li ...

  4. [转]Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

    版权声明:本文出自郭霖的博客,转载必须注明出处. 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9255575 最近项目中需要用到L ...

  5. Android下拉刷新效果实现

    本文主要包括以下内容 自定义实现pulltorefreshView 使用google官方SwipeRefreshLayout 下拉刷新大致原理 判断当前是否在最上面而且是向下滑的,如果是的话,则加载数 ...

  6. Android 下拉刷新框架实现

    原文地址:http://blog.csdn.net/leehong2005/article/details/12567757 前段时间项目中用到了下拉刷新功能,之前在网上也找到过类似的demo,但这些 ...

  7. Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能 (转)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9255575 最 近项目中需要用到ListView下拉刷新的功能,一开始想图省事,在 ...

  8. Android 下拉刷新上拉载入效果功能

    应用场景: 在App开发中,对于信息的获取与演示.不可能所有将其获取与演示,为了在用户使用中,给予用户以友好.方便的用户体验,以滑动.下拉的效果动态载入数据的要求就会出现. 为此.该效果功能就须要应用 ...

  9. Android下拉刷新上拉载入控件,对全部View通用!

    转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/38868463 前面写过一篇关于下拉刷新控件的博客下拉刷新控件终结者:Pull ...

随机推荐

  1. layer-list实现只有左、右和下边框的圆角矩形

    项目中需要实现如下效果的布局 也就是一个左右下角带圆角,上方不带圆角的白色背景矩形,而且只有左.右和下边框,颜色为浅灰色. 当然,切一个.9图片作为背景也能实现,但是能用代码实现的还是尽量用代码实现, ...

  2. Find Minimum in Rotated Sorted Array leetcode java

    题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 ...

  3. Redis 数据结构之Keys

    这是Redis官方文档的keys列表 (1) set  key value--设置某个键为某个值 (2) get key -- 获取设置的值 (3)del key -- 删除设置的键 (4)expir ...

  4. 【Android源代码下载】收集整理android界面UI效果源码

    在Android开发中,Android界面UI效果设计一直都是很多童鞋关注的问题,今天给大家分享下大神收集整理的多个android界面UI效果,都是源码,都是干货,贡献给各位网友! 话不多说,直接上效 ...

  5. clearfix清除浮动进化史

    我想大家在写CSS的时候应该都对清除浮动的用法深有体会,今天我们就还讨论下clearfix的进化史吧. clearfix清除浮动 首先在很多很多年以前我们常用的清除浮动是这样的. .clear{cle ...

  6. Android酷炫实用的开源框架——UI框架(转)

    转载别人整理好的文章,列出了很多炫酷的UI开源设计 原文地址:http://www.androidchina.net/1992.html 1.Side-Menu.Android分类侧滑菜单,Yalan ...

  7. Android判断当前线程是否是主线程的方法

    开发过程中有时候会在Thread类中执行某些操作,有些操作会由于Android版本的不同,尤其是低版本而Crash,因此必要的时候会查看某些容易引起crash的操作是否是在主线程,这里举三种方法: 方 ...

  8. LOB字段存放在指定表空间 清理CLOB字段及压缩CLOB空间

     LOB字段存放在指定表空间 清理CLOB字段及压缩CLOB空间    把LOB字段的SEGMENT 存放在指定表空间.清理CLOB字段及压缩CLOB空间 1.创建LOB字段存放表空间:create ...

  9. C语言代写

    MTRX1702 - C ProgrammingAssignment 2This assignment requires you to design and build a program that ...

  10. 让MyEclipse2013兼容Retina屏幕

    1. 找到文件:/Applications/MyEclipse/MyEclipse Professional.app/Contents/Profile/myeclipse.app/Contents/I ...