diff --git a/.gitignore b/.gitignore index 39b589f2182e45a6c39eacd1f82af4085fef3f5e..f376fd1fa233e0c6729c9a6102e88b023220b80f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,11 @@ -build/ -gradle/ -.gradle/ -.idea/ -gradlew -gradlew.bat -local.properties *.iml - -# Local files -local.properties - -# Gradle files -.gradle/ -build/ -gradle/ -gradlew -gradlew.bat - -# IntelliJ files -.idea/ -.navigation/ -captures/ -*.iml - -# OS X files -._* +.gradle +.idea +/local.properties .DS_Store +/build +/captures +.externalNativeBuild +/entry/.preview +.cxx + diff --git a/.jitpack.yml b/.jitpack.yml deleted file mode 100644 index f0b927328ae9e60f3755c2185660da786d8c8117..0000000000000000000000000000000000000000 --- a/.jitpack.yml +++ /dev/null @@ -1,2 +0,0 @@ -before_install: - - gradle -b wrapper.gradle diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9e9d5cfda92bfe31f7b38c4cd56eacb54c34b2af..0000000000000000000000000000000000000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -language: android -jdk: oraclejdk8 - -git: - depth: 3 - -branches: - only: - - master - - legacy - - dev - - -android: - components: - - tools - - android-29 - - platform-tools - - build-tools-28.0.3 - - -before_install: - - gradle -b wrapper.gradle - - -after_script: - - cat */build/reports/lint-results.xml - - -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ - -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ - - $HOME/.android/build-cache - - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e8fcfa65c1392f0246f6795e231284a123d1e394 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +## 0.0.1-SNAPSHOT + +ohos 第一个版本 + + * 实现了原库的大部分 api + * 原库中数据切换是在动画移动中,openHarmony是在动画开始时切换 + diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/README.OPENSOURCE b/README.OPENSOURCE new file mode 100644 index 0000000000000000000000000000000000000000..4017411fa3660f574cea8ed3445e26c3179a1f53 --- /dev/null +++ b/README.OPENSOURCE @@ -0,0 +1,19 @@ +[ + + { + + "Name": "RxDiffUtil", + + "License": "Apache License 2.0", + + "License File": " LICENSE ", + + "Version Number": "2.0.0", + + "Upstream URL": "https://github.com/v2rc/RxDiffUtil", + + "Description": "围绕 DiffUtil库的 RecyclerView窗口小部件的Rx包装器,它处理线程并使用来响应对适配器的并发更改" + + } + +] \ No newline at end of file diff --git a/README.md b/README.md index 2f078a9a778b5236c54432b2005f542634f9d578..e49cdde78d329344a6848a52fd06ec47b7efc2ac 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,78 @@ -![Icon](icon.png) RxDiffUtil -============================ -[![Build][1]][2] -[![Release][3]][4] -[![Coverage][5]][6] -[![Versions][7]][8] +# RxDiffUtil -*RxDiffUtil* is an Rx wrapper around the Android [DiffUtil] library for the -`RecyclerView` widget. It handles threading and reacts to concurrent changes -to the adapter with a `ConcurrentModificationException`. +## 项目介绍 -All computation is done on the thread defined by the upstream `Flowable`, -while the application of the diff result and all terminal events are -propagated on the Android main thread. +- 项目名称:RxDiffUtil +- 所属系列:openharmony的第三方组件适配移植 +- 功能:围绕DiffUtil库的 RecyclerView窗口小部件的Rx包装器,它处理线程并使用来响应对适配器的并发更改 +- 项目移植状态:主功能完成(原库中数据切换是在动画移动中,openHarmony是在动画开始时切换) +- 调用差异:无 +- 开发版本:sdk6,DevEco Studio2.2 Beta1 +- 基线版本:Release 2.0.0 -The resulting `Completable` expects upstream to honor backpressure and shares -the subscription to reduce concurrent changes to the adapter. +## 效果演示 + -Usage ------ -Convert any `Flowable` to a `Completable` applying all changes as diff to the -provided adapter. +## 使用说明 +1.创建CustomTableLayout对象,并绑定Provider +``` + CustomTableLayout customTableLayout = new CustomTableLayout(this); + customTableLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig( + ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT)); + DirectionalLayout directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_dl); + directionalLayout.removeAllComponents(); + directionalLayout.addComponent(customTableLayout); + + customTableLayout.setChangeDataListener(this); + provider = new MyProvider(LayoutScatter.getInstance(this)); + List emptyList = new ArrayList<>(); + Pair, DiffResult> initialPair = Pair.create(emptyList, null); + disposable = ThingRepository + .latestThings(FIVE_CHANGE_DATA_TIME, TimeUnit.SECONDS) + .scan(initialPair, (pair, next) -> { + DiffResult result = calculateDiff(); + return Pair.create(next, result); + }) + .skip(1) + .subscribeOn(computation()) + .observeOn(mainThread()) + .subscribe(listDiffResultPair -> { + provider.setThings(listDiffResultPair.f); + listDiffResultPair.s.dispatchUpdatesTo(customTableLayout, provider); + }); +``` - service.observeData() - .subscribeOn(Schedulers.compute()) - .to(RxDiffUtil.with(adapter)) - .calculateDiff(callback)) - .applyDiff(AdapterImpl::setUnsafe) - .subscribe(); +## 测试信息 +CodeCheck代码测试无异常 -Installation ------------- +CloudTest代码测试无异常 -Add [JitPack][4] to your repositories and *RxDiffUtil* to the dependencies +病毒安全检测通过 - compile "com.github.v2rc:rxdiffutil:$rxDiffUtilVersion" +当前版本demo功能与原组件基本无差异 -License -------- +## 版本迭代 +- 0.0.1-SNAPSHOT + +## 版权和许可信息 +``` Copyright (C) 2018 Christian Schmitz Copyright (C) 2017 volders GmbH with <3 in Berlin - + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - - [1]: https://travis-ci.org/v2rc/RxDiffUtil.svg - [2]: https://travis-ci.org/v2rc/RxDiffUtil - [3]: https://jitpack.io/v/v2rc/rxdiffutil.svg - [4]: https://jitpack.io/#v2rc/rxdiffutil - [5]: https://codecov.io/gh/v2rc/RxDiffUtil/badge.svg - [6]: https://codecov.io/gh/v2rc/RxDiffUtil - [7]: https://asapi.herokuapp.com/com.github.v2rc/rxdiffutil@svg - [8]: https://asapi.herokuapp.com/com.github.v2rc/rxdiffutil - [DiffUtil]: https://developer.android.com/reference/android/support/v7/util/DiffUtil.html +``` \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0b0e58fe3fdc93ab7bf87b6d4533b8b63b399553..fd383b9ad5f8cb6947c897734ddc7d7681395fe9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,22 +1,38 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 6 + defaultConfig { + compatibleSdkVersion 5 + } +} + buildscript { repositories { - google() + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } jcenter() } - dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + classpath 'com.huawei.ohos:hap:2.4.5.0' + classpath 'com.huawei.ohos:decctest:1.2.4.1' } } allprojects { repositories { - google() + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } jcenter() } } - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/entry/.gitignore b/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9 --- /dev/null +++ b/entry/.gitignore @@ -0,0 +1 @@ +/build diff --git a/entry/build.gradle b/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..3413f908869a4fa475c4ccfd4f477f0e186f90fd --- /dev/null +++ b/entry/build.gradle @@ -0,0 +1,29 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 6 + defaultConfig { + compatibleSdkVersion 5 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.200' + api 'io.reactivex.rxjava3:rxjava:3.0.3' + implementation 'io.openharmony.tpc.thirdlib:Rxohos:1.0.0' +} +decc { + supportType = ['html', 'xml'] +} diff --git a/entry/proguard-rules.pro b/entry/proguard-rules.pro new file mode 100644 index 0000000000000000000000000000000000000000..f7666e47561d514b2a76d5a7dfbb43ede86da92a --- /dev/null +++ b/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/entry/src/main/config.json b/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..7039cc5ca8d8683a591b32cc5ff4a0fac8717e9b --- /dev/null +++ b/entry/src/main/config.json @@ -0,0 +1,47 @@ +{ + "app": { + "bundleName": "cafe.adriel.ohosaudioconverter.rxdiffutil", + "vendor": "adriel", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "cafe.adriel.ohosaudioconverter.rxdiffutil", + "name": ".MyApplication", + "mainAbility": "cafe.adriel.ohosaudioconverter.rxdiffutil.MainAbility", + "deviceType": [ + "phone", + "tablet" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "name": "cafe.adriel.ohosaudioconverter.rxdiffutil.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ] + } +} \ No newline at end of file diff --git a/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestFunction.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/CustStateChangedListener.java similarity index 39% rename from library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestFunction.java rename to entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/CustStateChangedListener.java index 7f38543d11ccf0afafe614d38eca38ebc9103124..1a18e6b72c0b10eddb3ca23ad0d9a6341d6bf6ec 100644 --- a/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestFunction.java +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/CustStateChangedListener.java @@ -1,11 +1,10 @@ /* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * + * Copyright (C) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,27 +13,37 @@ * limitations under the License. */ -package berlin.volders.rxdiff2.test; +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import ohos.agp.animation.Animator; + +/** + * ThingRepository. + * + * @since 2021-06-29 + */ +public class CustStateChangedListener implements Animator.StateChangedListener { + @Override + public void onStart(Animator animator) { + } -import berlin.volders.rxdiff2.RxDiffUtil; -import io.reactivex.Completable; -import io.reactivex.Flowable; -import io.reactivex.functions.Function; + @Override + public void onStop(Animator animator) { + } -public class AndroidTestFunction implements Function, Completable> { + @Override + public void onCancel(Animator animator) { + } - private final AndroidTestAdapter adapter; - private final Function, T> object; + @Override + public void onEnd(Animator animator) { + } - public AndroidTestFunction(AndroidTestAdapter adapter, Function, T> object) { - this.adapter = adapter; - this.object = object; + @Override + public void onPause(Animator animator) { } @Override - public Completable apply(Flowable o) { - return o.to(RxDiffUtil.with(adapter)) - .calculateDiff(object, adapter) - .applyDiff(adapter); + public void onResume(Animator animator) { } } diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/CustomTableLayout.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/CustomTableLayout.java new file mode 100644 index 0000000000000000000000000000000000000000..fed465e3880145249b274d1e0b537e23ce4cc548 --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/CustomTableLayout.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import cafe.adriel.ohosaudioconverter.rxdiffutil.adapter.BaseProvider; +import ohos.agp.animation.Animator; +import ohos.agp.animation.AnimatorProperty; +import ohos.agp.components.*; +import ohos.agp.window.service.DisplayManager; +import ohos.app.Context; +import ohos.app.dispatcher.TaskDispatcher; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static cafe.adriel.ohosaudioconverter.rxdiffutil.ThingRepository.*; + +/** + * CustomTableLayout. + * + * @since 2021-06-29 + */ +public class CustomTableLayout extends DependentLayout { + private List dependentLayouts; + private TaskDispatcher taskDispatcher; + private List cycleList; + private TableRunnable tableRunnable; + private List tempList; + private boolean isAdd = false; + private BaseProvider mBaseProvider; + private ChangeDataListener changeDataListener; + + /** + * MyRunnable. + * + * @since 2021-06-29 + */ + private class TableRunnable implements Runnable { + @Override + public void run() { + if (tempList.size() > 0) { + tempList.clear(); + } + if (cycleList.size() > 0) { + cycleList.clear(); + } + int cycleNumber = ThingRepository.randomCycleNumber(); + int countCycle = 0; + while (countCycle < cycleNumber) { + int disappearIndex = ThingRepository.randomlyGenerated(mBaseProvider.count()); + if (!cycleList.contains(disappearIndex)) { + cycleList.add(disappearIndex); + countCycle++; + } + } + tempList.addAll(dependentLayouts); + Collections.shuffle(dependentLayouts); // 将集合随机打乱 + hiddenTable(0f, 0, cycleNumber); + } + + private void tableMove(int cycleNumber) { + for (int ii = 0; ii < tempList.size(); ii++) { + for (int jj = 0; jj < dependentLayouts.size(); jj++) { + if (tempList.get(ii) == dependentLayouts.get(jj)) { + AnimatorProperty property = new AnimatorProperty(); + property.setTarget(tempList.get(ii)) + .moveFromX(tempList.get(ii).getContentPositionX()) + .moveFromY(tempList.get(ii).getContentPositionY()) + .moveToX(tempList.get(jj).getContentPositionX()) + .moveToY(tempList.get(jj).getContentPositionY()) + .setDuration(DURATION); + int finalI = ii; + property.setStateChangedListener(new CustStateChangedListener() { + @Override + public void onEnd(Animator animator) { + super.onEnd(animator); + if ((mBaseProvider.count() - 1) == finalI) { + hiddenTable(1.0f, 1, cycleNumber); + } + } + + @Override + public void onStart(Animator animator) { + super.onStart(animator); + if (changeDataListener != null) { + changeDataListener.changeData(tempList.get(finalI), finalI); + } + } + + @Override + public void onResume(Animator animator) { + super.onResume(animator); + } + + @Override + public void onStop(Animator animator) { + super.onStop(animator); + property.stop(); + } + }); + property.start(); + } + } + } + } + + private void hiddenTable(float alpha, int flag, int cycleNumber) { + int disCom = 0; + for (int ii = 0; ii < tempList.size(); ii++) { + for (Integer integer : cycleList) { + if (ii == integer) { + disCom++; + AnimatorProperty property = new AnimatorProperty(); + property.setTarget(tempList.get(ii)) + .alpha(alpha) + .setDuration(DURATION); + int finalDisCom = disCom; + property.setStateChangedListener(new CustStateChangedListener() { + @Override + public void onEnd(Animator animator) { + super.onEnd(animator); + if (flag == 0 && finalDisCom == cycleNumber) { + tableMove(cycleNumber); + } + } + + @Override + public void onStop(Animator animator) { + super.onStop(animator); + property.stop(); + } + }); + property.start(); + } + } + } + } + } + + /** + * CustomTableLayout + * + * @param context Context + */ + public CustomTableLayout(Context context) { + super(context); + } + + /** + * CustomTableLayout + * + * @param context Context + * @param attrSet AttrSet + */ + public CustomTableLayout(Context context, AttrSet attrSet) { + super(context, attrSet); + } + + /** + * CustomTableLayout + * + * @param context Context + * @param attrSet AttrSet + * @param styleName String + */ + public CustomTableLayout(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + } + + /** + * 设置数据 + * + * @param context Context + * @param baseProvider BaseProvider + */ + public void setProvider(Context context, BaseProvider baseProvider) { + mBaseProvider = baseProvider; + initView(context); + } + + private void initView(Context context) { + if (cycleList == null) { + cycleList = new ArrayList<>(); + } + + if (tempList == null) { + tempList = new ArrayList<>(); + } + if (!isAdd) { + if (dependentLayouts == null) { + dependentLayouts = new ArrayList<>(); + } + for (int ii = 0; ii < mBaseProvider.count(); ii++) { + Component dependentLayout = mBaseProvider.getComponent(ii, null, this); + dependentLayouts.add(dependentLayout); + } + initData(context); + } + if (taskDispatcher == null) { + taskDispatcher = context.getUITaskDispatcher(); + } + if (tableRunnable == null) { + tableRunnable = new TableRunnable(); + } + } + + /** + * 循环发送 + */ + public void sendDelayDispatch() { + taskDispatcher.asyncDispatch(tableRunnable); + } + + private void initData(Context context) { + int hh = 0; + int widthTable = DisplayManager.getInstance() + .getDefaultDisplay(context).get() + .getRealAttributes().width / SEVEN; + for (int ii = 0; ii < dependentLayouts.size(); ii++) { + if (ii % SEVEN == 0 && ii != 0) { + hh += COUNT; + } + dependentLayouts.get(ii).setWidth(widthTable); + dependentLayouts.get(ii).setMarginLeft(ii % SEVEN * widthTable); + dependentLayouts.get(ii).setMarginTop(hh); + addComponent(dependentLayouts.get(ii)); + } + isAdd = true; + } + + public void setChangeDataListener(ChangeDataListener changeDataListener) { + this.changeDataListener = changeDataListener; + } + + /** + * ChangeDataListener. + * + * @since 2021-06-29 + */ + public interface ChangeDataListener { + /** + * 刷新数据 + * + * @param component Component + * @param position int + */ + void changeData(Component component, int position); + } +} diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/DiffResult.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/DiffResult.java new file mode 100644 index 0000000000000000000000000000000000000000..7a15721abc8ab2b8200173ed0a8654d7ee2f3ab6 --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/DiffResult.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import cafe.adriel.ohosaudioconverter.rxdiffutil.adapter.BaseProvider; + +/** + * DiffResult. + * + * @since 2021-06-29 + */ +public class DiffResult { + /** + * calculateDiff + * + * @return DiffResult + */ + public static DiffResult calculateDiff() { + return new DiffResult(); + } + + /** + * dispatchUpdatesTo + * + * @param customTableLayout CustomTableLayout + * @param baseProvider BaseProvider + */ + public void dispatchUpdatesTo(CustomTableLayout customTableLayout, BaseProvider baseProvider) { + customTableLayout.setProvider(customTableLayout.getContext(), baseProvider); + customTableLayout.sendDelayDispatch(); + } +} diff --git a/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestDiffUtilCallback.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/MainAbility.java similarity index 30% rename from library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestDiffUtilCallback.java rename to entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/MainAbility.java index 59cd2a3e1777767ff68a50154186f4bdeb112133..3d68a6b0013d6614ee64f583d4165d03ef3c871b 100644 --- a/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestDiffUtilCallback.java +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/MainAbility.java @@ -1,11 +1,10 @@ /* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * + * Copyright (C) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,49 +13,21 @@ * limitations under the License. */ -package berlin.volders.rxdiff2.test; - -import io.reactivex.functions.Function; - -import static androidx.recyclerview.widget.DiffUtil.Callback; - -class AndroidTestDiffUtilCallback extends Callback { - - private final T oldData; - private final T newData; - private final Function sizeOf; +package cafe.adriel.ohosaudioconverter.rxdiffutil; - AndroidTestDiffUtilCallback(T oldData, T newData, Function sizeOf) { - this.oldData = oldData; - this.newData = newData; - this.sizeOf = sizeOf; - } - - @Override - public int getOldListSize() { - try { - return sizeOf.apply(oldData); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - @Override - public int getNewListSize() { - try { - return sizeOf.apply(newData); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - @Override - public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { - return false; - } +import cafe.adriel.ohosaudioconverter.rxdiffutil.slice.MainAbilitySlice; +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +/** + * 主界面 + * + * @since 2021-07-05 + */ +public class MainAbility extends Ability { @Override - public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { - return true; + public void onStart(Intent intent) { + super.onStart(intent); + super.setMainRoute(MainAbilitySlice.class.getName()); } } diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/MyApplication.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..bee818077f268f6b38d5ca74256c498612adf267 --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/MyApplication.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import ohos.aafwk.ability.AbilityPackage; + +/** + * 应用 + * + * @since 2021-07-05 + */ +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/Thing.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/Thing.java new file mode 100644 index 0000000000000000000000000000000000000000..0a2508735104adf2d45dea1451da8694b3894261 --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/Thing.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import ohos.utils.Parcel; +import ohos.utils.Sequenceable; + +/** + * Thing. + * + * @since 2021-06-29 + */ +public class Thing implements Sequenceable { + private int id; + private String text; + private int color; + + private Thing() { + } + + private Thing(int id, String text, int color) { + this.id = id; + this.text = text; + this.color = color; + } + + /** + * builder + * + * @return Builder + */ + public static Builder builder() { + return new Builder(); + } + + @Override + public boolean marshalling(Parcel parcel) { + return parcel.writeInt(id) && parcel.writeString(text) && parcel.writeInt(color); + } + + @Override + public boolean unmarshalling(Parcel parcel) { + id = parcel.readInt(); + text = parcel.readString(); + color = parcel.readInt(); + return true; + } + + public int getId() { + return id; + } + + public String getText() { + return text; + } + + public int getColor() { + return color; + } + + @Override + public boolean hasFileDescriptor() { + return false; + } + + /** + * Builder. + * + * @since 2021-06-29 + */ + public static class Builder { + private int mId; + private String mText; + private int mColor; + + private Builder() { + } + + /** + * 设置id + * + * @param id int + * @return Builder + */ + public Builder id(int id) { + this.mId = id; + return this; + } + + /** + * 设置text + * + * @param text String + * @return Builder + */ + public Builder text(String text) { + this.mText = text; + return this; + } + + /** + * 设置color + * + * @param color int + * @return Builder + */ + public Builder color(int color) { + this.mColor = color; + return this; + } + + /** + * build + * + * @return Thing + */ + public Thing build() { + return new Thing(mId, mText, mColor); + } + } +} diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ThingRepository.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ThingRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..938d5b166f7c4be4d51a9a36d4e2d42c2c6a4617 --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ThingRepository.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.schedulers.Schedulers; + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * ThingRepository. + * + * @since 2021-06-29 + */ +public class ThingRepository { + /** + * 数据 + */ + public static final int COUNT = 100; + /** + * 动画时间 + */ + public static final int DURATION = 1000; + /** + * 一排几个 + */ + public static final int SEVEN = 7; + /** + * 截取数据范围 + */ + public static final float ZERO_POINT_EIGHT = 0.8f; + private static final int CYCLE_COUNT = 10; + private static final int SIXTY_FIVE = 65; + private static final int TWENTY_FIVE = 25; + private static SecureRandom random = new SecureRandom(); + + private ThingRepository() { + } + + /** + * 初始化数据 + * + * @param interval long + * @param timeUnit TimeUnit + * @return Flowable + */ + public static Flowable> latestThings(long interval, TimeUnit timeUnit) { + return Flowable + .interval(0, interval, timeUnit, Schedulers.computation()) + .map(i -> shuffle(randomThings()).subList(0, (int) (COUNT * ZERO_POINT_EIGHT))); + } + + /** + * 初始化数据 + * + * @return List + */ + public static List randomThings() { + List things = new ArrayList<>(COUNT); + for (int ii = 0; ii < COUNT; ii++) { + things.add(newThing(ii)); + } + return things; + } + + /** + * 移除数据 + * + * @param things List + * @return List + */ + public static List shuffle(List things) { + List shuffled = new ArrayList<>(things.size()); + while (!things.isEmpty()) { + Thing thing = things.remove(random.nextInt(things.size())); + shuffled.add(thing); + } + return shuffled; + } + + private static Thing newThing(int id) { + Thing.Builder builder = Thing.builder(); + + builder.id(id); + char first = (char) (random.nextInt(TWENTY_FIVE) + SIXTY_FIVE); + char second = (char) (random.nextInt(TWENTY_FIVE) + SIXTY_FIVE); + char third = (char) (random.nextInt(TWENTY_FIVE) + SIXTY_FIVE); + + builder.text(String.valueOf(new char[]{first, second, third})); + builder.color(random.nextInt()); + + return builder.build(); + } + + /** + * 初始化一个范围的值 + * + * @return int + */ + public static int randomCycleNumber() { + return random.nextInt(CYCLE_COUNT) + CYCLE_COUNT; + } + + /** + * 初始化一个随机数 + * + * @param count int + * @return int + */ + public static int randomlyGenerated(int count) { + return random.nextInt(count); + } +} diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/adapter/BaseProvider.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/adapter/BaseProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..116ad023289bf5c36a023d2a2bc211a09b7de99e --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/adapter/BaseProvider.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil.adapter; + +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; + +/** + * BaseProvider. + * + * @since 2021-06-29 + */ +public abstract class BaseProvider { + /** + * 获取数量 + * + * @return int + */ + public abstract int count(); + + /** + * 获取布局 + * + * @param position 下标 + * @param component component + * @param componentContainer componentContainer + * @return Component + */ + public abstract Component getComponent(int position, Component component, ComponentContainer componentContainer); +} diff --git a/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/slice/MainAbilitySlice.java b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/slice/MainAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..7cb685898b4b472520d13a5d362b2a2dea153f25 --- /dev/null +++ b/entry/src/main/java/cafe/adriel/ohosaudioconverter/rxdiffutil/slice/MainAbilitySlice.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cafe.adriel.ohosaudioconverter.rxdiffutil.slice; + +import cafe.adriel.ohosaudioconverter.rxdiffutil.*; +import cafe.adriel.ohosaudioconverter.rxdiffutil.adapter.BaseProvider; +import io.reactivex.rxjava3.disposables.Disposable; +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.agp.colors.RgbColor; +import ohos.agp.components.*; +import ohos.agp.components.element.ShapeElement; +import ohos.agp.utils.Color; +import ohos.utils.Pair; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static cafe.adriel.ohosaudioconverter.rxdiffutil.DiffResult.calculateDiff; +import static io.reactivex.rxjava3.openharmony.schedulers.OpenHarmonySchedulers.mainThread; +import static io.reactivex.rxjava3.schedulers.Schedulers.computation; + +/** + * 主界面 + * + * @since 2021-07-05 + */ +public class MainAbilitySlice extends AbilitySlice implements CustomTableLayout.ChangeDataListener { + private static final int FIVE_CHANGE_DATA_TIME = 5; + private Disposable disposable; + private MyProvider provider; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setUIContent(ResourceTable.Layout_ability_main); + } + + @Override + public void onActive() { + super.onActive(); + CustomTableLayout customTableLayout = new CustomTableLayout(this); + customTableLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig( + ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT)); + DirectionalLayout directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_dl); + directionalLayout.removeAllComponents(); + directionalLayout.addComponent(customTableLayout); + + customTableLayout.setChangeDataListener(this); + provider = new MyProvider(LayoutScatter.getInstance(this)); + List emptyList = new ArrayList<>(); + Pair, DiffResult> initialPair = Pair.create(emptyList, null); + disposable = ThingRepository + .latestThings(FIVE_CHANGE_DATA_TIME, TimeUnit.SECONDS) + .scan(initialPair, (pair, next) -> { + DiffResult result = calculateDiff(); + return Pair.create(next, result); + }) + .skip(1) + .subscribeOn(computation()) + .observeOn(mainThread()) + .subscribe(listDiffResultPair -> { + provider.setThings(listDiffResultPair.f); + listDiffResultPair.s.dispatchUpdatesTo(customTableLayout, provider); + }); + } + + @Override + protected void onInactive() { + super.onInactive(); + releaseDisposable(); + } + + @Override + protected void onBackground() { + super.onBackground(); + releaseDisposable(); + } + + @Override + protected void onStop() { + super.onStop(); + releaseDisposable(); + } + + private void releaseDisposable() { + if (disposable != null) { + disposable.dispose(); + disposable = null; + } + } + + @Override + public void changeData(Component component, int position) { + Text itemText = (Text) component.findComponentById(ResourceTable.Id_list_item_text); + itemText.setText(provider.getThings().get(position).getText()); + DependentLayout itemDirectionalLayout = (DependentLayout) component + .findComponentById(ResourceTable.Id_list_item_dl); + ShapeElement shapeElement = new ShapeElement(); + shapeElement.setRgbColor(new RgbColor(new Color(provider.getThings().get(position).getColor()).getValue())); + itemDirectionalLayout.setBackground(shapeElement); + } + + /** + * MyProvider + * + * @since 2021-07-05 + */ + private class MyProvider extends BaseProvider { + private List things = new ArrayList<>(); + private LayoutScatter mLayoutScatter; + + MyProvider(LayoutScatter layoutScatter) { + this.mLayoutScatter = layoutScatter; + } + + @Override + public int count() { + return things.size(); + } + + @Override + public Component getComponent(int position, Component component, ComponentContainer componentContainer) { + Component dependentLayout = mLayoutScatter + .parse(ResourceTable.Layout_list_item, componentContainer, false); + Text itemText = (Text) dependentLayout.findComponentById(ResourceTable.Id_list_item_text); + DependentLayout itemDirectionalLayout = (DependentLayout) dependentLayout + .findComponentById(ResourceTable.Id_list_item_dl); + itemText.setText(things.get(position).getText()); + ShapeElement shapeElement = new ShapeElement(); + shapeElement.setRgbColor(new RgbColor(new Color(things.get(position).getColor()).getValue())); + itemDirectionalLayout.setBackground(shapeElement); + return dependentLayout; + } + + public List getThings() { + return things; + } + + public void setThings(List things) { + if (this.things.size() > 0) { + this.things.clear(); + } + this.things = things; + } + } +} diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..416bf0f3bb5c24408ffcc5cbbc7f5a80842fdc4d --- /dev/null +++ b/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "RxDiffUtil" + }, + { + "name": "mainability_description", + "value": "Java_Empty Ability" + }, + { + "name": "mainability_HelloWorld", + "value": "Hello World" + } + ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/graphic/background_ability_main.xml b/entry/src/main/resources/base/graphic/background_ability_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0 --- /dev/null +++ b/entry/src/main/resources/base/graphic/background_ability_main.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/layout/ability_main.xml b/entry/src/main/resources/base/layout/ability_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..4e45e065b819f1c14a372b3c718bacd2aa5033f7 --- /dev/null +++ b/entry/src/main/resources/base/layout/ability_main.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/layout/list_item.xml b/entry/src/main/resources/base/layout/list_item.xml new file mode 100644 index 0000000000000000000000000000000000000000..95418490c18bba5693607ddce6e642441c242636 --- /dev/null +++ b/entry/src/main/resources/base/layout/list_item.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ diff --git a/entry/src/main/resources/en/element/string.json b/entry/src/main/resources/en/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..80a08afe4d91b765996108aa0ec22812b5ab3f1d --- /dev/null +++ b/entry/src/main/resources/en/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "RxDiffUtil" + }, + { + "name": "mainability_description", + "value": "Java_Empty Ability" + }, + { + "name": "mainability_HelloWorld", + "value": "Hello World" + } + ] +} diff --git a/entry/src/main/resources/zh/element/string.json b/entry/src/main/resources/zh/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..530d9b3bfb81505568e0ae67f97aed90b4ea0e43 --- /dev/null +++ b/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "RxDiffUtil" + }, + { + "name": "mainability_description", + "value": "Java_Empty Ability" + }, + { + "name": "mainability_HelloWorld", + "value": "你好,世界" + } + ] +} \ No newline at end of file diff --git a/entry/src/ohosTest/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ExampleOhosTest.java b/entry/src/ohosTest/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ExampleOhosTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ed5c8fee41e6b60bd7c7b6c80d158e1246bf0643 --- /dev/null +++ b/entry/src/ohosTest/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ExampleOhosTest.java @@ -0,0 +1,16 @@ +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import junit.framework.TestCase; +import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry; +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ExampleOhosTest extends TestCase { + @Test + public void testBundleName() { + final String actualBundleName = AbilityDelegatorRegistry.getArguments().getTestBundleName(); + Assert.assertEquals("cafe.adriel.ohosaudioconverter.rxdiffutil", actualBundleName); + } +} \ No newline at end of file diff --git a/entry/src/ohosTest/java/cafe/adriel/ohosaudioconverter/rxdiffutil/RxDiffUtilTest.java b/entry/src/ohosTest/java/cafe/adriel/ohosaudioconverter/rxdiffutil/RxDiffUtilTest.java new file mode 100644 index 0000000000000000000000000000000000000000..734f3c9fd8ea25faed53c1897abde4bfeefe4196 --- /dev/null +++ b/entry/src/ohosTest/java/cafe/adriel/ohosaudioconverter/rxdiffutil/RxDiffUtilTest.java @@ -0,0 +1,24 @@ +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import junit.framework.TestCase; +import org.junit.Test; + +import java.util.List; + + +public class RxDiffUtilTest extends TestCase { + + @Test + public void testGetData() { + List list = ThingRepository.randomThings(); + assertTrue(list.size() > 0); + } + + @Test + public void testRandom() { + int position = ThingRepository.randomlyGenerated(100); + assertTrue(position < 100); + } + + +} diff --git a/entry/src/test/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ExampleTest.java b/entry/src/test/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ExampleTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7c371ba725d411c746f88d2f0f2397cff41d67a9 --- /dev/null +++ b/entry/src/test/java/cafe/adriel/ohosaudioconverter/rxdiffutil/ExampleTest.java @@ -0,0 +1,9 @@ +package cafe.adriel.ohosaudioconverter.rxdiffutil; + +import org.junit.Test; + +public class ExampleTest { + @Test + public void onStart() { + } +} diff --git a/gradle.properties b/gradle.properties index dbb7bf70d15c9c47ae831e64298c1bbc8b5edce9..be492496f9a20ac2d980ef4fc30061f4184c1c40 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,13 @@ -android.enableJetifier=true -android.useAndroidX=true +# Project-wide Gradle settings. +# IDE (e.g. DevEco Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# If the Chinese output is garbled, please configure the following parameter. +# This function is enabled by default when the DevEco Studio builds the hap/app,if you need disable gradle parallel,you should set org.gradle.parallel false. +# more information see https://docs.gradle.org/current/userguide/performance.html +# org.gradle.parallel=false +# org.gradle.jvmargs=-Dfile.encoding=GBK \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/icon.png b/icon.png deleted file mode 100644 index 044390219936a2b62e845c5bf8b4113e82373a87..0000000000000000000000000000000000000000 Binary files a/icon.png and /dev/null differ diff --git a/image/gif.gif b/image/gif.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1c75ca668830f43547dae9a31b3e1d22e9bc934 Binary files /dev/null and b/image/gif.gif differ diff --git a/library/build.gradle b/library/build.gradle deleted file mode 100644 index 81b6030b01a24234eaf52526430627d659b0c094..0000000000000000000000000000000000000000 --- a/library/build.gradle +++ /dev/null @@ -1,55 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'com.github.dcendents.android-maven' - -android { - compileSdkVersion 29 - - defaultConfig { - versionCode 21 - - minSdkVersion 14 - targetSdkVersion 29 - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -dependencies { - api 'androidx.recyclerview:recyclerview:1.0.0' - api 'io.reactivex.rxjava2:rxjava:2.1.17' - - implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' - - testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.10.0' - testImplementation 'org.robolectric:robolectric:4.3' - testImplementation 'androidx.test:core:1.2.0' -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs -} - -task javadoc(type: Javadoc) { - failOnError false - source = android.sourceSets.main.java.sourceFiles - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - options { - links "https://d.android.com/reference/" - linksOffline "https://d.android.com/reference/", "${android.sdkDirectory}/docs/reference/" - } -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -artifacts { - archives sourcesJar - archives javadocJar -} diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml deleted file mode 100644 index da3ddad6018d1c7ae1f9887b4d77f0ac034ef695..0000000000000000000000000000000000000000 --- a/library/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/library/src/main/java/berlin/volders/rxdiff2/OnCalculateDiffResult.java b/library/src/main/java/berlin/volders/rxdiff2/OnCalculateDiffResult.java deleted file mode 100644 index 98cc421bddccaaab8f3dceda8531d1f49d0d0e15..0000000000000000000000000000000000000000 --- a/library/src/main/java/berlin/volders/rxdiff2/OnCalculateDiffResult.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import androidx.annotation.VisibleForTesting; -import androidx.recyclerview.widget.DiffUtil.DiffResult; -import androidx.recyclerview.widget.RecyclerView.Adapter; -import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver; - -import java.lang.ref.WeakReference; -import java.util.ConcurrentModificationException; - -import io.reactivex.functions.Action; -import io.reactivex.functions.BiConsumer; -import io.reactivex.functions.BiFunction; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static androidx.recyclerview.widget.DiffUtil.calculateDiff; - -class OnCalculateDiffResult extends AdapterDataObserver { - - private final Action p; - @VisibleForTesting - final WeakReference adapter; - @VisibleForTesting - final T o; - @VisibleForTesting - final DiffResult diff; - - @VisibleForTesting - boolean invalidated = false; - - OnCalculateDiffResult(WeakReference adapter, T o, BiFunction cb, - boolean dm, Action p) throws Exception { - this.adapter = adapter; - A a = nonLeaking(adapter); - a.registerAdapterDataObserver(this); - Callback callback = cb.apply(a, o); - this.o = o; - this.diff = calculateDiff(callback, dm); - this.p = p; - } - - void applyDiff(BiConsumer onUpdate) throws Exception { - A adapter = nonLeaking(this.adapter); - checkConcurrency(adapter); - onUpdate.accept(adapter, o); - diff.dispatchUpdatesTo(adapter); - p.run(); - } - - @VisibleForTesting - static A nonLeaking(WeakReference adapter) { - A a = adapter.get(); - if (a != null) { - return a; - } - throw new RxDiffUtil.SubscriptionLeak(); - } - - @VisibleForTesting - void checkConcurrency(Adapter adapter) { - if (invalidated) { - throw new ConcurrentModificationException("adapter data changed - diff outdated"); - } - invalidated = true; - adapter.unregisterAdapterDataObserver(this); - } - - @Override - public void onChanged() { - invalidated = true; - nonLeaking(adapter).unregisterAdapterDataObserver(this); - } - - @Override - public void onItemRangeChanged(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { - onChanged(); - } - - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeRemoved(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { - onChanged(); - } -} diff --git a/library/src/main/java/berlin/volders/rxdiff2/OnCalculateDiffSubscriber.java b/library/src/main/java/berlin/volders/rxdiff2/OnCalculateDiffSubscriber.java deleted file mode 100644 index ba929ce2e5607ea9750ea7322618ecfbe4b72af4..0000000000000000000000000000000000000000 --- a/library/src/main/java/berlin/volders/rxdiff2/OnCalculateDiffSubscriber.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 Christian Schmitz - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import androidx.annotation.VisibleForTesting; - -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -import java.lang.ref.WeakReference; - -import io.reactivex.functions.Action; -import io.reactivex.functions.BiFunction; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static androidx.recyclerview.widget.RecyclerView.Adapter; - -class OnCalculateDiffSubscriber - implements Action, Subscriber, Subscription { - - private final Subscriber> observer; - @VisibleForTesting - final WeakReference adapter; - private final BiFunction cb; - private final boolean dm; - - private Subscription s; - - OnCalculateDiffSubscriber(Subscriber> subscriber, - WeakReference adapter, BiFunction cb, boolean dm) { - super(); - this.observer = subscriber; - this.adapter = adapter; - this.cb = cb; - this.dm = dm; - } - - @Override - public final void onSubscribe(Subscription s) { - this.s = s; - observer.onSubscribe(this); - s.request(1); - } - - @Override - public void onNext(T o) { - try { - observer.onNext(new OnCalculateDiffResult<>(adapter, o, cb, dm, this)); - } catch (Exception error) { - onError(error); - } - } - - @Override - public void onComplete() { - observer.onComplete(); - } - - @Override - public void onError(Throwable e) { - observer.onError(e); - } - - @Override - public void cancel() { - s.cancel(); - } - - @Override - public void request(long n) { - } - - @Override - public void run() { - s.request(1); - } -} diff --git a/library/src/main/java/berlin/volders/rxdiff2/RxDiffResult.java b/library/src/main/java/berlin/volders/rxdiff2/RxDiffResult.java deleted file mode 100644 index f90199c44e9e2caa11979f27346c76d67d39358b..0000000000000000000000000000000000000000 --- a/library/src/main/java/berlin/volders/rxdiff2/RxDiffResult.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; - -import java.util.ConcurrentModificationException; - -import io.reactivex.Completable; -import io.reactivex.Flowable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.functions.BiConsumer; - -import static androidx.recyclerview.widget.RecyclerView.Adapter; - -/** - * {@code RxDiffResult} provides an interface to apply the result of the - * {@code RxDiffUtil.calculateDiff()} methods family. Only one - * {@code Completable} returned by {@link #applyDiff(BiConsumer)} should be - * active at any time. Simultaneous application of the diff results in a - * {@link ConcurrentModificationException}. - * - * @param type of the data set - * @param type of the adapter - */ -@SuppressWarnings("WeakerAccess") -public class RxDiffResult { - - @VisibleForTesting - final Flowable> o; - - RxDiffResult(Flowable> o) { - this.o = o.share().observeOn(AndroidSchedulers.mainThread()); - } - - /** - * @param onUpdate callback to update the data set - * @return a {@link Completable} to apply - */ - @NonNull - public Completable applyDiff(@NonNull BiConsumer onUpdate) { - return o.doOnNext(result -> result.applyDiff(onUpdate)).share().ignoreElements(); - } -} diff --git a/library/src/main/java/berlin/volders/rxdiff2/RxDiffUtil.java b/library/src/main/java/berlin/volders/rxdiff2/RxDiffUtil.java deleted file mode 100644 index 9bbcdded290f260c58ecb5a9a1c8191f3463b544..0000000000000000000000000000000000000000 --- a/library/src/main/java/berlin/volders/rxdiff2/RxDiffUtil.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; - -import java.lang.ref.WeakReference; - -import io.reactivex.Completable; -import io.reactivex.Flowable; -import io.reactivex.functions.BiFunction; -import io.reactivex.functions.Function; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static androidx.recyclerview.widget.RecyclerView.Adapter; - -/** - * {@code RxDiffUtil} calculates and applies the diff between new and old data. - * The {@code RxDiffUtil} instance should be applied to an flowable with the - * {@link Flowable#to(Function)} method. After chaining all actions, this also - * transforms the {@link Flowable} into a shared {@link Completable}. - *
- * service.observeData()
- *        .compose(transformer)
- *        .onBackpressureLatest()
- *        .to(RxDiffUtil.with(adapter))
- *        .calculateDiff(callback)
- *        .applyDiff(adapter::setUnsafe)
- *        .subscribe();
- * 
- * - * @param type of the data set - * @param
type of the adapter - */ -@SuppressWarnings("WeakerAccess") -public class RxDiffUtil { - - @VisibleForTesting - final WeakReference adapter; - @VisibleForTesting - final Flowable o; - - RxDiffUtil(WeakReference adapter, Flowable o) { - this.adapter = adapter; - this.o = o; - } - - /** - * @param cb callback to provide the {@link Callback} to calculate the diff - * @return an {@link RxDiffResult} to apply to the adapter - */ - @NonNull - public RxDiffResult calculateDiff(@NonNull BiFunction cb) { - return calculateDiff(cb, true); - } - - /** - * @param cb callback to provide the {@link Callback} to calculate the diff - * @param dm should try to detect moved items - * @return an {@link RxDiffResult} to apply to the adapter - */ - @NonNull - public RxDiffResult calculateDiff(@NonNull BiFunction cb, boolean dm) { - return new RxDiffResult<>(o.lift(s -> new OnCalculateDiffSubscriber<>(s, adapter, cb, dm))); - } - - /** - * @param o old data to use to calculate the diff - * @param cb callback to provide the {@link Callback} to calculate the diff - * @return an {@link RxDiffResult} to apply to the adapter - */ - @NonNull - public RxDiffResult calculateDiff(@NonNull Function o, - @NonNull BiFunction cb) { - return calculateDiff(o, cb, true); - } - - /** - * @param o old data to use to calculate the diff - * @param cb callback to provide the {@link Callback} to calculate the diff - * @param dm should try to detect moved items - * @return an {@link RxDiffResult} to apply to the adapter - */ - @NonNull - public RxDiffResult calculateDiff(@NonNull Function o, - @NonNull BiFunction cb, boolean dm) { - return calculateDiff((a, n) -> cb.apply(o.apply(a), n), dm); - } - - /** - * @param adapter the adapter to apply the diff to - * @param type of the data set - * @param type of the adapter - * @return a transformer function to use with {@link Flowable#to(Function)} - */ - @NonNull - public static Function, RxDiffUtil> - with(final A adapter) { - WeakReference adapterReference = new WeakReference<>(adapter); - return o -> new RxDiffUtil<>(adapterReference, o); - } - - /** - * Exception thrown if the {@link Flowable} modified with {@code RxDiffUtil} - * is still active after the adapter was cleared. - */ - public static class SubscriptionLeak extends IllegalStateException { - SubscriptionLeak() { - } - } -} diff --git a/library/src/test/java/berlin/volders/rxdiff2/OnCalculateDiffResultTest.java b/library/src/test/java/berlin/volders/rxdiff2/OnCalculateDiffResultTest.java deleted file mode 100644 index 5b4225548e4e1622a86776521eb7350f8142d0b1..0000000000000000000000000000000000000000 --- a/library/src/test/java/berlin/volders/rxdiff2/OnCalculateDiffResultTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import androidx.recyclerview.widget.RecyclerView.Adapter; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import java.lang.ref.WeakReference; -import java.util.ConcurrentModificationException; - -import io.reactivex.functions.Action; -import io.reactivex.functions.BiConsumer; -import io.reactivex.functions.BiFunction; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -@SuppressWarnings({"unchecked", "WeakerAccess"}) -@RunWith(MockitoJUnitRunner.class) -public class OnCalculateDiffResultTest { - - @Mock - Adapter adapter; - @Mock - BiFunction callback; - @Mock - Action producer; - @Mock - Callback cb; - @Mock - BiConsumer empty; - - OnCalculateDiffResult result; - - @Before - public void setup() throws Exception { - doReturn(cb).when(callback).apply(any(Adapter.class), any()); - result = new OnCalculateDiffResult<>(new WeakReference<>(adapter), null, callback, false, producer); - } - - @Test - public void applyDiff() throws Exception { - result.applyDiff(empty); - - verify(producer).run(); - } - - @Test(expected = ConcurrentModificationException.class) - public void applyDiff_concurrently() throws Exception { - result.onChanged(); - - result.applyDiff(empty); - } - - @Test - public void onChanged() { - result.onChanged(); - - assertThat(result.invalidated, is(true)); - } - - @Test - public void onItemRangeChanged() { - result.onItemRangeChanged(0, 1); - - assertThat(result.invalidated, is(true)); - } - - @Test - public void onItemRangeChanged_payload() { - result.onItemRangeChanged(0, 1, null); - - assertThat(result.invalidated, is(true)); - } - - @Test - public void onItemRangeInserted() { - result.onItemRangeInserted(0, 1); - - assertThat(result.invalidated, is(true)); - } - - @Test - public void onItemRangeRemoved() { - result.onItemRangeRemoved(0, 1); - - assertThat(result.invalidated, is(true)); - } - - @Test - public void onItemRangeMoved() { - result.onItemRangeMoved(0, 1, 2); - - assertThat(result.invalidated, is(true)); - } - - @Test - public void nonLeaking() { - assertThat(OnCalculateDiffResult.nonLeaking(new WeakReference<>(adapter)), is(adapter)); - } - - @Test(expected = RxDiffUtil.SubscriptionLeak.class) - public void nonLeaking_leaking() { - OnCalculateDiffResult.nonLeaking(new WeakReference(null)); - } - - @Test - public void checkConcurrency() { - result.checkConcurrency(adapter); - } - - @Test(expected = ConcurrentModificationException.class) - public void checkConcurrency_changed() { - result.onChanged(); - - result.checkConcurrency(adapter); - } -} diff --git a/library/src/test/java/berlin/volders/rxdiff2/OnCalculateDiffSubscriberTest.java b/library/src/test/java/berlin/volders/rxdiff2/OnCalculateDiffSubscriberTest.java deleted file mode 100644 index 6f73faf37327eacd154fe81b5d98ca1c95a629e4..0000000000000000000000000000000000000000 --- a/library/src/test/java/berlin/volders/rxdiff2/OnCalculateDiffSubscriberTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2018 Christian Schmitz - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - -import java.lang.ref.WeakReference; - -import io.reactivex.functions.BiFunction; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static androidx.recyclerview.widget.RecyclerView.Adapter; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@SuppressWarnings({"unchecked", "WeakerAccess"}) -@RunWith(MockitoJUnitRunner.class) -public class OnCalculateDiffSubscriberTest { - - @Captor - ArgumentCaptor> result; - - @Mock - Adapter adapter; - @Mock - BiFunction callback; - @Mock - Callback cb; - @Mock - Subscriber subscriber; - @Mock - Subscription subscription; - - OnCalculateDiffSubscriber diff; - - @Before - public void setup() throws Exception { - doReturn(cb).when(callback).apply(any(Adapter.class), any()); - diff = new OnCalculateDiffSubscriber(subscriber, new WeakReference(adapter), callback, false); - diff.onSubscribe(subscription); - } - - @Test - public void onSubscribe() { - verify(subscriber).onSubscribe(diff); - verify(subscription).request(1); - } - - @Test - public void onNext() { - String value = "foobar"; - - diff.onNext(value); - - verify(subscriber, never()).onError(any()); - verify(subscriber, never()).onComplete(); - verify(subscriber).onNext(result.capture()); - OnCalculateDiffResult actual = result.getValue(); - assertThat(actual.adapter.get(), is(diff.adapter.get())); - assertThat(actual.o, is(value)); - assertThat(actual.diff, notNullValue()); - } - - @Test - public void onNext_error() throws Exception { - RuntimeException e = new RuntimeException(); - doThrow(e).when(callback).apply(any(), any()); - - - diff.onNext(""); - - verify(subscriber).onError(e); - verify(subscriber, never()).onComplete(); - verify(subscriber, never()).onNext(any()); - } - - @Test - public void onCompleted() { - diff.onComplete(); - - verify(subscriber, never()).onError(any()); - verify(subscriber).onComplete(); - verify(subscriber, never()).onNext(any()); - } - - @Test - public void onError() { - Throwable e = new Throwable(); - - diff.onError(e); - - verify(subscriber).onError(e); - verify(subscriber, never()).onComplete(); - verify(subscriber, never()).onNext(any()); - } - - @Test - public void cancel() { - diff.cancel(); - - verify(subscription).cancel(); - } - - @Test - public void run() { - diff.run(); - - verify(subscription, times(2)).request(1); - } -} diff --git a/library/src/test/java/berlin/volders/rxdiff2/RxDiffResultTest.java b/library/src/test/java/berlin/volders/rxdiff2/RxDiffResultTest.java deleted file mode 100644 index 1d89410b926b60da8288ae8edcd0d2791ad5d544..0000000000000000000000000000000000000000 --- a/library/src/test/java/berlin/volders/rxdiff2/RxDiffResultTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2018 Christian Schmitz - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import androidx.recyclerview.widget.RecyclerView.Adapter; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.robolectric.RobolectricTestRunner; - -import java.lang.ref.WeakReference; -import java.util.ConcurrentModificationException; - -import io.reactivex.functions.Action; -import io.reactivex.functions.BiConsumer; -import io.reactivex.functions.BiFunction; -import io.reactivex.observers.TestObserver; -import io.reactivex.processors.PublishProcessor; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; - -@SuppressWarnings({"unchecked", "WeakerAccess"}) -@RunWith(RobolectricTestRunner.class) -public class RxDiffResultTest { - - @Mock - BiConsumer action; - @Mock - Adapter adapter; - @Mock - BiFunction callback; - @Mock - Action producer; - @Mock - Callback cb; - - RxDiffResult rxDiffResult; - PublishProcessor emitter; - - @Before - public void setup() throws Exception { - initMocks(this); - doReturn(cb).when(callback).apply(any(Adapter.class), any()); - emitter = PublishProcessor.create(); - rxDiffResult = new RxDiffResult(emitter); - } - - @Test - public void applyDiff() throws Exception { - TestObserver subscriber = rxDiffResult.applyDiff(action).test(); - - emitResult(1); - emitResult(2); - - verify(action).accept(adapter, 1); - verify(action).accept(adapter, 2); - subscriber.assertSubscribed() - .assertNoErrors() - .assertNotComplete() - .assertNoValues(); - } - - @Test - @SuppressWarnings("ResultOfMethodCallIgnored") - public void applyDiff_concurrently() throws Exception { - rxDiffResult.applyDiff(action).test(); - TestObserver subscriber = rxDiffResult.applyDiff(action).test(); - - emitResult(1); - - verify(action).accept(adapter, 1); - subscriber.assertSubscribed() - .assertError(ConcurrentModificationException.class) - .assertNotComplete() - .assertNoValues(); - } - - void emitResult(int i) throws Exception { - emitter.onNext(new OnCalculateDiffResult(new WeakReference(adapter), i, callback, true, producer)); - } -} diff --git a/library/src/test/java/berlin/volders/rxdiff2/RxDiffUtilAndroidTest.java b/library/src/test/java/berlin/volders/rxdiff2/RxDiffUtilAndroidTest.java deleted file mode 100644 index 8d9ee434ca9a1b87569acf9c02399bbfaab5f333..0000000000000000000000000000000000000000 --- a/library/src/test/java/berlin/volders/rxdiff2/RxDiffUtilAndroidTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2018 Christian Schmitz - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -import java.util.Arrays; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.List; - -import berlin.volders.rxdiff2.test.AndroidTestAdapter; -import berlin.volders.rxdiff2.test.AndroidTestFunction; -import io.reactivex.Completable; -import io.reactivex.Flowable; -import io.reactivex.functions.Function; -import io.reactivex.observers.TestObserver; - -import static io.reactivex.Flowable.fromIterable; - -@SuppressWarnings({"unchecked", "WeakerAccess"}) -@RunWith(RobolectricTestRunner.class) -public class RxDiffUtilAndroidTest { - - static final List> values = Arrays.asList( - Collections.emptyList(), - Collections.singletonList("single"), - Arrays.asList("one", "two"), - Collections.emptyList(), - Arrays.asList("one", "two", "three") - ); - - AndroidTestAdapter> adapter; - Function>, Completable> rxDiff; - - @Before - public void setup() { - adapter = new AndroidTestAdapter<>(l -> l == null ? 0 : l.size(), values.get(0)); - rxDiff = new AndroidTestFunction<>(adapter, adapter); - } - - @Test - public void applyDiff_empty() { - TestObserver observer = adapter.test(); - TestObserver subscriber = fromIterable(values) - .take(1) - .to(rxDiff) - .test(); - subscriber.awaitTerminalEvent(); - - subscriber.assertSubscribed() - .assertNoErrors() - .assertComplete() - .assertNoValues(); - observer.assertValue(values.get(0)); - } - - @Test - public void applyDiff_full() { - TestObserver observer = adapter.test(); - TestObserver subscriber = fromIterable(values) - .skip(1) - .take(1) - .to(rxDiff) - .test(); - subscriber.awaitTerminalEvent(); - - subscriber.assertSubscribed() - .assertNoErrors() - .assertComplete() - .assertNoValues(); - observer.assertValue(values.get(1)); - } - - @Test - public void applyDiff_full_empty() { - TestObserver observer = adapter.test(); - TestObserver subscriber = fromIterable(values) - .skip(2) - .take(2) - .to(rxDiff) - .test(); - subscriber.awaitTerminalEvent(); - - subscriber.assertSubscribed() - .assertNoErrors() - .assertComplete() - .assertNoValues(); - observer.assertValues(values.get(2), values.get(3)); - } - - @Test - public void applyDiff_full_full() { - TestObserver observer = adapter.test(); - TestObserver subscriber = fromIterable(values) - .skip(1) - .take(2) - .to(rxDiff) - .test(); - subscriber.awaitTerminalEvent(); - - subscriber.assertSubscribed() - .assertNoErrors() - .assertComplete() - .assertNoValues(); - observer.assertValues(values.get(1), values.get(2)); - } - - @Test - public void applyDiff_stream() { - TestObserver observer = adapter.test(); - TestObserver subscriber = fromIterable(values) - .to(rxDiff) - .test(); - subscriber.awaitTerminalEvent(); - - subscriber.assertSubscribed() - .assertNoErrors() - .assertComplete() - .assertNoValues(); - observer.assertValues(values.toArray(new List[0])); - } - - @Test - public void applyDiff_concurrently() { - rxDiff = new AndroidTestFunction<>(adapter, adapter.notifyOnGet()); - - TestObserver observer = adapter.test(); - TestObserver subscriber = fromIterable(values) - .skip(1) - .to(rxDiff) - .test(); - subscriber.awaitTerminalEvent(); - - subscriber.assertSubscribed() - .assertError(ConcurrentModificationException.class) - .assertNotComplete() - .assertNoValues(); - observer.assertNoValues(); - } -} diff --git a/library/src/test/java/berlin/volders/rxdiff2/RxDiffUtilTest.java b/library/src/test/java/berlin/volders/rxdiff2/RxDiffUtilTest.java deleted file mode 100644 index 702bee97608bb7a655e0542a410ab0f18e7d0722..0000000000000000000000000000000000000000 --- a/library/src/test/java/berlin/volders/rxdiff2/RxDiffUtilTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2018 Christian Schmitz - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.robolectric.RobolectricTestRunner; - -import java.lang.ref.WeakReference; - -import io.reactivex.Flowable; -import io.reactivex.functions.BiFunction; -import io.reactivex.functions.Function; - -import static androidx.recyclerview.widget.DiffUtil.Callback; -import static androidx.recyclerview.widget.RecyclerView.Adapter; -import static io.reactivex.Flowable.empty; -import static io.reactivex.Flowable.never; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; - -@SuppressWarnings({"unchecked", "WeakerAccess"}) -@RunWith(RobolectricTestRunner.class) -public class RxDiffUtilTest { - - @Mock - Adapter adapter; - @Mock - BiFunction callback; - @Mock - Function function; - @Mock - Callback cb; - - RxDiffUtil rxDiffUtil; - - @Before - public void setup() throws Exception { - initMocks(this); - doReturn(cb).when(callback).apply(any(), any()); - rxDiffUtil = new RxDiffUtil(new WeakReference(adapter), never().startWith(1)); - } - - @Test - public void calculateDiff_callback() throws Exception { - OnCalculateDiffResult result = (OnCalculateDiffResult) rxDiffUtil - .calculateDiff(callback) - .o.test() - .assertSubscribed() - .assertNoErrors() - .assertNotComplete() - .assertValueCount(1) - .values().get(0); - - assertThat(result.adapter.get(), is(adapter)); - assertThat(result.o, is(1)); - verify(callback).apply(any(Adapter.class), any()); - } - - @Test - public void calculateDiff_callback_detectMoves() throws Exception { - OnCalculateDiffResult result = (OnCalculateDiffResult) rxDiffUtil - .calculateDiff(callback, false) - .o.test() - .assertSubscribed() - .assertNoErrors() - .assertNotComplete() - .assertValueCount(1) - .values().get(0); - - assertThat(result.adapter.get(), is(adapter)); - assertThat(result.o, is(1)); - verify(callback).apply(any(Adapter.class), any()); - } - - @Test - public void calculateDiff_callback2() throws Exception { - OnCalculateDiffResult result = (OnCalculateDiffResult) rxDiffUtil - .calculateDiff(function, callback) - .o.test() - .assertSubscribed() - .assertNoErrors() - .assertNotComplete() - .assertValueCount(1) - .values().get(0); - - assertThat(result.adapter.get(), is(adapter)); - assertThat(result.o, is(1)); - verify(callback).apply(any(), any()); - verify(function).apply(any()); - } - - @Test - public void calculateDiff_callback2_detectMoves() throws Exception { - OnCalculateDiffResult result = (OnCalculateDiffResult) rxDiffUtil - .calculateDiff(function, callback, false) - .o.test() - .assertSubscribed() - .assertNoErrors() - .assertNotComplete() - .assertValueCount(1) - .values().get(0); - - assertThat(result.adapter.get(), is(adapter)); - assertThat(result.o, is(1)); - verify(callback).apply(any(), any()); - verify(function).apply(any()); - } - - @Test - public void with() throws Exception { - Function, RxDiffUtil> factory = RxDiffUtil.with(adapter); - Flowable flowable = empty(); - rxDiffUtil = factory.apply(flowable); - - assertThat(rxDiffUtil.adapter.get(), is(adapter)); - assertThat(rxDiffUtil.o, is(flowable)); - } -} diff --git a/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestAdapter.java b/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestAdapter.java deleted file mode 100644 index 7240b0d929c1bc0e99ba8cbf41ca30a26d724925..0000000000000000000000000000000000000000 --- a/library/src/test/java/berlin/volders/rxdiff2/test/AndroidTestAdapter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2017 volders GmbH with <3 in Berlin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package berlin.volders.rxdiff2.test; - -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.DiffUtil; - -import io.reactivex.functions.BiConsumer; -import io.reactivex.functions.BiFunction; -import io.reactivex.functions.Function; -import io.reactivex.observers.TestObserver; -import io.reactivex.subjects.ReplaySubject; - -import static androidx.recyclerview.widget.RecyclerView.Adapter; -import static androidx.recyclerview.widget.RecyclerView.ViewHolder; -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; -import static io.reactivex.subjects.ReplaySubject.create; - -public class AndroidTestAdapter extends Adapter implements - Function, T>, BiConsumer, T>, - BiFunction { - - private final ReplaySubject ts = create(); - private final Function sizeOf; - - public AndroidTestAdapter(Function sizeOf, T emptyState) { - this.ts.onNext(emptyState); - this.sizeOf = sizeOf; - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ViewHolder(new View(getApplicationContext())) { - }; - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - } - - @Override - public int getItemCount() { - try { - return sizeOf.apply(apply(this)); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - @Override - public void accept(AndroidTestAdapter adapter, T t) { - adapter.ts.onNext(t); - } - - @Override - public T apply(AndroidTestAdapter adapter) { - int last = adapter.ts.getValues().length - 1; - return adapter.ts.skip(last).blockingFirst(); - } - - @NonNull - @Override - public DiffUtil.Callback apply(@Nullable T oldData, @Nullable T newData) { - return new AndroidTestDiffUtilCallback<>(oldData, newData, sizeOf); - } - - public TestObserver test() { - return ts.skip(1).test(); - } - - public Function, T> notifyOnGet() { - return adapter -> { - adapter.notifyDataSetChanged(); - return adapter.apply(adapter); - }; - } -} diff --git a/settings.gradle b/settings.gradle index d8f14a134bfe59398fc6676d433cafe772807616..4773db73233a570c2d0c01a22e75321acfbf7a07 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':library' +include ':entry' diff --git a/wrapper.gradle b/wrapper.gradle deleted file mode 100644 index 1006bf5cd53a05c296d8f189bf393f165e228f8e..0000000000000000000000000000000000000000 --- a/wrapper.gradle +++ /dev/null @@ -1,5 +0,0 @@ -wrapper { - gradleVersion '5.5.1' - distributionType Wrapper.DistributionType.ALL -} -defaultTasks 'wrapper'