Android-ObservableScrollView(二)

  • Base相关方法

  • FillGap


本篇主要根据官方提供的simple结合源码理解上面相关知识,由于Activity都是根据基类构建出来的,先来了解基类构建以及涉及到的BaseActivity基类内部提供的方法。

BaseActivity提供了ActionBar的高度获取方法根据actionBar的属性actionBarSize,以及获取屏幕content内容视图的高度(get到新技能)

  protected int getActionBarSize() {//在下面提到的header视图布局的TextView会用到actionBarSize属性,个人比较喜欢用View.getMeasuredHeight()
        TypedValue typedValue = new TypedValue();
        int[] textSizeAttr = new int[]{R.attr.actionBarSize};
        int indexOfAttrTextSize = 0;
        TypedArray a = obtainStyledAttributes(typedValue.data, textSizeAttr);
        int actionBarSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
        a.recycle();
        return actionBarSize;
    }

  protected int getScreenHeight() {
        return findViewById(android.R.id.content).getHeight();
    }

setDummyData相关方法迭代只是为视图添加适配器,setDummyDataWithHeader方法核心就两点,为动态创建的headerView配置最小高度和Clickable设置

  headerView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, headerHeight));
  // headerView最小高度
  headerView.setMinimumHeight(headerHeight);
  // 这是需要禁用头的列表选择器效果
  headerView.setClickable(true);
  setDummyDataWithHeader(listView, headerView, num);

下面来看一组效果图

FillGap系类的Simple都继承自基类FillGapBaseActivity extends BaseActivity

public abstract class FillGapBaseActivity<S extends Scrollable> extends BaseActivity implements ObservableScrollViewCallbacks {

}

createScrollable在各自Activity实现里面的控件Observable系列自定义控件实现了Scrollable所以各自Activity直接返回即可,这里的scrollable主要用于获取currentScrollY来更新视图。onScrollChanged滑动变化监听回调后根据scrollY调用updateViews更新视图。下面通过一幅图来理解base里面的变量定义

当然上图效果是展示运行后的效果,布局布局界面却是这样的

那这到底是怎么达到效果,一跳转Activity就把header部分view显示到最下面的呢?且看Base里面的onCreate方法,调用了addOnGlobalLayoutListener,在刚进入界面会执行回调,此时scrollY默认是0,执行updateViews方法更新视图,这里FillGap2BaseActivity基于父类重构getHeaderTranslationY方法重新计算出真正的需要transtionY的值作用于header,下面是相关代码

public abstract class FillGap2BaseActivity<S extends Scrollable> extends FillGapBaseActivity<S> {
    protected float getHeaderTranslationY(int scrollY) {
        return ScrollUtils.getFloat(-scrollY + mFlexibleSpaceImageHeight - mHeaderBar.getHeight(), 0, Float.MAX_VALUE);
    }
}

//.......................................

 protected void updateViews(int scrollY, boolean animated) {
        // If it's ListView, onScrollChanged is called before ListView is laid out (onGlobalLayout).
        // This causes weird animation when onRestoreInstanceState occurred,
        // so we check if it's laid out already.
        if (!mReady) {
            return;
        }
        // 图片的transtionY的值按照scrollY的二分之一来计算,如果按照scrollY值来计算就是平推效果
        ViewHelper.setTranslationY(mImage, -scrollY / 2);

        // Translate header 变化header位置,如果是 scrollY=0,就直接吧header放到了上图位置,第一次加载时候animation为false,让人感觉不到transtion效果
        ViewHelper.setTranslationY(mHeader, getHeaderTranslationY(scrollY));

        // Show/hide gap
        final int headerHeight = mHeaderBar.getHeight();

        boolean scrollUp = mPrevScrollY < scrollY;

        if (scrollUp) {//根据滑动方向调整header视图的背景高度
            if (mFlexibleSpaceImageHeight - headerHeight - mActionBarSize <= scrollY) {
                changeHeaderBackgroundHeightAnimated(false, animated);
            }
        } else {
            if (scrollY <= mFlexibleSpaceImageHeight - headerHeight - mActionBarSize) {
                changeHeaderBackgroundHeightAnimated(true, animated);
            }
        }
        mPrevScrollY = scrollY;
    }

进过FillGap2simple相关的阅读后进行了一下实践发现并没有想象那么简单,首先遇到一个问题,调用ViewHelper.setTranstionY后原来位置还有一片空白,具体原因出在clipChildren属性,设置为false,允许子布局超出视图范围

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="@dimen/flexible_space_image_height"
        android:scaleType="centerCrop"
        android:src="@drawable/example" />

   //..............................

其次呢下拉滑动,header和imageView视图的显示问题,这里需要主要ViewHelper.setTranslationY方法的调用边界控制。具体自行参考官方simple


参考资料:
http://www.cnblogs.com/over140/p/3508335.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值