来来来,随老夫撸一个支付宝玩玩——自定义Behavior的正确打开方式

本文介绍了如何实现类似支付宝首页的功能,通过自定义CoordinatorLayout的Behavior来协调子View交互。文章详细讲解了Behavior的核心组件以及关键方法的实现,包括layoutDependsOn、onLayoutChild、onDependentViewChanged等,辅以代码示例,帮助读者理解自定义Behavior的过程。最后提到了作者使用自封装的RecycleView库,但未公开源码。

最近在和项目经理都斗智斗勇的时候,突然被甩过来一个类似支付宝首页的功能需求,虽然网上有一些类似的功能,但是都是以前比较老一些的版本,于是决定自己来定制一个,老规矩,先上图

GIF.gif

要实现这样一个效果,首先想到的自然就是 CoordinatorLayout;

什么是CoordinatorLayout?
CoordinatorLayout是用来协调其子view们之间动作的一个父view,而Behavior就是用来给CoordinatorLayout的子view们实现交互的。关于这个控件,大神们已经介绍的很详细了,这里我就不过多啰嗦,直接开撸了

关于Behavior
要自定义Behavior,首先要搞清楚两个核心View,child 和 dependency;他们分别代表的是要应用behavior的View 和触发behavior并与child进行互动的View。

要实现上面的的效果,需要实现以下几个关键方法
- layoutDependsOn(CoordinatorLayout parent, View child, View dependency)
用来判断child是否有一个对应的dependency,如果有就返回true,默认情况下返回的是false

  • onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection)
    此方法可用于动态更改childView的布局,如果自定义Behaior,这个方法一定返回true,否则将使用默认Behavior的布局

  • onDependentViewChanged(CoordinatorLayout parent, View child, View dependency)
    此方法在dependencyView发生变化的时候调用,在这里,我们可以对child根据dependency的变化进行一定的操作

  • onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes)
    此方法表示开始滑动,最后一个参数表示的是滑动方向,并且只有在返回值为true的时候才能出发接下来的操作,在这里可以进行一些过滤操作,比如值接受垂直方向的滑动等

  • onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes)
    在onStartNestedScroll返回为true的时候调用,此时表示CoordinatorLayout已经拦截了滑动,在这里可以做一些滑动初始化的操作

  • onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed)
    在开始嵌套滑动之前,会执行此操作,dx、dy分别表示用户手指滑动的距离,consumed则表示在操作过程中,消耗掉的滑动距离,例如:

consumed[1] = dy;

此时表示垂直方向的滑动被全部消耗,将不会被传递到下一步操作,相对应的child,如RecycleView将不能接受的滑动操作,不会进行滑动

  • onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)
    此方法在嵌套滑动时候调用,可以多滑动过程进行操作

OK,各位看官,主要方法介绍完了,我懂,现在要开始贴代码了对吧,老夫混迹各大网站多年,不会被打的,代码来了

首先,由于 我们确定是否应用自定义Behavior,如果是就返回true

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        if (child != null) {
            childeView = new WeakReference<View>(child);
        }
        
以下是一个使用 Java 实现将大量逐条到来的数据先入队,然后批量入库的代码示例。此示例假设使用 JDBC 进行数据库操作,并且使用 `LinkedBlockingQueue` 作为队列来存储数据。 ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; // 定义数据对象 class Data { private String field1; private int field2; public Data(String field1, int field2) { this.field1 = field1; this.field2 = field2; } public String getField1() { return field1; } public int getField2() { return field2; } } // 批量入库任务类 class BatchInsertTask implements Runnable { private final LinkedBlockingQueue<Data> queue; private static final int BATCH_SIZE = 100; private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database"; private static final String DB_USER = "your_username"; private static final String DB_PASSWORD = "your_password"; public BatchInsertTask(LinkedBlockingQueue<Data> queue) { this.queue = queue; } @Override public void run() { List<Data> batch = new ArrayList<>(BATCH_SIZE); while (true) { try { // 从队列中取出数据 Data data = queue.take(); batch.add(data); // 当达到批量大小或者队列为空时执行批量插入 if (batch.size() >= BATCH_SIZE || queue.isEmpty()) { insertBatch(batch); batch.clear(); } } catch (InterruptedException | SQLException e) { e.printStackTrace(); } } } private void insertBatch(List<Data> batch) throws SQLException { try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); PreparedStatement statement = connection.prepareStatement("INSERT INTO your_table (field1, field2) VALUES (?, ?)")) { for (Data data : batch) { statement.setString(1, data.getField1()); statement.setInt(2, data.getField2()); statement.addBatch(); } statement.executeBatch(); } } } // 主类 public class DataEnqueueAndBatchInsert { public static void main(String[] args) { LinkedBlockingQueue<Data> queue = new LinkedBlockingQueue<>(); // 启动批量插入任务线程 Thread batchInsertThread = new Thread(new BatchInsertTask(queue)); batchInsertThread.start(); // 模拟逐条数据到来 for (int i = 0; i < 1000; i++) { Data data = new Data("value" + i, i); try { queue.put(data); } catch (InterruptedException e) { e.printStackTrace(); } } } } ``` ### 代码说明 1. **Data 类**:定义了数据对象,包含两个字段 `field1` 和 `field2`。 2. **BatchInsertTask 类**:实现了 `Runnable` 接口,用于从队列中取出数据并批量插入数据库。 - `queue`:存储数据的队列。 - `BATCH_SIZE`:批量插入的大小。 - `DB_URL`、`DB_USER`、`DB_PASSWORD`:数据库连接信息。 - `run` 方法:不断从队列中取出数据,当达到批量大小或者队列为空时执行批量插入。 - `insertBatch` 方法:使用 `PreparedStatement` 执行批量插入操作。 3. **DataEnqueueAndBatchInsert 类**:主类,创建队列和批量插入任务线程,并模拟逐条数据到来。 ### 注意事项 - 请根据实际情况修改数据库连接信息和表名。 - 此示例使用了 `LinkedBlockingQueue`,它是线程安全的队列。 - 批量插入的大小可以根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值