使用嵌套滚动实现viewpager和header的联动

要实现ViewPager 添加一个头部,并和 viewPager 中子 view 的联动效果;可能大家第一印象都是又得处理touch 事件了。不错,处理事件是万能的,也是所有这一些列问题的基础。不过处理事件对于很多人来说确实还是一个复杂而有难度的过程。其实 google 也意识到了这一点,之后出的一些框架和技术都是尽量做了封装,尽量避免让开发者去做这些复杂的事件。
今天我们就使用嵌套滚动实现 viewPager 添加一个 header 并实现和其子 View 的联动效果。
先看一下效果图:

首先不了解嵌套滚动的基本用法的同学,先看一下嵌套滚动的基本用法和几个回掉方法的含义,然后再向下看。
先说一下实现思路,然后再看代码吧

阅读全文

事件传递温习

Android 事件传递

事件传递总得来说就是自上而下一次传递,通过分发,拦截,处理等步骤,从上到下,依次分发询问,中间可进行拦截,可进行消费。
先看下图:

阅读全文

Android嵌套滚动入门

嵌套滚动是 Android OS 5.0之后,google 为我们提供的新特性。这种机制打破了我们对之前 Android 传统的事件处理的认知。从一定意义上可以理解为嵌套滚动是逆向的事件传递机制。

如上图所示,其原理就是这样。那么下边我们从代码的层面看一下实现。
代码中主要涉及到了四个类:
NestedScrollingChild、NestedScrollingChildHelper、
NestedScrollingParent、NestedScrollingParentHelper
先看NestedScrollingChild 接口中定义的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public interface NestedScrollingChild {
/**
* 设置是否启用嵌套滚动
*/
public void setNestedScrollingEnabled(boolean enabled);

/**
* 判断是否启用嵌套滚动
*/
public boolean isNestedScrollingEnabled();

/**
* 开始嵌套滚动
* @param axes 标识方向,有 x, y 方形和默认值0
*/
public boolean startNestedScroll(int axes);

/**
* 嵌套滚动结束
*/
public void stopNestedScroll();

/**
* 判断父 view 是否支持嵌套滚动
*/
public boolean hasNestedScrollingParent();

/**
* 分发嵌套滚动,一般再 onTouch/onInterceptTouchEvent/dispatchTouchEvent 中调用
* @param dxConsumed x轴滚动的距离
* @param dyConsumed y 轴滚动的距离
* @param dxUnconsumed x 轴上未消费的距离
* @param dyUnconsumed y 轴上未消费的距离
* @param offsetInWindow 子 View 的窗体偏移
*/
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);

/**
* 滚动之前调用,进行分发预滚动事件
*/
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);

/**
* 滑动时调用 ,分发滑动事件
*/
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);

/**
* 滚动之前调用,分发预滚动事件
*/
public boolean dispatchNestedPreFling(float velocityX, float velocityY);
}

阅读全文

RecyclerView绑定View时更新数据问题解决

线上版本报了一个很奇怪的异常Java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll
看到这个确实是源码里抱出来的,查了很久后来发现: 在 bindView 的时候不能直接调用 notify 更新 view,如果在 bindView 的时候直接调用notify 的操作,就会出现上边异常。
解决方案:
将 notify 的操作放置到Runnable 队列里去执行,以保证本次 notify 执行完成后再执行下一次 notify 的操作。

阅读全文

Java设计模式总结---单例模式

最近想系统的总结学习一下 java 的设计模式,于是做了计划每周搞一个。从最熟悉的开始吧—–单例 Singleton。

使用情景

单例目的是保证只有一个对象,所以一般使用单例有两种情况:一种真的就是需要一个对象,例如缓存,数据库,日志对象,读取配置;另一种是创建一个对象比较耗时,这时我们可以考虑使用单例,只创建一次。

阅读全文

vim笔记一

光标

  • hjkl 四个键操作光标方向。 j, k 上下 h,l 左右。

    vim 的进入和退出

阅读全文

shell正则表达式

正则的意义

正则对于平时的开发工作是非常有意义的,如果不用正则有可能你需要复杂的逻辑去完成一个需求。然而,使用正则的时候经常会骂娘, 为什么骂娘? 无非两个原因: 一、看不懂了。二、忘记了规则实在写不出来。 其实,如果不是特别经常使用正则确实会忘的比较厉害。但是,如果你对正则进行一个深入的理解,是有助于长期记忆的。

阅读全文

Gradle守护进程导致的android打包异常

公司内部打包平台可以根据不同分支不同渠道信息进行自动化打包。昨天发版打包时竟然发现了一个特别诡异的问题导致生成的 apk 安装包直接崩溃。

问题描述

先选择含有听云sdk 代码的分支进行自动化打包,打包完毕验证 apk 没有问题; 然后选择不含有听云 sdk 代码的分支进行自动化打包,打包完成,验证 apk,直接启动崩溃。查看 log
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/networkbench/agent/impl/instrumentation/NBSSQLiteInstrumentation;
看到上述 log,第一反应有点懵逼,怎么会包听云 sdk 中的类呢。明明代码中没有引入听云 sdk。 难道 代码 checkout 出错了?难道 build脚本我忘记 clean Task 了? 难道 clean 代码没有 clean 干净?……

阅读全文

SQLite迁移到GreenDao

从原生的 SQLite 迁移到 GreenDao 数据库框架整体上来讲还是相对比较容易的,这也归功与 GreenDao 易用的 API 和编译期注解。

整体的设计思路

db_framework

阅读全文

Android数据库调研以及GreenDao3使用

网易新闻客户端对数据库的依赖是比较重的,很多数据都存在了客户端数据库,因此我们很早之前就想将数据库模块进行改造。于是我们对目前 Android 上使用比较广泛的数据库框架做了一个调研,并写了一个 demo 比较了一下各个框架的性能和易用性。

Android 上常用的数据库框架

调研了一下目前 android 上常用的数据库框架,主要有:

阅读全文