Android下拉刷新底部操作栏的隐藏问题

最近自己编写下拉刷新的时候,发现了一个问题,就是有一个需求是这样的:要求页面中是一个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());
          }
      }
});

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

时间: 2024-11-04 22:47:43

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

Android下拉刷新库,利用viewdraghelper实现,集成了下拉刷新,底部加载更多,数据初始加载显示loading等功能

项目Github地址:https://github.com/sddyljsx/pulltorefresh Android下拉刷新库,利用viewdraghelper实现. 集成了下拉刷新,底部加载更多,以及刚进入加载数据的loadview.包括了listview与gridview的改写. 效果1: 效果2: 效果3: 效果4: 效果5: 使用说明: imageList=(ListView)findViewById(R.id.image_list); imageAdapter=new ImageA

【原创:参赛作品】窥视懒人的秘密---android下拉刷新开启手势的新纪元

小飒的成长史原创作品:窥视懒人的秘密---android下拉刷新开启手势的新纪元转载请注明出处 *****************************************************************        前言:窥视懒人那些不为人知的秘密 ***************************************************************** 作为一个程序员,哪有不勤奋的道理,当我们都在为技术奋不顾身的时候.偏偏懒人创造了世界. 有的

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

转载请标明原文地址:http://blog.csdn.net/yalinfendou/article/details/47707017 关于Android下拉刷新上拉加载,网上的Demo太多太多了,这里不是介绍怎么去实现下拉刷新上拉加载,而是针对下拉刷新上拉加载常用的一些应用场景就行了一些总结,包含了下拉刷新上拉加载过程中遇到的一些手势冲突问题的解决方法(只能算是抛砖引玉). 去年9月的时候,那时自己正在独立做Android项目.记得刚刚写完那个ListView列表页面(木有下拉刷新,上拉加载)

Android 下拉刷新上拉加载效果功能,使用开源项目android-pulltorefresh实现

应用场景: 在App开发中,对于信息的获取与演示,不可能全部将其获取与演示,为了在用户使用中,给予用户以友好.方便的用户体验,以滑动.下拉的效果动态加载数据的要求就会出现.为此,该效果功能就需要应用到所需要的展示页面中. 知识点介绍: 本文主要根据开源项目android-pulltorefresh展开介绍. android-pulltorefresh [一个强大的拉动刷新开源项目,支持各种控件下拉刷新 ListView.ViewPager.WevView.ExpandableListView.G

Android 下拉刷新上拉加载效果功能

应用场景: 在App开发中,对于信息的获取与演示,不可能全部将其获取与演示,为了在用户使用中,给予用户以友好.方便的用户体验,以滑动.下拉的效果动态加载数据的要求就会出现.为此,该效果功能就需要应用到所需要的展示页面中. 知识点介绍: 本文主要根据开源项目android-pulltorefresh展开介绍. android-pulltorefresh [一个强大的拉动刷新开源项目,支持各种控件下拉刷新 ListView.ViewPager.WevView.ExpandableListView.G

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

转载请标明原文地址:http://blog.csdn.net/yalinfendou/article/details/47707017 关于Android下拉刷新上拉载入,网上的Demo太多太多了,这里不是介绍怎么去实现下拉刷新上拉载入,而是针对下拉刷新上拉载入经常使用的一些应用场景即可了一些总结,包括了下拉刷新上拉载入过程中遇到的一些手势冲突问题的解决方法(仅仅能算是抛砖引玉). 去年9月的时候.那时自己正在独立做Android项目. 记得刚刚写完那个ListView列表页面(木有下拉刷新,上

android 下拉刷新上拉加载更多,高仿ios左滑动删除item,解决了众多手势问题

一.前言 老规矩,别的不说,这demo是找了很相关知识集合而成的,可以说对我这种小白来说是绞尽脑汁!程序员讲的是无图无真相!现在大家一睹为快! 二.比较关键的还是scroller这个类的 package com.icq.slideview.view; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; i

Android下拉刷新,上拉加载。

原文:Android下拉刷新,上拉加载. 源代码下载地址:http://www.zuidaima.com/share/1550463747574784.htm Android列表的下拉刷新,上拉加载. 源码截图 package com.zuidaima.stay.pull.lib; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import

android下拉刷新上拉加载简单的实现方法;

项目中需要用到android下拉刷新和上拉加载:所以学习了一个很简单的很方便的一个例子:自己也写过下拉刷新和上拉加载的功能:但是如果每个界面都要实现这个功能的话非常的麻烦:所以学习了别人很好的demo:然后分享一下: 我的学习步骤: 在网上下载demo:然后把必要的导入到项目中: 在此附上下载源码网址:http://download.csdn.net/detail/android_drawing/8596553 所有的源代码如下: XListViewFooter类 /** * @file XFo