├── .gitignore ├── LICENSE.txt ├── README.md ├── android.keystore ├── base.gradle ├── build.gradle ├── core ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── mcxiaoke │ └── next │ ├── Charsets.java │ ├── app │ ├── MultiIntentService.java │ ├── NextBaseActivity.java │ └── NextBaseFragment.java │ ├── cache │ ├── DiscCache.java │ ├── IDiscCache.java │ ├── IMemoryCache.java │ ├── LruCache.java │ ├── LruCacheCompat.java │ ├── LruCacheImpl.java │ ├── MapCacheImpl.java │ ├── MemoryCache.java │ └── MemoryCacheImpl.java │ ├── collection │ ├── NoDuplicatesArrayList.java │ ├── NoDuplicatesCopyOnWriteArrayList.java │ ├── NoDuplicatesLinkedList.java │ ├── NoEmptyStringHashMap.java │ └── WeakFastHashMap.java │ ├── common │ └── NextMessage.java │ ├── db │ ├── ExtendedCursor.java │ └── SQLiteContentProvider.java │ ├── geo │ └── LastLocationFinder.java │ ├── io │ ├── BoundedInputStream.java │ ├── CountingInputStream.java │ ├── CountingOutputStream.java │ ├── NameGenerator.java │ ├── ProxyInputStream.java │ ├── ProxyOutputStream.java │ ├── SafeFileNameGenerator.java │ └── StringBuilderWriter.java │ └── utils │ ├── AndroidUtils.java │ ├── AssertUtils.java │ ├── BitmapUtils.java │ ├── CryptoUtils.java │ ├── IOUtils.java │ ├── ImageType.java │ ├── ImageUtils.java │ ├── LogUtils.java │ ├── MimeUtils.java │ ├── NetworkUtils.java │ ├── PackageUtils.java │ ├── ReflectionUtils.java │ ├── StringUtils.java │ ├── ThreadUtils.java │ ├── TrafficUtils.java │ ├── ViewUtils.java │ └── ZipUtils.java ├── deploy ├── docs ├── android-how-app-process-and-activity-started.md ├── android-how-app-ui-displayed.md ├── cache.md ├── core.md ├── func.md ├── http-async.md ├── http.md ├── recycler.md ├── share.md ├── task.md └── ui.md ├── func ├── build.gradle ├── gradle.properties └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── mcxiaoke │ │ └── next │ │ └── func │ │ ├── Fn.java │ │ ├── Range.java │ │ └── functions │ │ ├── Action.java │ │ ├── Action0.java │ │ ├── Action1.java │ │ ├── Action2.java │ │ ├── Func0.java │ │ ├── Func1.java │ │ ├── Func2.java │ │ ├── Function.java │ │ └── Predicate.java │ └── test │ └── java │ └── com │ └── mcxiaoke │ └── next │ └── func │ └── tests │ └── FunctionsTest.java ├── gradle-mvn-push.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── http ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.txt └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── mcxiaoke │ │ └── next │ │ └── http │ │ ├── BodyPart.java │ │ ├── HttpAsync.java │ │ ├── HttpConsts.java │ │ ├── HttpMethod.java │ │ ├── HttpQueue.java │ │ ├── KeyValue.java │ │ ├── LoggingInterceptor.java │ │ ├── NextClient.java │ │ ├── NextParams.java │ │ ├── NextRequest.java │ │ ├── NextResponse.java │ │ ├── NoEmptyValuesHashMap.java │ │ ├── ProgressInterceptor.java │ │ ├── ProgressListener.java │ │ ├── ProgressRequestBody.java │ │ ├── ProgressResponseBody.java │ │ ├── callback │ │ ├── BitmapCallback.java │ │ ├── FileCallback.java │ │ ├── GsonCallback.java │ │ ├── HttpCallback.java │ │ ├── ResponseCallback.java │ │ └── StringCallback.java │ │ ├── exception │ │ └── HttpException.java │ │ ├── job │ │ ├── HttpJob.java │ │ └── HttpJobBuilder.java │ │ ├── processor │ │ └── HttpProcessor.java │ │ ├── support │ │ └── Tuple.java │ │ └── transformer │ │ ├── BitmapTransformer.java │ │ ├── FileTransformer.java │ │ ├── GsonTransformer.java │ │ ├── HttpTransformer.java │ │ ├── ResponseTransformer.java │ │ └── StringTransformer.java │ └── test │ └── java │ └── com │ └── mcxiaoke │ └── next │ └── http │ └── BaseTest.java ├── markets.txt ├── recycler ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.txt └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── mcxiaoke │ │ └── next │ │ └── recycler │ │ ├── AdvancedRecyclerAdapter.java │ │ ├── AdvancedRecyclerArrayAdapter.java │ │ ├── AdvancedRecyclerView.java │ │ └── HeaderFooterRecyclerAdapter.java │ └── res │ └── layout │ └── layout_advanced_recycler_view_loading.xml ├── samples ├── .gitignore ├── build.gradle ├── libs │ └── xbus-0.1.0-SNAPSHOT.jar ├── mcxiaoke.keystore ├── packer.properties ├── proguard-rules.txt └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── mcxiaoke │ │ └── next │ │ └── samples │ │ ├── AlertDialogSamples.java │ │ ├── BaseActivity.java │ │ ├── Data.java │ │ ├── ListViewExtendSamples.java │ │ ├── MotionTrackListView.java │ │ ├── RecyclerViewSample.java │ │ ├── SampleUtils.java │ │ ├── Samples.java │ │ ├── SamplesApp.java │ │ ├── StickyHeaderSamples.java │ │ ├── StringListAdapter.java │ │ ├── TouchFrameLayout.java │ │ ├── bus │ │ ├── BaseBusSample.java │ │ ├── BasicBusSample.java │ │ └── BasicBusSample2.java │ │ ├── core │ │ ├── LicenseSamples.java │ │ └── TaskQueueSamples.java │ │ ├── http │ │ ├── NextClientSamples.java │ │ ├── StatusItem.java │ │ └── User.java │ │ ├── layout │ │ ├── CustomViewGroup.java │ │ ├── FlowLayout.java │ │ ├── FlowLayoutA.java │ │ ├── GridLayout.java │ │ ├── LineLayoutSample.java │ │ ├── SimpleLineLayout.java │ │ ├── ViewGroupDemo.java │ │ └── ViewGroupSample.java │ │ └── license │ │ ├── LicenseHelper.java │ │ ├── LicenseInfo.java │ │ └── LicenseView.java │ └── res │ ├── anim │ ├── anim_bottom_in.xml │ ├── anim_bottom_out.xml │ ├── anim_top_in.xml │ ├── anim_top_out.xml │ ├── disappear.xml │ ├── fade_in.xml │ ├── fade_out.xml │ ├── footer_appear.xml │ ├── footer_disappear.xml │ ├── grow_from_bottom.xml │ ├── grow_from_bottomleft_to_topright.xml │ ├── grow_from_bottomright_to_topleft.xml │ ├── grow_from_top.xml │ ├── grow_from_topleft_to_bottomright.xml │ ├── grow_from_topright_to_bottomleft.xml │ ├── header_appear.xml │ ├── header_disappear.xml │ ├── in_from_left.xml │ ├── in_from_right.xml │ ├── keep.xml │ ├── on_screen_hint_enter.xml │ ├── on_screen_hint_exit.xml │ ├── photo_fade_out.xml │ ├── photo_selection_added.xml │ ├── photo_selection_removed.xml │ ├── pump_bottom.xml │ ├── pump_top.xml │ ├── rail.xml │ ├── shrink_from_bottom.xml │ ├── shrink_from_bottomleft_to_topright.xml │ ├── shrink_from_bottomright_to_topleft.xml │ ├── shrink_from_top.xml │ ├── shrink_from_topleft_to_bottomright.xml │ ├── shrink_from_topright_to_bottomleft.xml │ ├── slide_in.xml │ ├── slide_out.xml │ ├── zoom_enter.xml │ ├── zoom_enter_2.xml │ ├── zoom_exit.xml │ └── zoom_exit_2.xml │ ├── drawable-hdpi │ ├── ic_actionbar_share.png │ └── ic_launcher.png │ ├── drawable-mdpi │ ├── ic_actionbar_share.png │ └── ic_launcher.png │ ├── drawable-xhdpi │ ├── ic_actionbar_share.png │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ ├── act_bus_basic.xml │ ├── act_demo.xml │ ├── act_dialog.xml │ ├── act_endless.xml │ ├── act_list.xml │ ├── act_list_extend.xml │ ├── act_next_executor.xml │ ├── act_next_recycler_view.xml │ ├── act_recycler.xml │ ├── act_simple_line.xml │ ├── act_sticky.xml │ ├── act_text.xml │ ├── act_viewgroup.xml │ ├── dialog_custom.xml │ ├── dialog_custom_title.xml │ ├── dummy_header.xml │ ├── flow_layout_demo.xml │ ├── layout_simple_header.xml │ ├── license_view.xml │ ├── list_item_license.xml │ ├── lt_simple_line.xml │ ├── main.xml │ ├── single.xml │ ├── sticky_header.xml │ ├── view_group_demo.xml │ └── view_group_demo_layout.xml │ ├── menu │ └── main.xml │ ├── raw │ └── licenses.xml │ └── values │ ├── attr.xml │ ├── ids.xml │ ├── strings.xml │ └── themes.xml ├── settings.gradle ├── task ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── mcxiaoke │ └── next │ └── task │ ├── Config.java │ ├── Failure.java │ ├── ITaskCallbacks.java │ ├── ITaskQueue.java │ ├── ITaskRunnable.java │ ├── SimpleTaskCallback.java │ ├── Success.java │ ├── Task.java │ ├── TaskBuilder.java │ ├── TaskCallable.java │ ├── TaskCallback.java │ ├── TaskFactory.java │ ├── TaskFuture.java │ ├── TaskImpl.java │ ├── TaskInfo.java │ ├── TaskQueue.java │ ├── TaskQueueImpl.java │ ├── TaskRunnable.java │ ├── TaskTag.java │ ├── ThreadUtils.java │ ├── WrappedCallable.java │ └── WrappedRunnable.java └── ui ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.txt └── src └── main ├── AndroidManifest.xml ├── java └── com │ └── mcxiaoke │ └── next │ └── ui │ ├── dialog │ ├── AlertDialogFragment.java │ ├── ProgressDialogFragment.java │ └── v4 │ │ ├── AlertDialogFragment.java │ │ └── ProgressDialogFragment.java │ ├── endless │ ├── EndlessAdapter.java │ └── EndlessListView.java │ ├── internal │ └── AdapterWrapper.java │ ├── layout │ ├── CheckableFrameLayout.java │ ├── CheckableImageView.java │ ├── CheckableLinearLayout.java │ ├── CheckableRelativeLayout.java │ ├── NoPressStateFrameLayout.java │ ├── NoPressStateLinearLayout.java │ ├── NoPressStateRelativeLayout.java │ ├── SquaredFrameLayout.java │ ├── SquaredLinearLayout.java │ ├── SquaredRelativeLayout.java │ └── Utils.java │ ├── list │ ├── AdapterExtend.java │ └── ListViewExtend.java │ ├── view │ ├── AspectRatioImageView.java │ ├── AutoScrollListView.java │ ├── CircularImageView.java │ ├── ExpandableTextView.java │ ├── FixedRatioImageView.java │ ├── NonLockingScrollView.java │ ├── SimpleProgressView.java │ └── SquaredImageView.java │ └── widget │ ├── AdvancedShareActionProvider.java │ ├── ArrayAdapterCompat.java │ ├── ArrayAdapterCompat2.java │ ├── ShareTarget.java │ └── v7 │ ├── AdvancedShareActionProvider.java │ └── ShareTarget.java └── res ├── layout └── cv_simple_progress.xml ├── values-zh-rCN └── strings.xml └── values ├── attrs.xml ├── colors.xml ├── dimens.xml ├── ids.xml ├── strings.xml └── styles.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .gradle 3 | build 4 | gen 5 | bin 6 | local.properties 7 | .gradle 8 | *.apk 9 | .*.swp 10 | /.classpath 11 | /.project 12 | .idea/ 13 | .settings/ 14 | gen-external-apklibs/ 15 | target 16 | classes/ 17 | ./gitignore 18 | project.properties 19 | signing.properties 20 | *.iml 21 | .DS_Store 22 | out/ 23 | -------------------------------------------------------------------------------- /android.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/android.keystore -------------------------------------------------------------------------------- /base.gradle: -------------------------------------------------------------------------------- 1 | android { 2 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) 3 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION 4 | 5 | defaultConfig { 6 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION) 7 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 8 | } 9 | 10 | lintOptions { 11 | quiet true 12 | abortOnError false 13 | } 14 | 15 | testOptions { 16 | unitTests.returnDefaultValues = true 17 | } 18 | 19 | } 20 | 21 | apply from: '../gradle-mvn-push.gradle' -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | ext.androidx_version = '1.0.0' 4 | 5 | repositories { 6 | jcenter() 7 | mavenCentral() 8 | google() 9 | maven { url 'https://maven.google.com'} 10 | } 11 | 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:4.0.1' 14 | } 15 | } 16 | 17 | allprojects { 18 | 19 | group project.GROUP 20 | version project.VERSION_NAME 21 | 22 | 23 | repositories { 24 | mavenLocal() 25 | mavenCentral() 26 | jcenter() 27 | google() 28 | maven { url 'https://maven.google.com'} 29 | } 30 | 31 | tasks.withType(JavaCompile) { 32 | options.encoding = 'UTF-8' 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | dependencies { 4 | 5 | testImplementation 'junit:junit:4.12' 6 | testImplementation 'org.mockito:mockito-core:2.18.3' 7 | } 8 | 9 | apply from: '../base.gradle' 10 | 11 | -------------------------------------------------------------------------------- /core/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=Next Commons Library Core 2 | POM_ARTIFACT_ID=core 3 | POM_PACKAGING=aar 4 | -------------------------------------------------------------------------------- /core/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/IDiscCache.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011-2013 Sergey Tarasevich 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.mcxiaoke.next.cache; 17 | 18 | import java.io.File; 19 | import java.io.FileFilter; 20 | import java.io.InputStream; 21 | 22 | public interface IDiscCache { 23 | 24 | void put(String key, byte[] data); 25 | 26 | void put(String key, InputStream stream); 27 | 28 | void put(String key, String text); 29 | 30 | String get(String key); 31 | 32 | File getFile(String key); 33 | 34 | byte[] getBytes(String key); 35 | 36 | boolean remove(String key); 37 | 38 | void clear(); 39 | 40 | int delete(FileFilter filter); 41 | 42 | File getCacheDir(); 43 | 44 | long getCacheSize(); 45 | } 46 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/IMemoryCache.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.cache; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 14-3-21 8 | * Time: 17:18 9 | */ 10 | public interface IMemoryCache { 11 | /** 12 | * Returns the value for {@code key} if it exists in the cache or can be 13 | * created by {@code #create}. If a value was returned, it is moved to the 14 | * head of the queue. This returns null if a value is not cached and cannot 15 | * be created. 16 | */ 17 | V get(K key); 18 | 19 | /** 20 | * Caches {@code value} for {@code key}. The value is moved to the head of 21 | * the queue. 22 | * 23 | * @return the previous value mapped by {@code key}. 24 | */ 25 | V put(K key, V value); 26 | 27 | /** 28 | * Caches {@code value} for {@code key} with expires. The value is moved to the head of 29 | * the queue. 30 | * 31 | * @return the previous value mapped by {@code key}. 32 | */ 33 | V put(K key, V value, long expires); 34 | 35 | /** 36 | * Removes the entry for {@code key} if it exists. 37 | * 38 | * @return the previous value mapped by {@code key}. 39 | */ 40 | V remove(K key); 41 | 42 | /** 43 | * Clear the cache, calling {@link #remove} on each removed entry. 44 | */ 45 | void clear(); 46 | 47 | /** 48 | * For all other caches, this returns the sum of 49 | * the sizes of the entries in this cache. 50 | */ 51 | int size(); 52 | 53 | /** 54 | * For caches that do not override {@link #size}, this returns the maximum 55 | * number of entries in the cache. For all other caches, this returns the 56 | * maximum sum of the sizes of the entries in this cache. 57 | */ 58 | int maxSize(); 59 | 60 | /** 61 | * Returns a copy of the current contents of the cache, ordered from least 62 | * recently accessed to most recently accessed. 63 | */ 64 | Map snapshot(); 65 | 66 | } 67 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/LruCache.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.cache; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 14-3-21 6 | * Time: 17:21 7 | */ 8 | class LruCache extends MemoryCacheImpl { 9 | private IMemoryCache> cache; 10 | 11 | public LruCache(int maxSize) { 12 | super(new LruCacheImpl>(maxSize)); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/LruCacheImpl.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.cache; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 15/6/16 8 | * Time: 13:35 9 | */ 10 | class LruCacheImpl implements IMemoryCache { 11 | 12 | private LruCacheCompat mCache; 13 | 14 | public LruCacheImpl() { 15 | mCache = new LruCacheCompat(Integer.MAX_VALUE / 2); 16 | } 17 | 18 | public LruCacheImpl(int maxSize) { 19 | mCache = new LruCacheCompat(maxSize); 20 | } 21 | 22 | @Override 23 | public V get(final K key) { 24 | return mCache.get(key); 25 | } 26 | 27 | @Override 28 | public V put(final K key, final V value) { 29 | return mCache.put(key, value); 30 | } 31 | 32 | @Override 33 | public V put(final K key, final V value, final long expires) { 34 | throw new UnsupportedOperationException(); 35 | } 36 | 37 | @Override 38 | public V remove(final K key) { 39 | return mCache.remove(key); 40 | } 41 | 42 | @Override 43 | public void clear() { 44 | mCache.evictAll(); 45 | } 46 | 47 | @Override 48 | public int size() { 49 | return mCache.size(); 50 | } 51 | 52 | @Override 53 | public int maxSize() { 54 | return Integer.MAX_VALUE; 55 | } 56 | 57 | @Override 58 | public Map snapshot() { 59 | throw new UnsupportedOperationException(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/MapCacheImpl.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.cache; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * User: mcxiaoke 8 | * Date: 15/6/16 9 | * Time: 13:35 10 | */ 11 | class MapCacheImpl implements IMemoryCache { 12 | 13 | private Map mCache; 14 | 15 | public MapCacheImpl() { 16 | mCache = new HashMap(); 17 | } 18 | 19 | @Override 20 | public V get(final K key) { 21 | return mCache.get(key); 22 | } 23 | 24 | @Override 25 | public V put(final K key, final V value) { 26 | return mCache.put(key, value); 27 | } 28 | 29 | @Override 30 | public V put(final K key, final V value, final long expires) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public V remove(final K key) { 36 | return mCache.remove(key); 37 | } 38 | 39 | @Override 40 | public void clear() { 41 | mCache.clear(); 42 | } 43 | 44 | @Override 45 | public int size() { 46 | return mCache.size(); 47 | } 48 | 49 | @Override 50 | public int maxSize() { 51 | return Integer.MAX_VALUE; 52 | } 53 | 54 | @Override 55 | public Map snapshot() { 56 | throw new UnsupportedOperationException(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/MemoryCache.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.cache; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 14-3-21 6 | * Time: 17:43 7 | */ 8 | public final class MemoryCache { 9 | 10 | private MemoryCache() { 11 | } 12 | 13 | public static IMemoryCache lruCache(int maxSize) { 14 | return new MemoryCacheImpl(new LruCacheImpl>(maxSize)); 15 | } 16 | 17 | public static IMemoryCache mapCache() { 18 | return new MemoryCacheImpl(new MapCacheImpl>()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/cache/MemoryCacheImpl.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.cache; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * User: mcxiaoke 8 | * Date: 14-3-21 9 | * Time: 17:21 10 | */ 11 | class MemoryCacheImpl implements IMemoryCache { 12 | 13 | static class Entry { 14 | public T data; 15 | public int size; 16 | public long expire; 17 | 18 | public Entry() { 19 | 20 | } 21 | 22 | public Entry(final T data) { 23 | this.data = data; 24 | } 25 | 26 | public Entry(final T data, final long expire) { 27 | this.data = data; 28 | this.expire = expire; 29 | } 30 | 31 | public boolean isExpired() { 32 | return expire > 0 && expire < System.currentTimeMillis(); 33 | } 34 | } 35 | 36 | private final Object mLock = new Object(); 37 | private IMemoryCache> cache; 38 | 39 | public MemoryCacheImpl(IMemoryCache> cache) { 40 | this.cache = cache; 41 | } 42 | 43 | @Override 44 | public V get(K key) { 45 | final Entry entry = cache.get(key); 46 | if (entry == null || entry.isExpired()) { 47 | remove(key); 48 | return null; 49 | } 50 | return entry.data; 51 | } 52 | 53 | @Override 54 | public V put(K key, V value) { 55 | final Entry entry = new Entry(value); 56 | final Entry ret = cache.put(key, entry); 57 | return ret == null ? null : ret.data; 58 | } 59 | 60 | @Override 61 | public V put(final K key, final V value, final long expires) { 62 | final Entry entry = new Entry(value, expires); 63 | final Entry ret = cache.put(key, entry); 64 | return ret == null ? null : ret.data; 65 | } 66 | 67 | @Override 68 | public V remove(K key) { 69 | final Entry ret = cache.remove(key); 70 | return ret == null ? null : ret.data; 71 | } 72 | 73 | @Override 74 | public void clear() { 75 | cache.clear(); 76 | } 77 | 78 | @Override 79 | public int size() { 80 | return cache.size(); 81 | } 82 | 83 | @Override 84 | public int maxSize() { 85 | return cache.maxSize(); 86 | } 87 | 88 | @Override 89 | public Map snapshot() { 90 | final Map map = new HashMap(); 91 | for (final Map.Entry> entry : cache.snapshot().entrySet()) { 92 | final Entry c = entry.getValue(); 93 | if (c == null || c.isExpired()) { 94 | continue; 95 | } 96 | map.put(entry.getKey(), c.data); 97 | } 98 | return map; 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/collection/NoDuplicatesArrayList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Twidere - Twitter client for Android 3 | * 4 | * Copyright (C) 2012-2014 Mariotaku Lee 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | package com.mcxiaoke.next.collection; 21 | 22 | import java.util.ArrayList; 23 | import java.util.Collection; 24 | 25 | public class NoDuplicatesArrayList extends ArrayList { 26 | 27 | public NoDuplicatesArrayList() { 28 | } 29 | 30 | public NoDuplicatesArrayList(final Collection collection) { 31 | addAll(collection); 32 | } 33 | 34 | public NoDuplicatesArrayList(final int capacity) { 35 | super(capacity); 36 | } 37 | 38 | @Override 39 | public boolean add(final E e) { 40 | return !contains(e) && super.add(e); 41 | } 42 | 43 | @Override 44 | public void add(final int index, final E element) { 45 | if (!contains(element)) { 46 | super.add(index, element); 47 | } 48 | } 49 | 50 | @Override 51 | public boolean addAll(final Collection collection) { 52 | final Collection copy = new ArrayList(collection); 53 | copy.removeAll(this); 54 | return super.addAll(copy); 55 | } 56 | 57 | @Override 58 | public boolean addAll(final int index, final Collection collection) { 59 | final Collection copy = new ArrayList(collection); 60 | copy.removeAll(this); 61 | return super.addAll(index, copy); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/collection/NoDuplicatesCopyOnWriteArrayList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Twidere - Twitter client for Android 3 | * 4 | * Copyright (C) 2012-2014 Mariotaku Lee 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | package com.mcxiaoke.next.collection; 21 | 22 | import java.util.ArrayList; 23 | import java.util.Collection; 24 | import java.util.concurrent.CopyOnWriteArrayList; 25 | 26 | public class NoDuplicatesCopyOnWriteArrayList extends CopyOnWriteArrayList { 27 | 28 | public NoDuplicatesCopyOnWriteArrayList() { 29 | super(); 30 | } 31 | 32 | public NoDuplicatesCopyOnWriteArrayList(final Collection collection) { 33 | super(collection); 34 | } 35 | 36 | public NoDuplicatesCopyOnWriteArrayList(final E[] array) { 37 | super(array); 38 | } 39 | 40 | @Override 41 | public boolean add(final E e) { 42 | return !contains(e) && super.add(e); 43 | } 44 | 45 | @Override 46 | public void add(final int index, final E element) { 47 | if (!contains(element)) { 48 | super.add(index, element); 49 | } 50 | } 51 | 52 | @Override 53 | public boolean addAll(final Collection collection) { 54 | final Collection copy = new ArrayList(collection); 55 | copy.removeAll(this); 56 | return super.addAll(copy); 57 | } 58 | 59 | @Override 60 | public boolean addAll(final int index, final Collection collection) { 61 | final Collection copy = new ArrayList(collection); 62 | copy.removeAll(this); 63 | return super.addAll(index, copy); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/collection/NoDuplicatesLinkedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Twidere - Twitter client for Android 3 | * 4 | * Copyright (C) 2012-2014 Mariotaku Lee 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | package com.mcxiaoke.next.collection; 21 | 22 | import java.util.Collection; 23 | import java.util.LinkedList; 24 | 25 | public class NoDuplicatesLinkedList extends LinkedList { 26 | 27 | public NoDuplicatesLinkedList() { 28 | super(); 29 | } 30 | 31 | public NoDuplicatesLinkedList(final Collection collection) { 32 | super(collection); 33 | } 34 | 35 | @Override 36 | public void add(final int index, final E element) { 37 | if (!contains(element)) { 38 | super.add(index, element); 39 | } 40 | } 41 | 42 | @Override 43 | public boolean add(final E e) { 44 | return !contains(e) && super.add(e); 45 | } 46 | 47 | @Override 48 | public boolean addAll(final int index, final Collection collection) { 49 | final Collection copy = new LinkedList(collection); 50 | copy.removeAll(this); 51 | return super.addAll(index, copy); 52 | } 53 | 54 | @Override 55 | public boolean addAll(final Collection collection) { 56 | final Collection copy = new LinkedList(collection); 57 | copy.removeAll(this); 58 | return super.addAll(copy); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/collection/NoEmptyStringHashMap.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.collection; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * User: mcxiaoke 8 | * Date: 15/7/6 9 | * Time: 17:34 10 | */ 11 | public class NoEmptyStringHashMap extends HashMap { 12 | 13 | public NoEmptyStringHashMap(final Map map) { 14 | super(); 15 | putAll(map); 16 | } 17 | 18 | @Override 19 | public String put(final String key, final String value) { 20 | if (value == null || value.isEmpty() || key.length() == 0) { 21 | return null; 22 | } 23 | return super.put(key, value); 24 | } 25 | 26 | @Override 27 | public void putAll(final Map map) { 28 | for (Map.Entry entry : map.entrySet()) { 29 | put(entry.getKey(), entry.getValue()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/io/NameGenerator.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011-2013 Sergey Tarasevich 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.mcxiaoke.next.io; 17 | 18 | public interface NameGenerator { 19 | 20 | String generate(String key); 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/io/SafeFileNameGenerator.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.io; 2 | 3 | import com.mcxiaoke.next.utils.StringUtils; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 14-3-25 8 | * Time: 15:55 9 | */ 10 | public class SafeFileNameGenerator implements NameGenerator { 11 | 12 | @Override 13 | public String generate(String key) { 14 | return StringUtils.toSafeFileName(key); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/utils/ImageUtils.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.utils; 2 | 3 | import android.os.Environment; 4 | 5 | import java.io.File; 6 | import java.text.DateFormat; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Date; 9 | import java.util.Locale; 10 | 11 | /** 12 | * User: mcxiaoke 13 | * Date: 15/6/16 14 | * Time: 10:47 15 | */ 16 | public class ImageUtils { 17 | 18 | public static final String PREFIX_IMAGE = "IMG_"; 19 | public static final String EXTENSION_JPEG = ".jpg"; 20 | public static final String EXTENSION_PNG = ".png"; 21 | 22 | public static final DateFormat IMG_FILE_NAME_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US); 23 | 24 | 25 | /** 26 | * 保存在 /sdcard/Pictures/xxx,用于普通的保存图片 27 | */ 28 | public static File createPictureFile(String dirName) { 29 | String timeStamp = IMG_FILE_NAME_FORMAT.format(new Date()); 30 | String imageFileName = PREFIX_IMAGE + timeStamp + EXTENSION_JPEG; 31 | return new File(getPicturesDir(dirName), imageFileName); 32 | } 33 | 34 | /** 35 | * 保存在 /sdcard/DCIM/xxx,用于拍照图片保存 36 | */ 37 | public static File createMediaFile(String dirName) { 38 | String timeStamp = IMG_FILE_NAME_FORMAT.format(new Date()); 39 | String imageFileName = PREFIX_IMAGE + timeStamp + EXTENSION_JPEG; 40 | return new File(getMediaDir(dirName), imageFileName); 41 | } 42 | 43 | public static File getPicturesDir(String dirName) { 44 | File picturesDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), dirName); 45 | if (!picturesDir.exists()) { 46 | picturesDir.mkdirs(); 47 | } 48 | return picturesDir; 49 | } 50 | 51 | public static File getMediaDir(String dirName) { 52 | File dcim = new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM); 53 | File mediaDir = new File(dcim, dirName); 54 | if (!mediaDir.exists()) { 55 | mediaDir.mkdirs(); 56 | } 57 | return mediaDir; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/com/mcxiaoke/next/utils/ThreadUtils.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.utils; 2 | 3 | import java.util.concurrent.LinkedBlockingQueue; 4 | import java.util.concurrent.RejectedExecutionHandler; 5 | import java.util.concurrent.SynchronousQueue; 6 | import java.util.concurrent.ThreadFactory; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | /** 11 | * User: mcxiaoke 12 | * Date: 14-5-10 13 | * Time: 12:02 14 | */ 15 | public final class ThreadUtils { 16 | private static final String TAG = ThreadUtils.class.getSimpleName(); 17 | 18 | public static ThreadPoolExecutor newCachedThreadPool(final String name) { 19 | return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 20 | 60L, TimeUnit.SECONDS, 21 | new SynchronousQueue(), 22 | new CounterThreadFactory(name), 23 | new LogDiscardPolicy()); 24 | } 25 | 26 | public static ThreadPoolExecutor newFixedThreadPool(final String name, int nThreads) { 27 | return new ThreadPoolExecutor(nThreads, nThreads, 28 | 0L, TimeUnit.MILLISECONDS, 29 | new LinkedBlockingQueue(), 30 | new CounterThreadFactory(name), 31 | new LogDiscardPolicy()); 32 | } 33 | 34 | public static ThreadPoolExecutor newSingleThreadExecutor(final String name) { 35 | return newFixedThreadPool(name, 1); 36 | } 37 | 38 | public static class LogDiscardPolicy implements RejectedExecutionHandler { 39 | 40 | public LogDiscardPolicy() { 41 | } 42 | 43 | public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 44 | LogUtils.v(TAG, "rejectedExecution() " + r + " is discard."); 45 | } 46 | } 47 | 48 | public static class CounterThreadFactory implements ThreadFactory { 49 | private int count; 50 | private String name; 51 | 52 | public CounterThreadFactory(String name) { 53 | this.name = (name == null ? "Android" : name); 54 | 55 | } 56 | 57 | @Override 58 | public Thread newThread(Runnable r) { 59 | Thread thread = new Thread(r); 60 | thread.setName(name + "-thread #" + count++); 61 | return thread; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /deploy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./gradlew clean build uploadArchives 3 | -------------------------------------------------------------------------------- /docs/cache.md: -------------------------------------------------------------------------------- 1 | ## 集成方法 2 | 3 | ```groovy 4 | // core 核心库, 格式:jar和aar 5 | compile 'com.mcxiaoke.next:core:1.5.1' 6 | ``` 7 | 8 | ## 缓存 9 | 10 | 11 | ```java 12 | 13 | // create memory cache, internally using map 14 | final IMemoryCache memoryCache= MemoryCache.mapCache(); 15 | // create memory cache, internally using lru cache 16 | // final IMemoryCache memoryCache= MemoryCache.lruCache(100); 17 | 18 | memoryCache.put("strKey", "value"); 19 | memoryCache.put("intKey", 123); 20 | memoryCache.put("boolKey", false); 21 | memoryCache.put("objKey", new TaskQueue()); 22 | memoryCache.put("boolKey", false); 23 | // expires in 300 seconds 24 | memoryCache.put("canExpireKey", "hello, world", 300*1000L); 25 | final String value = memoryCache.get("strKey"); 26 | 27 | final Context context = mockContext(); 28 | // default disc cache, use /data/data/package-name/cache/.disc/ dir 29 | final DiscCache discCache = new DiscCache(context); 30 | // use custom /data/data/package-name/cache/json-cache/ dir 31 | //final DiscCache discCache=new DiscCache(context,"json-cache"); 32 | // use custom /sdcard/Android/data/package-name/cache/json-cache/ dir 33 | //final DiscCache discCache=new DiscCache(context,"json-cache",DiscCache.MODE_EXTERNAL); 34 | 35 | discCache.setCacheDir("dirName"); 36 | discCache.setCharset("UTF-8"); 37 | discCache.setFileNameGenerator(nameGenerator); 38 | final byte[] bytes = new byte[100]; 39 | discCache.put("bytes", bytes); 40 | discCache.put("stream", new ByteArrayInputStream(bytes)); 41 | discCache.put("text", "some text for cache"); 42 | 43 | final byte[] bytesValue = discCache.getBytes("bytes"); 44 | final File file = discCache.getFile("stream"); 45 | final String stringValue = discCache.get("text"); 46 | discCache.remove("cacheKey"); 47 | discCache.clear(); 48 | discCache.delete(new FileFilter() { 49 | @Override 50 | public boolean accept(final File pathname) { 51 | return false; 52 | } 53 | }); 54 | 55 | 56 | ``` 57 | -------------------------------------------------------------------------------- /docs/recycler.md: -------------------------------------------------------------------------------- 1 | ## 集成方法 2 | 3 | ```groovy 4 | // v1.0.9 新增 5 | // recycler EndlessRecyclerView, 格式:aar 6 | compile 'com.mcxiaoke.next:recycler:1.5.2' 7 | ``` 8 | 9 | ## EndlessRecyclerView 10 | 11 | - **AdvancedRecyclerView** 支持列表顶部和底部加载更多的RecyclerView 12 | - **AdvancedRecyclerArrayAdapter** 适用于RecyclerView的ArrayAdapter,接口同ArrayAdapter 13 | - **HeaderFooterRecyclerAdapter** 支持添加Header和Footer的RecyclerView.Adapter 14 | 15 | ```java 16 | 17 | mRecyclerAdapter = new StringRecyclerAdapter(this, new ArrayList()); 18 | mRecyclerAdapter.addAll(buildData()); 19 | // 设置RecyclerView.Adapter 20 | mEndlessRecyclerView.setAdapter(mRecyclerAdapter); 21 | // 设置自动加载更多的回调 22 | mEndlessRecyclerView.setOnLoadMoreListener(new OnLoadMoreListener() { 23 | @Override 24 | public void onLoadMore(final EndlessRecyclerView view) { 25 | doLoadMore(); 26 | } 27 | }); 28 | // 是否启用滚动到底部自动加载更多功能 29 | mEndlessRecyclerView.enable(true); 30 | //底部Footer显示正在加载中 31 | mEndlessRecyclerView.showProgress(); 32 | // 底部Footer显示为空 33 | mEndlessRecyclerView.showEmpty(); 34 | // 底部Footer显示文本 35 | mEndlessRecyclerView.showText("no more data"); 36 | // 里列表底部多少个就开始自动加载更多 37 | mEndlessRecyclerView.setLoadMoreThreshold(3); 38 | // 加载更多数据完成时调用此方法 39 | mEndlessRecyclerView.onComplete(); 40 | 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/share.md: -------------------------------------------------------------------------------- 1 | ## 集成方法 2 | 3 | ```groovy 4 | // ui UI组件, 格式:aar 5 | compile 'com.mcxiaoke.next:ui:1.5.1' 6 | ``` 7 | 8 | ## AdvancedShareActionProvider 9 | 10 | ```java 11 | 12 | @Override 13 | public boolean onCreateOptionsMenu(Menu menu) { 14 | getMenuInflater().inflate(R.menu.main, menu); 15 | MenuItem share = menu.findItem(R.id.menu_share); 16 | final AdvancedShareActionProvider provider = (AdvancedShareActionProvider) share.getActionProvider(); 17 | final MenuItem.OnMenuItemClickListener listener = new MenuItem.OnMenuItemClickListener() { 18 | @Override 19 | public boolean onMenuItemClick(MenuItem menuItem) { 20 | Log.v(TAG, "Share Target, onMenuItemClicked"); 21 | return true; 22 | } 23 | }; 24 | ShareTarget target = new ShareTarget("ShareTarget", 25 | getResources().getDrawable(android.R.drawable.ic_menu_share), listener); 26 | provider.addShareTarget(target); 27 | final String pkg = getPackageName(); 28 | provider.addCustomPackage("com.twitter.android"); 29 | provider.addCustomPackage(pkg); 30 | provider.addCustomPackage("com.twitter.android"); 31 | provider.removePackage("com.google.android.apps.plus"); 32 | provider.setDefaultLength(3); 33 | Intent intent = new Intent(Intent.ACTION_SEND); 34 | intent.setType("text/plain"); 35 | intent.putExtra(Intent.EXTRA_TEXT, "I am some text for sharing!"); 36 | provider.setShareIntent(intent); 37 | return true; 38 | } 39 | 40 | 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/ui.md: -------------------------------------------------------------------------------- 1 | ## 集成方法 2 | 3 | ```groovy 4 | // ui UI组件, 格式:aar 5 | compile 'com.mcxiaoke.next:ui:1.5.1' 6 | ``` 7 | 8 | ## UI组件 9 | 10 | 一些常用的UI控件,可简化日常开发,包含: 11 | 12 | - **AlertDialogFragment和ProgressDialogFragment** 封装好的DialogFragment,接口简单,同时有4.0版本和使用support-v4的版本 13 | 14 | - **EndlessListView** 封装的ListView,添加了支持加载更多数据的接口和FooterView展示 15 | 16 | - **CheckableFrameLayout** Checkable布局系列,包含几种常用布局的Checkable封装,附带一个很有用的CheckableImageView 17 | 18 | - **NoPressStateFrameLayout** NoPress布局系统,包含几种常用布局的NoPressState封装 19 | 20 | - **SquaredFrameLayout** Squared布局系列,包含几个常用布局的Squared封装,正方形布局 21 | 22 | - **typeface** typeface包里包含一些支持字体设置的常用控件,如Button/TextView/CheckBox等 23 | 24 | - **AspectRatioImageView** 定制的ImageView,缩放时会保持长宽比 25 | 26 | - **CircularImageView** 圆形ImageView,一般用作头像等显示,不建议使用,github有更好的项目 27 | 28 | - **FixedRatioImageView** 强制高宽比的ImageView,可选以水平或垂直方向为基准,另外还有一个强制保持正方形的SquaredImageView 29 | 30 | - **AdvancedShareActionProvider** 高级版的ShareActionProvider,支持自定义分享菜单列表项,自定图标和分享内容等,包含4.0的版本和使用AppCompat的版本,具体可以看源码和示例 31 | 32 | - **ArrayAdapterCompat** 增强版的ArrayAdapter,支持2.3以上版本,增加很多实用方法 33 | -------------------------------------------------------------------------------- /func/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | dependencies { 4 | // compile project(":core") 5 | testImplementation 'com.google.guava:guava:22.0' 6 | testImplementation 'junit:junit:4.12' 7 | testImplementation 'org.mockito:mockito-core:2.18.3' 8 | } 9 | 10 | apply from: '../base.gradle' 11 | 12 | -------------------------------------------------------------------------------- /func/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=Next Commons Library Function Operators 2 | POM_ARTIFACT_ID=functions 3 | POM_PACKAGING=aar 4 | -------------------------------------------------------------------------------- /func/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/Range.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func; 2 | 3 | import java.util.Iterator; 4 | import java.util.NoSuchElementException; 5 | 6 | /** 7 | * User: mcxiaoke 8 | * Date: 15/8/24 9 | * Time: 13:59 10 | */ 11 | public class Range implements Iterable { 12 | 13 | public static Range range(int max) { 14 | return new Range(max); 15 | } 16 | 17 | private int start; 18 | private int end; 19 | private int step; 20 | 21 | public Range(int end) { 22 | this(0, end); 23 | } 24 | 25 | public Range(int start, int end) { 26 | this(start, end, 1); 27 | } 28 | 29 | public Range(int start, int end, int step) { 30 | this.start = start; 31 | this.end = end; 32 | this.step = step; 33 | } 34 | 35 | 36 | @Override 37 | public Iterator iterator() { 38 | final int max = end; 39 | return new Iterator() { 40 | 41 | private int current = start; 42 | 43 | @Override 44 | public boolean hasNext() { 45 | return current < max; 46 | } 47 | 48 | @Override 49 | public Integer next() { 50 | if (hasNext()) { 51 | return current += step; 52 | } else { 53 | throw new NoSuchElementException("Range reached the end"); 54 | } 55 | } 56 | 57 | @Override 58 | public void remove() { 59 | throw new UnsupportedOperationException("Can't remove values from a Range"); 60 | } 61 | }; 62 | } 63 | } -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Action.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func.functions; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/20 6 | * Time: 11:40 7 | */ 8 | interface Action { 9 | } 10 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Action0.java: -------------------------------------------------------------------------------- 1 | 2 | package com.mcxiaoke.next.func.functions; 3 | 4 | public interface Action0 extends Action { 5 | void call(); 6 | } 7 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Action1.java: -------------------------------------------------------------------------------- 1 | 2 | package com.mcxiaoke.next.func.functions; 3 | 4 | public interface Action1 extends Action { 5 | void call(T t); 6 | } 7 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Action2.java: -------------------------------------------------------------------------------- 1 | 2 | package com.mcxiaoke.next.func.functions; 3 | 4 | public interface Action2 extends Action { 5 | void call(T1 t1, T2 t2); 6 | } 7 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Func0.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func.functions; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 15/8/20 8 | * Time: 10:24 9 | */ 10 | public interface Func0 extends Function { 11 | 12 | R call(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Func1.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func.functions; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/20 6 | * Time: 10:24 7 | */ 8 | public interface Func1 extends Function { 9 | 10 | R call(T t); 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Func2.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func.functions; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/20 6 | * Time: 10:43 7 | */ 8 | public interface Func2 extends Function { 9 | R call(T1 t1, T2 t2); 10 | } 11 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Function.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func.functions; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/20 6 | * Time: 10:41 7 | */ 8 | interface Function { 9 | } 10 | -------------------------------------------------------------------------------- /func/src/main/java/com/mcxiaoke/next/func/functions/Predicate.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.func.functions; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/20 6 | * Time: 11:16 7 | */ 8 | public interface Predicate { 9 | 10 | /** 11 | * Evaluates this predicate on the given argument. 12 | * 13 | * @param t the input argument 14 | * @return {@code true} if the input argument matches the predicate, 15 | * otherwise {@code false} 16 | */ 17 | boolean accept(T t); 18 | } 19 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=1.7.0 2 | VERSION_CODE=1700 3 | GROUP=com.mcxiaoke.next 4 | 5 | POM_DESCRIPTION=Android Next Components: Cache, Task, Views, Widgets, Utils 6 | POM_URL=https://github.com/mcxiaoke/Android-Next 7 | POM_SCM_URL=https://github.com/mcxiaoke/Android-Next.git 8 | POM_SCM_CONNECTION=scm:git:git@github.com:mcxiaoke/Android-Next.git 9 | POM_SCM_DEV_CONNECTION=scm:git:git@github.com:mcxiaoke/Android-Next.git 10 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 11 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 12 | POM_LICENCE_DIST=repo 13 | POM_DEVELOPER_ID=mcxiaoke 14 | POM_DEVELOPER_NAME=Xiaoke Zhang 15 | POM_DEVELOPER_EMAIL=mail@mcxiaoke.com 16 | 17 | ANDROID_BUILD_TARGET_SDK_VERSION=29 18 | ANDROID_BUILD_TOOLS_VERSION=29.0.2 19 | ANDROID_BUILD_SDK_VERSION=29 20 | 21 | ANDROID_BUILD_MIN_SDK_VERSION=21 22 | android.useAndroidX=true 23 | android.enableJetifier=true 24 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Jul 21 14:07:20 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /http/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /http/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | dependencies { 4 | implementation project(":core") 5 | implementation project(":task") 6 | implementation 'com.squareup.okhttp3:okhttp:4.8.0' 7 | implementation 'com.google.code.gson:gson:2.8.6' 8 | 9 | testImplementation 'com.google.code.gson:gson:2.8.6' 10 | testImplementation 'junit:junit:4.12' 11 | testImplementation 'org.mockito:mockito-core:2.18.3' 12 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 13 | androidTestImplementation 'org.hamcrest:hamcrest-library:1.3' 14 | } 15 | 16 | apply from: '../base.gradle' 17 | 18 | -------------------------------------------------------------------------------- /http/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=Next Commons Library Http 2 | POM_ARTIFACT_ID=http 3 | POM_PACKAGING=aar 4 | -------------------------------------------------------------------------------- /http/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/mcxiaoke/develop/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the ProGuard 5 | # include property in project.properties. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} -------------------------------------------------------------------------------- /http/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/BodyPart.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import com.mcxiaoke.next.utils.AssertUtils; 4 | import okhttp3.MediaType; 5 | import okhttp3.RequestBody; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | 10 | /** 11 | * User: mcxiaoke 12 | * Date: 15/7/2 13 | * Time: 13:15 14 | */ 15 | public class BodyPart { 16 | 17 | 18 | public final String name; 19 | public final String contentType; 20 | public final File file; 21 | public final byte[] bytes; 22 | public final String fileName; 23 | public final long length; 24 | private RequestBody body; 25 | 26 | private BodyPart(String name, File file, String mimeType, String fileName) { 27 | AssertUtils.notNull(name, "name can not be null."); 28 | AssertUtils.notNull(file, "file can not be null."); 29 | AssertUtils.notNull(mimeType, "mimeType can not be null."); 30 | this.name = name; 31 | this.contentType = mimeType; 32 | this.file = file; 33 | this.bytes = null; 34 | this.length = file.length(); 35 | this.fileName = fileName == null ? HttpConsts.DEFAULT_NAME : fileName; 36 | this.body = RequestBody.create(MediaType.parse(contentType), file); 37 | } 38 | 39 | private BodyPart(String name, byte[] bytes, String mimeType, String fileName) { 40 | AssertUtils.notNull(name, "name can not be null."); 41 | AssertUtils.notNull(bytes, "bytes can not be null."); 42 | AssertUtils.notNull(mimeType, "mimeType can not be null."); 43 | this.name = name; 44 | this.contentType = mimeType; 45 | this.file = null; 46 | this.bytes = bytes; 47 | this.length = bytes.length; 48 | this.fileName = fileName == null ? HttpConsts.DEFAULT_NAME : fileName; 49 | this.body = RequestBody.create(MediaType.parse(contentType), bytes); 50 | } 51 | 52 | public String getName() { 53 | return name; 54 | } 55 | 56 | public String getFileName() { 57 | return fileName; 58 | } 59 | 60 | public String getContentType() { 61 | return contentType; 62 | } 63 | 64 | public RequestBody getBody() throws IOException { 65 | return body; 66 | } 67 | 68 | public static BodyPart create(String name, File file, 69 | String mimeType, String fileName) { 70 | return new BodyPart(name, file, mimeType, fileName); 71 | } 72 | 73 | public static BodyPart create(String name, byte[] bytes, 74 | String mimeType, final String fileName) { 75 | return new BodyPart(name, bytes, mimeType, fileName); 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "BodyPart{" + 81 | "name='" + name + '\'' + 82 | ", contentType='" + contentType + '\'' + 83 | ", file=" + file + 84 | ", fileName='" + fileName + '\'' + 85 | ", length=" + length + 86 | '}'; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/HttpConsts.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import com.mcxiaoke.next.Charsets; 4 | import okhttp3.MediaType; 5 | 6 | import java.nio.charset.Charset; 7 | 8 | /** 9 | * User: mcxiaoke 10 | * Date: 14-2-8 11 | * Time: 11:56 12 | */ 13 | public interface HttpConsts { 14 | 15 | int SLOW_REQUEST_THRESHOLD_MS = 3000; 16 | 17 | String ENCODING_UTF8 = Charsets.ENCODING_UTF_8; 18 | Charset CHARSET_UTF8 = Charsets.UTF_8; 19 | 20 | int BUFFER_SIZE = 10 * 1024; 21 | 22 | int CONNECT_TIMEOUT = 10 * 1000; 23 | int READ_TIMEOUT = 10 * 1000; 24 | int WRITE_TIMEOUT = 10 * 1000; 25 | 26 | String APPLICATION_OCTET_STREAM = "application/octet-stream"; 27 | MediaType MEDIA_TYPE_OCTET_STREAM = MediaType.parse("application/octet-stream; charset=utf-8"); 28 | String CONTENT_TYPE_FORM_ENCODED = "application/x-www-form-urlencoded"; 29 | String EMPTY_STRING = ""; 30 | String DEFAULT_NAME = "nofilename"; 31 | 32 | byte[] NO_BODY = new byte[0]; 33 | 34 | char QUERY_STRING_SEPARATOR = '?'; 35 | String PARAM_SEPARATOR = "&"; 36 | String PAIR_SEPARATOR = "="; 37 | 38 | String REFERER = "Referer"; 39 | String ENCODING_GZIP = "gzip"; 40 | String ACCEPT = "Accept"; 41 | String ACCEPT_CHARSET = "Accept-Charset"; 42 | String ACCEPT_ENCODING = "Accept-Encoding"; 43 | String ACCEPT_LANGUAGE = "Accept-Language"; 44 | String AUTHORIZATION = "Authorization"; 45 | String CACHE_CONTROL = "Cache-Control"; 46 | String CONTENT_ENCODING = "Content-Encoding"; 47 | String CONTENT_LANGUAGE = "Content-Language"; 48 | String CONTENT_LENGTH = "Content-Length"; 49 | String CONTENT_LOCATION = "Content-Location"; 50 | String CONTENT_TYPE = "Content-Type"; 51 | String DATE = "Date"; 52 | String ETAG = "ETag"; 53 | String EXPIRES = "Expires"; 54 | String HOST = "Host"; 55 | String IF_MATCH = "If-Match"; 56 | String IF_MODIFIED_SINCE = "If-Modified-Since"; 57 | String IF_NONE_MATCH = "If-None-Match"; 58 | String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; 59 | String LAST_MODIFIED = "Last-Modified"; 60 | String LOCATION = "Location"; 61 | String PRAGMA = "Pragma"; 62 | String TRANSFER_ENCODING = "Transfer-Encoding"; 63 | String USER_AGENT = "User-Agent"; 64 | String VARY = "Vary"; 65 | String WWW_AUTHENTICATE = "WWW-Authenticate"; 66 | String COOKIE = "Cookie"; 67 | String SET_COOKIE = "Set-Cookie"; 68 | } 69 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Square, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.mcxiaoke.next.http; 17 | 18 | import java.util.Arrays; 19 | import java.util.HashSet; 20 | import java.util.LinkedHashSet; 21 | import java.util.Set; 22 | 23 | public enum HttpMethod { 24 | 25 | GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, TRACE; 26 | 27 | public static final Set METHODS = new HashSet(Arrays.asList( 28 | "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "PATCH")); 29 | 30 | public static boolean isValid(final String method) { 31 | return METHODS.contains(method); 32 | } 33 | 34 | public static boolean supportBody(final String method) { 35 | return supportBody(HttpMethod.valueOf(method)); 36 | } 37 | 38 | public static boolean supportBody(final HttpMethod method) { 39 | return HttpMethod.POST.equals(method) 40 | || HttpMethod.PUT.equals(method) 41 | || HttpMethod.PATCH.equals(method); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/KeyValue.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import android.util.Pair; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 2017/4/12 8 | * Time: 17:54 9 | */ 10 | 11 | public class KeyValue extends Pair { 12 | 13 | public static KeyValue of(final String key, final String value) { 14 | return new KeyValue(key, value); 15 | } 16 | 17 | public KeyValue(final String key, final String value) { 18 | super(key, value); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "{" + String.valueOf(first) + ":" + String.valueOf(second) + "}"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/LoggingInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import android.util.Log; 4 | import com.mcxiaoke.next.utils.IOUtils; 5 | import com.mcxiaoke.next.utils.StringUtils; 6 | import okhttp3.Interceptor; 7 | import okhttp3.Request; 8 | import okhttp3.Response; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * User: mcxiaoke 14 | * Date: 15/7/2 15 | * Time: 16:01 16 | */ 17 | public class LoggingInterceptor implements Interceptor { 18 | private final boolean dumpHeaders; 19 | private final boolean dumpBody; 20 | 21 | public LoggingInterceptor() { 22 | this(false, false); 23 | } 24 | 25 | public LoggingInterceptor(final boolean headers) { 26 | this(headers, false); 27 | } 28 | 29 | public LoggingInterceptor(final boolean headers, final boolean body) { 30 | dumpHeaders = headers; 31 | dumpBody = body; 32 | } 33 | 34 | @Override 35 | public Response intercept(final Chain chain) throws IOException { 36 | long t1 = System.nanoTime(); 37 | final Request request = chain.request(); 38 | Log.v(NextClient.TAG, String.format("[OkHttp Request] %s %s on %s%n", 39 | request.method(), request.url(), chain.connection())); 40 | if (dumpHeaders) { 41 | Log.v(NextClient.TAG, "[Request Headers] " + request.headers()); 42 | } 43 | final Response response = chain.proceed(request); 44 | long t2 = System.nanoTime(); 45 | Log.v(NextClient.TAG, String.format("[OkHttp Response] %s %s (%s:%s) in %.1fms%n " 46 | , request.method(), request.url() 47 | , response.code(), response.message() 48 | , (t2 - t1) / 1e6d)); 49 | if (dumpHeaders) { 50 | Log.v(NextClient.TAG, "[Response Headers] " + response.headers()); 51 | } 52 | if (dumpBody) { 53 | Log.v(NextClient.TAG, "[Response Body] " + responseToText(response)); 54 | } 55 | return response; 56 | } 57 | 58 | private static String responseToText(final Response response) 59 | throws IOException { 60 | return StringUtils.safeSubString(IOUtils.readString(response.body().charStream()), 2048); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/NoEmptyValuesHashMap.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * User: mcxiaoke 8 | * Date: 15/7/6 9 | * Time: 17:34 10 | */ 11 | class NoEmptyValuesHashMap extends HashMap { 12 | 13 | public NoEmptyValuesHashMap() { 14 | super(); 15 | } 16 | 17 | public NoEmptyValuesHashMap(final int capacity) { 18 | super(capacity); 19 | } 20 | 21 | public NoEmptyValuesHashMap(final int capacity, final float loadFactor) { 22 | super(capacity, loadFactor); 23 | } 24 | 25 | public NoEmptyValuesHashMap(final Map map) { 26 | super(); 27 | putAll(map); 28 | } 29 | 30 | @Override 31 | public String put(final String key, final String value) { 32 | if (value == null || value.isEmpty() || key.length() == 0) { 33 | return null; 34 | } 35 | return super.put(key, value); 36 | } 37 | 38 | @Override 39 | public void putAll(final Map map) { 40 | for (Entry entry : map.entrySet()) { 41 | put(entry.getKey(), entry.getValue()); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/ProgressInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import okhttp3.Interceptor; 4 | import okhttp3.Response; 5 | 6 | import java.io.IOException; 7 | 8 | /** 9 | * User: mcxiaoke 10 | * Date: 15/7/2 11 | * Time: 15:17 12 | */ 13 | class ProgressInterceptor implements Interceptor { 14 | private ProgressListener listener; 15 | 16 | public ProgressInterceptor(final ProgressListener listener) { 17 | this.listener = listener; 18 | } 19 | 20 | @Override 21 | public Response intercept(final Chain chain) throws IOException { 22 | Response response = chain.proceed(chain.request()); 23 | return response.newBuilder() 24 | .body(new ProgressResponseBody(response.body(), listener)) 25 | .build(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/ProgressListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: mcxiaoke 3 | * Date: 2016/10/25 4 | * Time: 12:28 5 | */ 6 | 7 | package com.mcxiaoke.next.http; 8 | 9 | public interface ProgressListener { 10 | void onProgress(long bytesWritten, long contentLength, boolean done); 11 | } 12 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/ProgressRequestBody.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: mcxiaoke 3 | * Date: 2016/10/25 4 | * Time: 12:28 5 | */ 6 | 7 | package com.mcxiaoke.next.http; 8 | 9 | import okhttp3.MediaType; 10 | import okhttp3.RequestBody; 11 | import okio.Buffer; 12 | import okio.BufferedSink; 13 | import okio.ForwardingSink; 14 | import okio.Okio; 15 | import okio.Sink; 16 | 17 | import java.io.IOException; 18 | 19 | public class ProgressRequestBody extends RequestBody { 20 | 21 | private final RequestBody body; 22 | private final ProgressListener listener; 23 | private BufferedSink buffer; 24 | 25 | public ProgressRequestBody(RequestBody body, ProgressListener listener) { 26 | this.body = body; 27 | this.listener = listener; 28 | } 29 | 30 | @Override 31 | public MediaType contentType() { 32 | return body.contentType(); 33 | } 34 | 35 | @Override 36 | public long contentLength() throws IOException { 37 | return body.contentLength(); 38 | } 39 | 40 | public RequestBody getBody() { 41 | return body; 42 | } 43 | 44 | public ProgressListener getListener() { 45 | return listener; 46 | } 47 | 48 | @Override 49 | public void writeTo(BufferedSink sink) throws IOException { 50 | if (buffer == null) { 51 | buffer = Okio.buffer(sink(sink)); 52 | } 53 | body.writeTo(buffer); 54 | buffer.flush(); 55 | } 56 | 57 | private Sink sink(Sink sink) { 58 | return new ForwardingSink(sink) { 59 | long bytesWritten = 0L; 60 | long contentLength = 0L; 61 | 62 | @Override 63 | public void write(Buffer source, long byteCount) throws IOException { 64 | super.write(source, byteCount); 65 | if (contentLength == 0) { 66 | contentLength = contentLength(); 67 | } 68 | bytesWritten += byteCount; 69 | if (listener != null) { 70 | listener.onProgress( 71 | bytesWritten, contentLength, bytesWritten == contentLength); 72 | } 73 | } 74 | }; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/ProgressResponseBody.java: -------------------------------------------------------------------------------- 1 | /** 2 | * User: mcxiaoke 3 | * Date: 2016/10/25 4 | * Time: 12:28 5 | */ 6 | 7 | package com.mcxiaoke.next.http; 8 | 9 | import okhttp3.MediaType; 10 | import okhttp3.ResponseBody; 11 | import okio.Buffer; 12 | import okio.BufferedSource; 13 | import okio.ForwardingSource; 14 | import okio.Okio; 15 | import okio.Source; 16 | 17 | import java.io.IOException; 18 | 19 | public class ProgressResponseBody extends ResponseBody { 20 | 21 | private final ResponseBody body; 22 | private final ProgressListener listener; 23 | private BufferedSource buffer; 24 | private long totalRead; 25 | 26 | public ProgressResponseBody(ResponseBody body, ProgressListener listener) { 27 | this.body = body; 28 | this.listener = listener; 29 | totalRead = 0L; 30 | } 31 | 32 | @Override 33 | public MediaType contentType() { 34 | return body.contentType(); 35 | } 36 | 37 | @Override 38 | public long contentLength() { 39 | return body.contentLength(); 40 | } 41 | 42 | public long totalBytesRead() { 43 | return totalRead; 44 | } 45 | 46 | @Override 47 | public BufferedSource source() { 48 | if (buffer == null) { 49 | buffer = Okio.buffer(source(body.source())); 50 | } 51 | return buffer; 52 | } 53 | 54 | private Source source(Source source) { 55 | return new ForwardingSource(source) { 56 | @Override 57 | public long read(Buffer sink, long byteCount) throws IOException { 58 | long bytesRead = super.read(sink, byteCount); 59 | // read() returns the number of bytes read, or -1 if this source is exhausted. 60 | totalRead += bytesRead != -1 ? bytesRead : 0; 61 | if (listener != null) { 62 | listener.onProgress( 63 | totalRead, body.contentLength(), bytesRead == -1); 64 | } 65 | return bytesRead; 66 | } 67 | }; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/callback/BitmapCallback.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.callback; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 16/1/11 8 | * Time: 14:46 9 | */ 10 | public interface BitmapCallback extends HttpCallback { 11 | } 12 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/callback/FileCallback.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.callback; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 15/8/21 8 | * Time: 10:51 9 | */ 10 | public interface FileCallback extends HttpCallback { 11 | } 12 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/callback/GsonCallback.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.callback; 2 | 3 | import com.google.gson.Gson; 4 | 5 | import java.lang.reflect.Type; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 15/8/21 10 | * Time: 11:25 11 | */ 12 | public abstract class GsonCallback implements HttpCallback { 13 | public final Type type; 14 | public final Gson gson; 15 | 16 | public GsonCallback(final Class clazz) { 17 | this(clazz, null); 18 | } 19 | 20 | public GsonCallback(final Class clazz, final Gson gson) { 21 | this.type = clazz; 22 | this.gson = gson; 23 | } 24 | 25 | public GsonCallback(final Type type) { 26 | this(type, null); 27 | } 28 | 29 | public GsonCallback(Type type, final Gson gson) { 30 | this.type = type; 31 | this.gson = gson; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/callback/HttpCallback.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.callback; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 16/1/11 6 | * Time: 12:16 7 | */ 8 | public interface HttpCallback { 9 | 10 | void handleResponse(T response); 11 | 12 | boolean handleException(Throwable throwable); 13 | } 14 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/callback/ResponseCallback.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.callback; 2 | 3 | import com.mcxiaoke.next.http.NextResponse; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 15/8/21 8 | * Time: 10:51 9 | */ 10 | public interface ResponseCallback extends HttpCallback { 11 | } 12 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/callback/StringCallback.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.callback; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/21 6 | * Time: 10:51 7 | */ 8 | public interface StringCallback extends HttpCallback { 9 | } 10 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/exception/HttpException.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.exception; 2 | 3 | import com.mcxiaoke.next.http.NextResponse; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 16/1/12 8 | * Time: 11:20 9 | */ 10 | public class HttpException extends Exception { 11 | 12 | public final NextResponse response; 13 | 14 | public HttpException(final NextResponse response) { 15 | super(response.message()); 16 | this.response = response; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return super.toString() + " {" + response + '}'; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/job/HttpJob.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.job; 2 | 3 | import com.mcxiaoke.next.http.HttpQueue; 4 | import com.mcxiaoke.next.http.NextRequest; 5 | import com.mcxiaoke.next.http.callback.HttpCallback; 6 | import com.mcxiaoke.next.http.processor.HttpProcessor; 7 | import com.mcxiaoke.next.http.transformer.HttpTransformer; 8 | import com.mcxiaoke.next.utils.AssertUtils; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * User: mcxiaoke 15 | * Date: 16/1/11 16 | * Time: 14:51 17 | */ 18 | public class HttpJob { 19 | 20 | public final NextRequest request; 21 | public final HttpTransformer transformer; 22 | public final HttpCallback callback; 23 | public final Object caller; 24 | private List> processors; 25 | 26 | public HttpJob(final NextRequest request, 27 | final HttpTransformer transformer, 28 | final HttpCallback callback, 29 | final Object caller) { 30 | this(request, transformer, callback, null, caller); 31 | } 32 | 33 | public HttpJob(final NextRequest request, 34 | final HttpTransformer transformer, 35 | final HttpCallback callback, 36 | final List> processors, 37 | final Object caller) { 38 | AssertUtils.notNull(request, "request must not be null."); 39 | AssertUtils.notNull(transformer, "transformer must not be null."); 40 | AssertUtils.notNull(caller, "caller must not be null."); 41 | this.request = request; 42 | this.transformer = transformer; 43 | this.callback = callback; 44 | this.caller = caller; 45 | if (processors != null) { 46 | this.processors = processors; 47 | } else { 48 | this.processors = new ArrayList>(2); 49 | } 50 | } 51 | 52 | public HttpJob addProcessor(HttpProcessor processor) { 53 | if (processor != null) { 54 | this.processors.add(processor); 55 | } 56 | return this; 57 | } 58 | 59 | public List> getProcessors() { 60 | return processors; 61 | } 62 | 63 | public String execute(final HttpQueue queue) { 64 | return queue.add(this); 65 | } 66 | 67 | public String execute() { 68 | return HttpQueue.getDefault().add(this); 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return "HttpJob{" + 74 | "request=" + request + 75 | ", transformer=" + transformer + 76 | ", callback=" + callback + 77 | ", processors=" + processors + 78 | ", caller=" + caller + 79 | '}'; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/job/HttpJobBuilder.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.job; 2 | 3 | import com.mcxiaoke.next.http.NextRequest; 4 | import com.mcxiaoke.next.http.callback.HttpCallback; 5 | import com.mcxiaoke.next.http.processor.HttpProcessor; 6 | import com.mcxiaoke.next.http.transformer.HttpTransformer; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class HttpJobBuilder { 12 | private NextRequest mRequest; 13 | private HttpTransformer mTransformer; 14 | private HttpCallback mCallback; 15 | private Object mCaller; 16 | public List> mProcessors; 17 | 18 | public HttpJobBuilder request(final NextRequest request) { 19 | mRequest = request; 20 | return this; 21 | } 22 | 23 | public HttpJobBuilder transformer(final HttpTransformer transformer) { 24 | mTransformer = transformer; 25 | return this; 26 | } 27 | 28 | public HttpJobBuilder callback(final HttpCallback callback) { 29 | mCallback = callback; 30 | return this; 31 | } 32 | 33 | public HttpJobBuilder caller(final Object caller) { 34 | mCaller = caller; 35 | return this; 36 | } 37 | 38 | public HttpJobBuilder processor(HttpProcessor processor) { 39 | if (processor != null) { 40 | if (mProcessors == null) { 41 | mProcessors = new ArrayList>(2); 42 | } 43 | mProcessors.add(processor); 44 | } 45 | return this; 46 | } 47 | 48 | public HttpJob create() { 49 | return new HttpJob(mRequest, mTransformer, mCallback, mProcessors, mCaller); 50 | } 51 | } -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/processor/HttpProcessor.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.processor; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 16/1/11 6 | * Time: 11:05 7 | * F from 8 | * T to 9 | */ 10 | public interface HttpProcessor { 11 | 12 | void process(T response); 13 | } 14 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/support/Tuple.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.support; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 16/1/12 6 | * Time: 13:04 7 | */ 8 | public class Tuple { 9 | public final First first; 10 | public final Second second; 11 | public final Third third; 12 | 13 | public Tuple(final First first, final Second second) { 14 | this.first = first; 15 | this.second = second; 16 | this.third = null; 17 | } 18 | 19 | public Tuple(final First first, final Second second, final Third third) { 20 | this.first = first; 21 | this.second = second; 22 | this.third = third; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/transformer/BitmapTransformer.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.transformer; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import com.mcxiaoke.next.http.NextResponse; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * User: mcxiaoke 11 | * Date: 16/1/11 12 | * Time: 14:29 13 | */ 14 | public class BitmapTransformer implements HttpTransformer { 15 | @Override 16 | public Bitmap transform(final NextResponse response) throws IOException { 17 | return BitmapFactory.decodeStream(response.stream()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/transformer/FileTransformer.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.transformer; 2 | 3 | import com.mcxiaoke.next.http.NextResponse; 4 | 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | /** 9 | * User: mcxiaoke 10 | * Date: 15/8/21 11 | * Time: 14:46 12 | */ 13 | public class FileTransformer implements HttpTransformer { 14 | 15 | private File file; 16 | 17 | public FileTransformer(final File file) { 18 | this.file = file; 19 | } 20 | 21 | 22 | @Override 23 | public File transform(final NextResponse response) throws IOException { 24 | boolean saved = response.writeTo(file); 25 | if (saved) { 26 | return file; 27 | } 28 | throw new IOException("can not save file: " + file); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/transformer/GsonTransformer.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.transformer; 2 | 3 | import com.google.gson.Gson; 4 | import com.mcxiaoke.next.http.NextResponse; 5 | 6 | import java.io.IOException; 7 | import java.lang.reflect.Type; 8 | 9 | /** 10 | * User: mcxiaoke 11 | * Date: 15/8/21 12 | * Time: 12:42 13 | */ 14 | public class GsonTransformer implements HttpTransformer { 15 | private Gson gson; 16 | private Type type; 17 | 18 | public GsonTransformer(final Gson gson, final Class clazz) { 19 | this.gson = gson; 20 | this.type = clazz; 21 | } 22 | 23 | public GsonTransformer(final Gson gson, final Type type) { 24 | this.gson = gson; 25 | this.type = type; 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | @Override 30 | public T transform(final NextResponse response) throws IOException { 31 | // ugly hack for runtime type for gson 32 | if (type instanceof Class) { 33 | return gson.fromJson(response.reader(), (Class) type); 34 | } else { 35 | return gson.fromJson(response.reader(), type); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/transformer/HttpTransformer.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.transformer; 2 | 3 | import com.mcxiaoke.next.http.NextResponse; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 15/8/21 10 | * Time: 12:24 11 | */ 12 | public interface HttpTransformer { 13 | 14 | T transform(NextResponse response) throws IOException; 15 | } 16 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/transformer/ResponseTransformer.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.transformer; 2 | 3 | import com.mcxiaoke.next.http.NextResponse; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 16/1/11 10 | * Time: 14:09 11 | */ 12 | public class ResponseTransformer implements HttpTransformer { 13 | @Override 14 | public NextResponse transform(final NextResponse response) throws IOException { 15 | return response; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /http/src/main/java/com/mcxiaoke/next/http/transformer/StringTransformer.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http.transformer; 2 | 3 | import com.mcxiaoke.next.http.NextResponse; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 15/8/21 10 | * Time: 12:25 11 | */ 12 | public class StringTransformer implements HttpTransformer { 13 | @Override 14 | public String transform(final NextResponse response) throws IOException { 15 | return response.string(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /http/src/test/java/com/mcxiaoke/next/http/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.http; 2 | 3 | import org.junit.Assert; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 15/7/6 8 | * Time: 14:41 9 | */ 10 | public class BaseTest { 11 | 12 | void isTrue(boolean condition) { 13 | Assert.assertTrue(condition); 14 | } 15 | 16 | void isFalse(boolean condition) { 17 | Assert.assertFalse(condition); 18 | } 19 | 20 | void notNull(Object object) { 21 | Assert.assertNotNull(object); 22 | } 23 | 24 | void isNull(Object object) { 25 | Assert.assertNull(object); 26 | } 27 | 28 | void isEquals(boolean expected, boolean actual) { 29 | Assert.assertEquals(expected, actual); 30 | } 31 | 32 | void isEquals(int expected, int actual) { 33 | Assert.assertEquals(expected, actual); 34 | } 35 | 36 | void isEquals(long expected, long actual) { 37 | Assert.assertEquals(expected, actual); 38 | } 39 | 40 | void isEquals(Object expected, Object actual) { 41 | Assert.assertEquals(expected, actual); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /markets.txt: -------------------------------------------------------------------------------- 1 | Google_Play#play store market 2 | Gradle_Test#test 3 | SomeMarket#some market 4 | -------------------------------------------------------------------------------- /recycler/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /recycler/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | dependencies { 4 | implementation "androidx.recyclerview:recyclerview:1.0.0" 5 | 6 | implementation project(":core") 7 | implementation project(":ui") 8 | } 9 | 10 | apply from: '../base.gradle' -------------------------------------------------------------------------------- /recycler/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=Next Commons Library RecyclerView 2 | POM_ARTIFACT_ID=recycler 3 | POM_PACKAGING=aar 4 | -------------------------------------------------------------------------------- /recycler/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/mcxiaoke/develop/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the ProGuard 5 | # include property in project.properties. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} -------------------------------------------------------------------------------- /recycler/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /recycler/src/main/res/layout/layout_advanced_recycler_view_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /samples/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /samples/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | dependencies { 4 | implementation fileTree(dir: 'libs', include: ['*.jar']) 5 | implementation project(":core") 6 | implementation project(":task") 7 | implementation project(":http") 8 | implementation project(":ui") 9 | implementation project(":recycler") 10 | implementation 'com.mcxiaoke.volley:library:1.0.18' 11 | implementation "com.jakewharton:butterknife:10.0.0" 12 | implementation "androidx.recyclerview:recyclerview:$androidx_version" 13 | implementation "androidx.appcompat:appcompat:$androidx_version" 14 | implementation "com.google.android.material:material:$androidx_version" 15 | implementation 'com.google.code.gson:gson:2.8.6' 16 | implementation 'io.reactivex:rxjava:1.0.12' 17 | implementation 'io.reactivex:rxandroid:0.25.0' 18 | 19 | annotationProcessor "com.jakewharton:butterknife-compiler:10.0.0" 20 | } 21 | 22 | android { 23 | 24 | compileOptions { 25 | sourceCompatibility JavaVersion.VERSION_1_8 26 | targetCompatibility JavaVersion.VERSION_1_8 27 | } 28 | 29 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) 30 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION 31 | 32 | flavorDimensions "main" 33 | 34 | defaultConfig { 35 | applicationId GROUP 36 | minSdkVersion 21 37 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 38 | } 39 | 40 | signingConfigs { 41 | release { 42 | storeFile file("../android.keystore") 43 | storePassword "android" 44 | keyAlias 'android' 45 | keyPassword 'android' 46 | } 47 | } 48 | 49 | buildTypes { 50 | release { 51 | signingConfig signingConfigs.release 52 | } 53 | 54 | beta { 55 | debuggable true 56 | signingConfig signingConfigs.release 57 | matchingFallbacks = ['release'] 58 | } 59 | 60 | debug { 61 | applicationIdSuffix null 62 | } 63 | 64 | } 65 | 66 | lintOptions { 67 | quiet true 68 | abortOnError false 69 | } 70 | 71 | } 72 | 73 | -------------------------------------------------------------------------------- /samples/libs/xbus-0.1.0-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/libs/xbus-0.1.0-SNAPSHOT.jar -------------------------------------------------------------------------------- /samples/mcxiaoke.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/mcxiaoke.keystore -------------------------------------------------------------------------------- /samples/packer.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/packer.properties -------------------------------------------------------------------------------- /samples/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/mcxiaoke/develop/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the ProGuard 5 | # include property in project.properties. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.ActionBar; 5 | import android.os.Bundle; 6 | import android.widget.Toast; 7 | import com.mcxiaoke.next.app.NextBaseActivity; 8 | 9 | /** 10 | * User: mcxiaoke 11 | * Date: 13-10-25 12 | * Time: 下午3:50 13 | */ 14 | @SuppressLint("Registered") 15 | public class BaseActivity extends NextBaseActivity { 16 | 17 | @Override 18 | protected void onCreate(final Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | final ActionBar actionBar = getActionBar(); 21 | actionBar.setDisplayHomeAsUpEnabled(true); 22 | } 23 | 24 | public void showToast(CharSequence text) { 25 | Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/SampleUtils.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.google.gson.JsonParser; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 15/3/26 10 | * Time: 11:50 11 | */ 12 | public class SampleUtils { 13 | 14 | public static String prettyPrintJson(final String rawJson) { 15 | final Gson gson = new GsonBuilder().setPrettyPrinting().create(); 16 | return gson.toJson(new JsonParser().parse(rawJson)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/SamplesApp.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | import com.mcxiaoke.next.utils.LogUtils; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 13-9-28 10 | * Time: 下午7:30 11 | */ 12 | public class SamplesApp extends Application { 13 | 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | LogUtils.setLevel(Log.VERBOSE); 18 | LogUtils.setFileLoggingLevel(this, Log.ASSERT); 19 | } 20 | 21 | @Override 22 | public void onTerminate() { 23 | super.onTerminate(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/StringListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | import com.mcxiaoke.next.ui.widget.ArrayAdapterCompat; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * User: mcxiaoke 14 | * Date: 13-10-25 15 | * Time: 下午4:51 16 | */ 17 | public class StringListAdapter extends ArrayAdapterCompat { 18 | private LayoutInflater mInflater; 19 | 20 | public StringListAdapter(Context context, List objects) { 21 | super(context, objects); 22 | mInflater = LayoutInflater.from(context); 23 | } 24 | 25 | @Override 26 | public View getView(int position, View convertView, ViewGroup parent) { 27 | if (convertView == null) { 28 | convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); 29 | } 30 | TextView textView = (TextView) convertView.findViewById(android.R.id.text1); 31 | textView.setText(getItem(position)); 32 | return convertView; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/TouchFrameLayout.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.FrameLayout; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 13-12-5 10 | * Time: 下午12:07 11 | */ 12 | public class TouchFrameLayout extends FrameLayout { 13 | 14 | public TouchFrameLayout(Context context) { 15 | super(context); 16 | } 17 | 18 | public TouchFrameLayout(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | } 21 | 22 | public TouchFrameLayout(Context context, AttributeSet attrs, int defStyle) { 23 | super(context, attrs, defStyle); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/bus/BasicBusSample.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.bus; 2 | 3 | import android.os.Bundle; 4 | import com.mcxiaoke.bus.Bus; 5 | import com.mcxiaoke.bus.BusReceiver; 6 | import com.mcxiaoke.next.samples.BuildConfig; 7 | import com.mcxiaoke.next.samples.R; 8 | import com.mcxiaoke.next.utils.LogUtils; 9 | 10 | /** 11 | * User: mcxiaoke 12 | * Date: 15/7/31 13 | * Time: 13:27 14 | */ 15 | public class BasicBusSample extends BaseBusSample { 16 | public static final String TAG = BasicBusSample.class.getSimpleName(); 17 | private static final boolean DEBUG = BuildConfig.DEBUG; 18 | 19 | @Override 20 | protected void onCreate(final Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | LogUtils.v(TAG, "onCreate()"); 23 | setContentView(R.layout.act_bus_basic); 24 | Bus.getDefault().register(this); 25 | test(); 26 | } 27 | 28 | @Override 29 | protected void onDestroy() { 30 | super.onDestroy(); 31 | LogUtils.v(TAG, "onDestroy()"); 32 | Bus.getDefault().unregister(this); 33 | } 34 | 35 | @BusReceiver 36 | public void testReceiver2(CharSequence event) { 37 | LogUtils.v(TAG, "testReceiver2() event=" + event 38 | + " thread=" + Thread.currentThread().getName()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/bus/BasicBusSample2.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.bus; 2 | 3 | import android.os.Bundle; 4 | import android.os.SystemClock; 5 | import com.mcxiaoke.bus.Bus; 6 | import com.mcxiaoke.bus.BusReceiver; 7 | import com.mcxiaoke.next.samples.BuildConfig; 8 | import com.mcxiaoke.next.samples.R; 9 | import com.mcxiaoke.next.task.SimpleTaskCallback; 10 | import com.mcxiaoke.next.task.TaskCallback; 11 | import com.mcxiaoke.next.task.TaskQueue; 12 | import com.mcxiaoke.next.utils.LogUtils; 13 | 14 | import java.util.Date; 15 | import java.util.Random; 16 | import java.util.concurrent.Callable; 17 | 18 | /** 19 | * User: mcxiaoke 20 | * Date: 15/7/31 21 | * Time: 13:27 22 | */ 23 | public class BasicBusSample2 extends BaseBusSample { 24 | public static final String TAG = BasicBusSample2.class.getSimpleName(); 25 | private static final boolean DEBUG = BuildConfig.DEBUG; 26 | 27 | @Override 28 | protected void onCreate(final Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | LogUtils.v(TAG, "onCreate()"); 31 | setContentView(R.layout.act_bus_basic); 32 | test(); 33 | } 34 | 35 | @Override 36 | protected void onDestroy() { 37 | super.onDestroy(); 38 | LogUtils.v(TAG, "onDestroy()"); 39 | } 40 | 41 | 42 | @BusReceiver 43 | public void testReceiver2(String event) { 44 | LogUtils.v(TAG, "testReceiver2() event=" + event 45 | + " thread=" + Thread.currentThread().getName()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/core/LicenseSamples.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.core; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ListView; 9 | import butterknife.BindView; 10 | import butterknife.ButterKnife; 11 | import com.mcxiaoke.next.samples.BaseActivity; 12 | import com.mcxiaoke.next.samples.R; 13 | import com.mcxiaoke.next.samples.license.LicenseHelper; 14 | import com.mcxiaoke.next.samples.license.LicenseInfo; 15 | import com.mcxiaoke.next.samples.license.LicenseView; 16 | import com.mcxiaoke.next.ui.widget.ArrayAdapterCompat; 17 | import com.mcxiaoke.next.utils.LogUtils; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * User: mcxiaoke 23 | * Date: 14-5-27 24 | * Time: 16:12 25 | */ 26 | public class LicenseSamples extends BaseActivity { 27 | public static final String TAG = LicenseSamples.class.getSimpleName(); 28 | 29 | @BindView(android.R.id.list) 30 | ListView mListView; 31 | 32 | @Override 33 | protected void onCreate(final Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.act_list); 36 | ButterKnife.bind(this); 37 | setLicenses(); 38 | } 39 | 40 | private void setLicenses() { 41 | List licenses = LicenseHelper.parse(this, R.raw.licenses); 42 | if (licenses == null || licenses.isEmpty()) { 43 | return; 44 | } 45 | 46 | LogUtils.e(TAG, "" + licenses); 47 | 48 | LicenseAdapter adapter = new LicenseAdapter(this, licenses); 49 | mListView.setAdapter(adapter); 50 | } 51 | 52 | static class LicenseAdapter extends ArrayAdapterCompat { 53 | private LayoutInflater mInflater; 54 | 55 | public LicenseAdapter(final Context context, final List objects) { 56 | super(context, objects); 57 | mInflater = LayoutInflater.from(context); 58 | } 59 | 60 | @Override 61 | public View getView(final int position, View convertView, 62 | final ViewGroup parent) { 63 | final ViewHolder holder; 64 | if (convertView == null) { 65 | convertView = mInflater.inflate(R.layout.list_item_license, parent, false); 66 | holder = new ViewHolder(convertView); 67 | convertView.setTag(holder); 68 | } else { 69 | holder = (ViewHolder) convertView.getTag(); 70 | } 71 | 72 | final LicenseInfo info = getItem(position); 73 | if (info != null) { 74 | holder.view.setLicenseInfo(info); 75 | } 76 | return convertView; 77 | } 78 | 79 | 80 | static class ViewHolder { 81 | LicenseView view; 82 | 83 | public ViewHolder(View root) { 84 | view = (LicenseView) root.findViewById(R.id.license); 85 | } 86 | } 87 | 88 | 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/http/User.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.http; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * User: mcxiaoke 7 | * Date: 16/1/12 8 | * Time: 15:55 9 | */ 10 | public class User { 11 | 12 | 13 | /** 14 | * loc_id : 108288 15 | * name : 阿北 16 | * created : 2006-01-09 21:12:47 17 | * is_banned : false 18 | * is_suicide : false 19 | * loc_name : 北京 20 | * avatar : http://img3.douban.com/icon/u1000001-30.jpg 21 | * signature : less is more 22 | * uid : ahbei 23 | * alt : http://www.douban.com/people/ahbei/ 24 | * desc : Less is more 25 | * type : user 26 | * id : 1000001 27 | * large_avatar : http://img3.douban.com/icon/up1000001-30.jpg 28 | */ 29 | 30 | @SerializedName("loc_id") 31 | public String locId; 32 | @SerializedName("name") 33 | public String name; 34 | @SerializedName("created") 35 | public String created; 36 | @SerializedName("is_banned") 37 | public boolean isBanned; 38 | @SerializedName("is_suicide") 39 | public boolean isSuicide; 40 | @SerializedName("loc_name") 41 | public String locName; 42 | @SerializedName("avatar") 43 | public String avatar; 44 | @SerializedName("signature") 45 | public String signature; 46 | @SerializedName("uid") 47 | public String uid; 48 | @SerializedName("alt") 49 | public String alt; 50 | @SerializedName("desc") 51 | public String desc; 52 | @SerializedName("type") 53 | public String type; 54 | @SerializedName("id") 55 | public String id; 56 | @SerializedName("large_avatar") 57 | public String largeAvatar; 58 | 59 | @Override 60 | public String toString() { 61 | return "User{" + 62 | "id='" + id + '\'' + 63 | ", name='" + name + '\'' + 64 | ", uid='" + uid + '\'' + 65 | ", type='" + type + '\'' + 66 | ", avatar='" + avatar + '\'' + 67 | ", locId='" + locId + '\'' + 68 | ", created='" + created + '\'' + 69 | '}'; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/layout/GridLayout.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.layout; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 15/8/27 6 | * Time: 16:02 7 | */ 8 | public class GridLayout { 9 | } 10 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/layout/LineLayoutSample.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.layout; 2 | 3 | import android.os.Bundle; 4 | import com.mcxiaoke.next.samples.BaseActivity; 5 | import com.mcxiaoke.next.samples.R; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 15/8/26 10 | * Time: 15:08 11 | */ 12 | public class LineLayoutSample extends BaseActivity { 13 | public static final String TAG = LineLayoutSample.class.getSimpleName(); 14 | 15 | @Override 16 | protected void onCreate(final Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.act_simple_line); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/layout/ViewGroupDemo.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.layout; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | /** 10 | * User: mcxiaoke 11 | * Date: 15/8/27 12 | * Time: 11:54 13 | */ 14 | public class ViewGroupDemo extends ViewGroup { 15 | public static final String TAG = ViewGroupDemo.class.getSimpleName(); 16 | 17 | public ViewGroupDemo(final Context context) { 18 | super(context); 19 | setup(context); 20 | } 21 | 22 | public ViewGroupDemo(final Context context, final AttributeSet attrs) { 23 | super(context, attrs); 24 | setup(context); 25 | } 26 | 27 | public ViewGroupDemo(final Context context, final AttributeSet attrs, final int defStyleAttr) { 28 | super(context, attrs, defStyleAttr); 29 | setup(context); 30 | } 31 | 32 | private void setup(Context context) { 33 | // LayoutInflater.from(context).inflate(R.layout.view_group_demo, this, true); 34 | } 35 | 36 | @Override 37 | protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 38 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 39 | measureChildren(widthMeasureSpec, heightMeasureSpec); 40 | final View child = getChildAt(0); 41 | Log.e(TAG, "onMeasure width=" + getMeasuredWidth() 42 | + " height=" + getMeasuredHeight()); 43 | Log.e(TAG, "onMeasure child width=" + child.getMeasuredWidth() 44 | + " height=" + child.getMeasuredHeight()); 45 | } 46 | 47 | @Override 48 | protected void onLayout(final boolean changed, final int l, final int t, 49 | final int r, final int b) { 50 | Log.e(TAG, "onLayout left=" + l + " top=" + t + " right=" + r + " bottom=" + b); 51 | final View child = getChildAt(0); 52 | child.layout(l + getPaddingLeft(), 53 | t + getPaddingTop(), 54 | l + getPaddingLeft() + child.getMeasuredWidth(), 55 | t + getPaddingTop() + child.getMeasuredHeight()); 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/layout/ViewGroupSample.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.layout; 2 | 3 | import android.os.Bundle; 4 | import com.mcxiaoke.next.samples.BaseActivity; 5 | import com.mcxiaoke.next.samples.R; 6 | 7 | /** 8 | * User: mcxiaoke 9 | * Date: 15/8/27 10 | * Time: 10:21 11 | */ 12 | public class ViewGroupSample extends BaseActivity { 13 | public static final String TAG = ViewGroupSample.class.getSimpleName(); 14 | 15 | @Override 16 | protected void onCreate(final Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.flow_layout_demo); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/src/main/java/com/mcxiaoke/next/samples/license/LicenseInfo.java: -------------------------------------------------------------------------------- 1 | package com.mcxiaoke.next.samples.license; 2 | 3 | /** 4 | * User: mcxiaoke 5 | * Date: 14-5-27 6 | * Time: 16:16 7 | */ 8 | public class LicenseInfo { 9 | 10 | public String name; 11 | public String url; 12 | public String copyright; 13 | public String license; 14 | 15 | @Override 16 | public String toString() { 17 | final StringBuilder sb = new StringBuilder("LicenseInfo{"); 18 | sb.append("name='").append(name).append('\''); 19 | sb.append(", url='").append(url).append('\''); 20 | sb.append(", copyright='").append(copyright).append('\''); 21 | sb.append(", license='").append(license).append('\''); 22 | sb.append('}'); 23 | return sb.toString(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/anim_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/anim_bottom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/anim_top_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/anim_top_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/disappear.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/footer_appear.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/footer_disappear.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/grow_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/grow_from_bottomleft_to_topright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/grow_from_bottomright_to_topleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/grow_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/grow_from_topleft_to_bottomright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/grow_from_topright_to_bottomleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/header_appear.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/header_disappear.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/in_from_left.xml: -------------------------------------------------------------------------------- 1 | 16 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/in_from_right.xml: -------------------------------------------------------------------------------- 1 | 16 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/keep.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/on_screen_hint_enter.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/on_screen_hint_exit.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/photo_fade_out.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | 20 | 27 | 28 | 33 | 34 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/photo_selection_added.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | 20 | 29 | 30 | 38 | 39 | 49 | 50 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/photo_selection_removed.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | 20 | 29 | 30 | 38 | 39 | 49 | 50 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/pump_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/pump_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/rail.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/shrink_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/shrink_from_bottomleft_to_topright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/shrink_from_bottomright_to_topleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/shrink_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/shrink_from_topleft_to_bottomright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/shrink_from_topright_to_bottomleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/slide_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/slide_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/zoom_enter.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 17 | 19 | 20 | 28 | 29 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/zoom_enter_2.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 31 | 32 | 36 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/zoom_exit.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 25 | 28 | 29 | 37 | 38 | 42 | 43 | -------------------------------------------------------------------------------- /samples/src/main/res/anim/zoom_exit_2.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 17 | 19 | 20 | 28 | 29 | 33 | 34 | -------------------------------------------------------------------------------- /samples/src/main/res/drawable-hdpi/ic_actionbar_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-hdpi/ic_actionbar_share.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable-mdpi/ic_actionbar_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-mdpi/ic_actionbar_share.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable-xhdpi/ic_actionbar_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-xhdpi/ic_actionbar_share.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcxiaoke/Android-Next/662c344d5f01bea433ddb63044fc666b2c3457eb/samples/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/src/main/res/layout/act_bus_basic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 12 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/act_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/act_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |