├── .gradle └── 3.2 │ ├── taskArtifacts │ ├── fileHashes.bin │ ├── fileSnapshots.bin │ ├── taskArtifacts.bin │ └── taskArtifacts.lock │ └── tasks │ ├── _app_compileDebugJavaWithJavac │ ├── localClassSetAnalysis │ │ ├── localClassSetAnalysis.bin │ │ └── localClassSetAnalysis.lock │ └── localJarClasspathSnapshot │ │ ├── localJarClasspathSnapshot.bin │ │ └── localJarClasspathSnapshot.lock │ └── _ikvStockChart_compileReleaseJavaWithJavac │ ├── localClassSetAnalysis │ ├── localClassSetAnalysis.bin │ └── localClassSetAnalysis.lock │ └── localJarClasspathSnapshot │ ├── localJarClasspathSnapshot.bin │ └── localJarClasspathSnapshot.lock ├── .idea ├── gradle.xml ├── libraries │ ├── __local_jars___D__github_ikvStockChart_master_app_libs_gson_2_2_1_jar_unspecified_jar.xml │ ├── com_alibaba_fastjson_1_1_46_android_jar.xml │ ├── com_android_support_animated_vector_drawable_25_1_0.xml │ ├── com_android_support_appcompat_v7_25_1_0.xml │ ├── com_android_support_design_25_1_0.xml │ ├── com_android_support_multidex_1_0_1.xml │ ├── com_android_support_multidex_instrumentation_1_0_1.xml │ ├── com_android_support_recyclerview_v7_25_1_0.xml │ ├── com_android_support_support_annotations_25_1_0_jar.xml │ ├── com_android_support_support_compat_25_1_0.xml │ ├── com_android_support_support_core_ui_25_1_0.xml │ ├── com_android_support_support_core_utils_25_1_0.xml │ ├── com_android_support_support_fragment_25_1_0.xml │ ├── com_android_support_support_media_compat_25_1_0.xml │ ├── com_android_support_support_v4_25_1_0.xml │ ├── com_android_support_support_vector_drawable_25_1_0.xml │ ├── com_android_support_transition_25_1_0.xml │ ├── com_chanven_lib_cptr_1_1_0.xml │ ├── com_readystatesoftware_systembartint_systembartint_1_0_3_jar.xml │ ├── com_tbruyelle_rxpermissions_rxpermissions_0_9_3.xml │ ├── com_wordplat_RecyclerViewEasyDivider_1_0_4.xml │ ├── io_reactivex_rxandroid_1_2_1.xml │ ├── io_reactivex_rxjava_1_1_9_jar.xml │ ├── junit_junit_4_12_jar.xml │ ├── org_hamcrest_hamcrest_core_1_3_jar.xml │ └── org_xutils_xutils_3_3_36.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── workspace.xml ├── 20180620144949.jpg ├── 20180620144955.jpg ├── CHANGE_LOG.md ├── PROPERTY.md ├── README.md ├── Screenshots ├── S70413-224859.jpg ├── S70413-224945.jpg ├── S70413-225013.jpg ├── S70413-225055.jpg ├── S70413-225125.jpg ├── S70413-225235.jpg ├── S70417-010650.jpg └── S70628-230542.jpg ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── libs │ ├── gson-2.2.1.jar │ └── picasso-release-2.5.2.4b.aar ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── kline1.txt │ ├── java │ │ └── com │ │ │ └── wordplat │ │ │ └── quickstart │ │ │ ├── activity │ │ │ ├── BaseActivity.java │ │ │ ├── Disable_Left_And_Right_Refresh_Activity.java │ │ │ ├── Enable_Left_And_Right_Refresh_Activity.java │ │ │ ├── MACD_RSI_KDJ_Show_Together_Activity.java │ │ │ ├── MainActivity.java │ │ │ ├── Multi_Color_Dynamic_Change_Configuration_Activity.java │ │ │ ├── Simple_TimeLine_Example_Activity.java │ │ │ ├── TestKLineActivty.java │ │ │ ├── With_Fragment_And_TabLayout_Switcher_Example_Activity.java │ │ │ ├── With_Pull_To_Refresh_Example_Activity.java │ │ │ └── With_RecyclerView_Example_Activity.java │ │ │ ├── adapter │ │ │ ├── BaseViewHolder.java │ │ │ ├── TextAdapter.java │ │ │ └── TextViewHolder.java │ │ │ ├── app │ │ │ ├── App.java │ │ │ ├── AppRuntime.java │ │ │ ├── AppRuntimeInitializer.java │ │ │ └── DeviceRuntime.java │ │ │ ├── bean │ │ │ ├── BtcBean.java │ │ │ ├── KLineBean.java │ │ │ ├── ResultBean.java │ │ │ ├── request │ │ │ │ └── ServerRequestParams.java │ │ │ └── response │ │ │ │ ├── IResultResponse.java │ │ │ │ ├── ServerResponse.java │ │ │ │ └── ServerResponseParser.java │ │ │ ├── fragment │ │ │ ├── BaseFragment.java │ │ │ └── KLineFragment.java │ │ │ ├── mvp │ │ │ ├── BasePresenter.java │ │ │ ├── BaseRequest.java │ │ │ ├── BaseView.java │ │ │ ├── BaseViewListener.java │ │ │ ├── BtcChinaApiRequest.java │ │ │ ├── BtcChinaPresenter.java │ │ │ ├── LoadingView.java │ │ │ ├── LoadingViewListener.java │ │ │ ├── StockApiRequest.java │ │ │ ├── StockPresenter.java │ │ │ └── exception │ │ │ │ ├── NetworkTimeOutException.java │ │ │ │ ├── NoNetworkException.java │ │ │ │ ├── ResultEmptyException.java │ │ │ │ ├── ResultFailedException.java │ │ │ │ └── ResultParseException.java │ │ │ ├── utils │ │ │ ├── AppUtils.java │ │ │ └── SSLHelper.java │ │ │ └── widget │ │ │ ├── TabButton.java │ │ │ └── pulllistview │ │ │ ├── ListRefreshView.java │ │ │ ├── LoadMoreViewFooter.java │ │ │ └── PullListLayout.java │ └── res │ │ ├── anim │ │ ├── dialog_enter.xml │ │ └── dialog_exit.xml │ │ ├── animator │ │ └── loading_rotation.xml │ │ ├── drawable-v21 │ │ └── btn_tab.xml │ │ ├── drawable │ │ ├── bg_ad_image_mark.xml │ │ ├── bg_tab.xml │ │ ├── btn_tab.xml │ │ ├── ic_default.xml │ │ ├── text_tab.xml │ │ ├── vector_drawable_loading.xml │ │ ├── vector_drawable_loading2.xml │ │ ├── vector_drawable_loading2_anim.xml │ │ └── vector_drawable_loading_anim.xml │ │ ├── layout │ │ ├── activity_left_and_right_refresh.xml │ │ ├── activity_macd_rsi_kdj_show_together.xml │ │ ├── activity_main.xml │ │ ├── activity_simple_timeline.xml │ │ ├── activity_with_fragment_and_tablayout_switcher.xml │ │ ├── activity_with_pull_to_refresh.xml │ │ ├── activtiy_test_kline.xml │ │ ├── fragment_kline.xml │ │ ├── item_text.xml │ │ └── view_list_refresh.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── image.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ ├── client.p12 │ │ └── mytruststore.bks │ │ ├── values-v19 │ │ └── styles.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ └── values │ │ ├── attri.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ └── warning.xml │ └── test │ └── java │ └── com │ └── wordplat │ └── quickstart │ └── ExampleUnitTest.java ├── build.gradle ├── build └── generated │ └── mockable-android-25.jar ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── ikvStockChart-master.iml ├── ikvStockChart ├── .gitignore ├── build.gradle ├── ikvStockChart.iml ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── wordplat │ │ │ └── ikvstockchart │ │ │ ├── InteractiveKLineLayout.java │ │ │ ├── InteractiveKLineView.java │ │ │ ├── KLineHandler.java │ │ │ ├── SimpleKLineHandler.java │ │ │ ├── align │ │ │ ├── XMarkerAlign.java │ │ │ ├── YLabelAlign.java │ │ │ └── YMarkerAlign.java │ │ │ ├── compat │ │ │ ├── GestureMoveActionCompat.java │ │ │ ├── PerformenceAnalyser.java │ │ │ └── ViewUtils.java │ │ │ ├── drawing │ │ │ ├── BOLLDrawing.java │ │ │ ├── CandleDrawing.java │ │ │ ├── EmptyDataDrawing.java │ │ │ ├── HighlightDrawing.java │ │ │ ├── IDrawing.java │ │ │ ├── KDJDrawing.java │ │ │ ├── KLineGridAxisDrawing.java │ │ │ ├── KLineVolumeDrawing.java │ │ │ ├── KLineVolumeHighlightDrawing.java │ │ │ ├── MACDDrawing.java │ │ │ ├── MADrawing.java │ │ │ ├── RSIDrawing.java │ │ │ ├── StockIndexYLabelDrawing.java │ │ │ ├── TimeLineDrawing.java │ │ │ └── TimeLineGridAxisDrawing.java │ │ │ ├── entry │ │ │ ├── Entry.java │ │ │ ├── EntryAdapter.java │ │ │ ├── EntrySet.java │ │ │ ├── SizeColor.java │ │ │ ├── StockBOLLIndex.java │ │ │ ├── StockDataTest.java │ │ │ ├── StockIndex.java │ │ │ ├── StockKDJIndex.java │ │ │ ├── StockKLineVolumeIndex.java │ │ │ ├── StockMACDIndex.java │ │ │ ├── StockPlaceIndex.java │ │ │ └── StockRSIIndex.java │ │ │ ├── marker │ │ │ ├── IMarkerView.java │ │ │ ├── XAxisTextMarkerView.java │ │ │ └── YAxisTextMarkerView.java │ │ │ └── render │ │ │ ├── AbstractRender.java │ │ │ ├── KLineRender.java │ │ │ └── TimeLineRender.java │ └── res │ │ ├── drawable │ │ └── text_tab.xml │ │ ├── layout │ │ └── tab_stockindex.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── wordplat │ └── ikvstockchart │ └── ExampleUnitTest.java ├── local.properties └── settings.gradle /.gradle/3.2/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/3.2/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /.gradle/3.2/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /.gradle/3.2/taskArtifacts/taskArtifacts.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/taskArtifacts/taskArtifacts.lock -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin -------------------------------------------------------------------------------- /.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/.gradle/3.2/tasks/_ikvStockChart_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/libraries/__local_jars___D__github_ikvStockChart_master_app_libs_gson_2_2_1_jar_unspecified_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/libraries/com_alibaba_fastjson_1_1_46_android_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_animated_vector_drawable_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_appcompat_v7_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_design_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_multidex_1_0_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_multidex_instrumentation_1_0_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_recyclerview_v7_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_annotations_25_1_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_compat_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_core_ui_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_core_utils_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_fragment_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_media_compat_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_v4_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_support_vector_drawable_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_android_support_transition_25_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/com_chanven_lib_cptr_1_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/com_readystatesoftware_systembartint_systembartint_1_0_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/com_tbruyelle_rxpermissions_rxpermissions_0_9_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/com_wordplat_RecyclerViewEasyDivider_1_0_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/io_reactivex_rxandroid_1_2_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/io_reactivex_rxjava_1_1_9_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/junit_junit_4_12_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/org_hamcrest_hamcrest_core_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/org_xutils_xutils_3_3_36.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /20180620144949.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/20180620144949.jpg -------------------------------------------------------------------------------- /20180620144955.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/20180620144955.jpg -------------------------------------------------------------------------------- /CHANGE_LOG.md: -------------------------------------------------------------------------------- 1 | ### 0.1.5 2 | 3 | > 2017.06.28 4 | 5 | 增加 K线图成交量柱状图 6 | 7 | ![S70413-225235](Screenshots/S70628-230542.jpg) 8 | 9 | ### 0.1.4 10 | 11 | > 2017.05.22 12 | 13 | 增加 蜡烛图实心空心设置 14 | 15 | fixed #10 16 | 17 | ![](http://ww1.sinaimg.cn/large/006tNc79gy1ffu3gin235j30f00qoaar.jpg) 18 | 19 | ### 0.1.3 20 | 21 | > 2017.04.25 22 | 23 | 添加 设置 X 轴、Y 轴 MarkerView 对齐方向 24 | 25 | ![](http://ww1.sinaimg.cn/large/006tNbRwgy1feysmzj8atg30dc0nkdy5.gif) 26 | 27 | ### 0.1.2 28 | 29 | > 2017.04.24 30 | 31 | 添加 设置 Y 轴标签对齐方向属性 32 | 33 | ### 0.1.1 34 | 35 | > 2017.04.17 36 | 37 | 修复 分时图布局文件中设置颜色大小无效的 bug 38 | 39 | ### 0.1.0 40 | 41 | > 2017.04.13 42 | 43 | 支持在 XML 布局文件和代码中设置各个线条颜色、大小配置 44 | 45 | 支持左滑、右滑加载 46 | 47 | 支持长按高亮、短按点击、双指缩放事件 48 | 49 | 支持 fling 滑动 50 | 51 | 支持 MACD、RSI、KDJ、BOLL 四个指标 52 | 53 | 支持自定义的指标显示方式 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 模仿火币K线图、主要修改MACD_RSI_KDJ_Show_Together_Activity 2 | ![image](https://github.com/NativeMonkey/kline/blob/master/20180620144949.jpg) 3 | ![image](https://github.com/NativeMonkey/kline/blob/master/20180620144955.jpg) 4 | -------------------------------------------------------------------------------- /Screenshots/S70413-224859.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70413-224859.jpg -------------------------------------------------------------------------------- /Screenshots/S70413-224945.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70413-224945.jpg -------------------------------------------------------------------------------- /Screenshots/S70413-225013.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70413-225013.jpg -------------------------------------------------------------------------------- /Screenshots/S70413-225055.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70413-225055.jpg -------------------------------------------------------------------------------- /Screenshots/S70413-225125.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70413-225125.jpg -------------------------------------------------------------------------------- /Screenshots/S70413-225235.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70413-225235.jpg -------------------------------------------------------------------------------- /Screenshots/S70417-010650.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70417-010650.jpg -------------------------------------------------------------------------------- /Screenshots/S70628-230542.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/Screenshots/S70628-230542.jpg -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.wordplat.InteractiveKLineView.example" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode APP_VERSION_CODE as int // 这里的值去 gradle.properties 文件中修改,免去每次更新版本都 sync 一遍 11 | versionName APP_VERSION_NAME as String 12 | vectorDrawables.useSupportLibrary = true 13 | 14 | multiDexEnabled true 15 | 16 | ndk { 17 | abiFilters 'armeabi', 'armeabi-v7a', 'x86' 18 | } 19 | 20 | manifestPlaceholders = [ 21 | SERVER_HTTP_URL_VERSION: SERVER_HTTP_URL_VERSION as String, 22 | ] 23 | } 24 | applicationVariants.all { variant -> 25 | if (variant.buildType.name.contains('release')) { 26 | variant.outputs.each { output -> 27 | def outputFile = output.outputFile 28 | if (outputFile != null && outputFile.name.endsWith('.apk')) { 29 | def fileName = "ikvStockChart-" + defaultConfig.versionName + "-release.apk" 30 | output.outputFile = new File(outputFile.parent, fileName) 31 | } 32 | } 33 | } 34 | } 35 | aaptOptions { 36 | additionalParameters "--no-version-vectors" 37 | } 38 | buildTypes { 39 | release { 40 | minifyEnabled false 41 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 42 | } 43 | } 44 | dexOptions { 45 | javaMaxHeapSize "4g" 46 | } 47 | lintOptions { 48 | abortOnError false 49 | } 50 | } 51 | 52 | repositories { 53 | flatDir { 54 | dirs 'libs' 55 | } 56 | } 57 | 58 | dependencies { 59 | compile fileTree(include: ['*.jar'], dir: 'libs') 60 | testCompile 'junit:junit:4.12' 61 | compile 'com.android.support:support-v4:25.1.0' 62 | compile 'com.android.support:appcompat-v7:25.1.0' 63 | compile 'com.android.support:design:25.1.0' 64 | compile 'com.android.support:recyclerview-v7:25.1.0' 65 | 66 | compile 'org.xutils:xutils:3.3.36' 67 | // 设置状态栏颜色 68 | compile 'com.readystatesoftware.systembartint:systembartint:1.0.3' 69 | // multidex 70 | compile 'com.android.support:multidex:1.0.1' 71 | // 下拉刷新, 支持ScrollView、RecyclerView 72 | compile 'com.chanven.lib:cptr:1.1.0' 73 | 74 | compile project(':ikvStockChart') 75 | 76 | compile 'com.wordplat:RecyclerViewEasyDivider:1.0.4' 77 | 78 | compile 'io.reactivex:rxjava:1.1.9' 79 | compile 'io.reactivex:rxandroid:1.2.1' 80 | compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.3@aar' 81 | 82 | compile 'com.alibaba:fastjson:1.1.46.android' 83 | } -------------------------------------------------------------------------------- /app/libs/gson-2.2.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/app/libs/gson-2.2.1.jar -------------------------------------------------------------------------------- /app/libs/picasso-release-2.5.2.4b.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NativeMonkey/kline/cf6e3c1b9dcbdf81be8257d2829144a79828b603/app/libs/picasso-release-2.5.2.4b.aar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/afon/Share/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 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 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 20 | 21 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 38 | 39 | 42 | 43 | 46 | 47 | 50 | 51 | 54 | 55 | 58 | 59 | 62 | 63 | 66 | 67 | 68 | 69 | 70 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.os.Build; 6 | import android.os.Bundle; 7 | import android.support.annotation.NonNull; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.view.View; 10 | import android.view.Window; 11 | import android.view.WindowManager; 12 | 13 | import com.readystatesoftware.systembartint.SystemBarTintManager; 14 | import com.wordplat.quickstart.R; 15 | import com.wordplat.quickstart.app.AppRuntimeInitializer; 16 | 17 | import org.xutils.x; 18 | 19 | public class BaseActivity extends AppCompatActivity { 20 | protected Activity mActivity; // 给子类用的,避免使用 XXXActivity.this 这种写法 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | init(); 26 | } 27 | 28 | private void init() { 29 | x.view().inject(this); 30 | 31 | mActivity = this; 32 | setStatusBarColor(R.color.colorPrimaryDark); 33 | } 34 | 35 | protected void setStatusBarColor(int colorResId) { 36 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && 37 | Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 38 | SystemBarTintManager tintManager = new SystemBarTintManager(this); 39 | tintManager.setStatusBarTintEnabled(true); 40 | tintManager.setNavigationBarTintEnabled(true); 41 | tintManager.setStatusBarTintResource(colorResId); 42 | } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 43 | getWindow().setStatusBarColor(getResources().getColor(colorResId)); 44 | } 45 | } 46 | 47 | protected void setTranslucentStatus(boolean on) { 48 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 我不知道为什么要加这个 49 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 50 | } 51 | 52 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 5.0 全透明实现 53 | 54 | Window window = getWindow(); 55 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 56 | window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 57 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 58 | window.setStatusBarColor(Color.TRANSPARENT); 59 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 4.4 全透明状态栏 60 | 61 | Window window = getWindow(); 62 | WindowManager.LayoutParams winParams = window.getAttributes(); 63 | final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; 64 | if (on) { 65 | winParams.flags |= bits; 66 | } else { 67 | winParams.flags &= ~bits; 68 | } 69 | window.setAttributes(winParams); 70 | } 71 | } 72 | 73 | @Override 74 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 75 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 76 | 77 | AppRuntimeInitializer.INSTANCE.dealOnRequestPermissionsResult(this, requestCode, permissions, grantResults); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/Disable_Left_And_Right_Refresh_Activity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | /** 8 | *

Disable_Left_And_Right_Refresh_Activity

9 | *

Date: 2017/3/31

10 | * 11 | * @author afon 12 | */ 13 | 14 | public class Disable_Left_And_Right_Refresh_Activity extends Enable_Left_And_Right_Refresh_Activity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | 20 | kLineLayout.getKLineView().setEnableLeftRefresh(false); 21 | kLineLayout.getKLineView().setEnableRightRefresh(false); 22 | } 23 | 24 | public static Intent createIntent(Context context) { 25 | Intent intent = new Intent(context, Disable_Left_And_Right_Refresh_Activity.class); 26 | return intent; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.Log; 7 | import android.view.KeyEvent; 8 | import android.widget.Toast; 9 | 10 | import com.wordplat.easydivider.RecyclerViewCornerRadius; 11 | import com.wordplat.easydivider.RecyclerViewLinearDivider; 12 | import com.wordplat.quickstart.R; 13 | import com.wordplat.quickstart.adapter.TextAdapter; 14 | import com.wordplat.quickstart.utils.AppUtils; 15 | 16 | import org.xutils.view.annotation.ContentView; 17 | import org.xutils.view.annotation.ViewInject; 18 | 19 | @ContentView(R.layout.activity_main) 20 | public class MainActivity extends BaseActivity { 21 | private static final String TAG = "MainActivity"; 22 | 23 | @ViewInject(R.id.textList) private RecyclerView textList = null; 24 | 25 | private TextAdapter textAdapter; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | 31 | textAdapter = new TextAdapter(mActivity); 32 | textList.setLayoutManager(new LinearLayoutManager(mActivity)); 33 | textList.setAdapter(textAdapter); 34 | 35 | RecyclerViewCornerRadius cornerRadius = new RecyclerViewCornerRadius(textList); 36 | cornerRadius.setCornerRadius(AppUtils.dpTopx(mActivity, 10)); 37 | 38 | RecyclerViewLinearDivider linearDivider = new RecyclerViewLinearDivider(mActivity, LinearLayoutManager.VERTICAL); 39 | linearDivider.setDividerSize(1); 40 | linearDivider.setDividerColor(0xff888888); 41 | linearDivider.setDividerMargin(AppUtils.dpTopx(mActivity, 10), AppUtils.dpTopx(mActivity, 10)); 42 | linearDivider.setDividerBackgroundColor(0xffffffff); 43 | linearDivider.setShowHeaderDivider(false); 44 | linearDivider.setShowFooterDivider(false); 45 | 46 | // 圆角背景必须第一个添加 47 | textList.addItemDecoration(cornerRadius); 48 | textList.addItemDecoration(linearDivider); 49 | 50 | for (int i = 0 ; i < 16 ; i++) { 51 | String result = Integer.toHexString(255 - i * 12); 52 | Log.i(TAG, "##d onCreate: " + result); 53 | } 54 | } 55 | 56 | /** 57 | * 点击两次退出 58 | */ 59 | private long exitTime = 0; 60 | 61 | @Override 62 | public boolean onKeyDown(int keyCode, KeyEvent event) { 63 | if (keyCode == KeyEvent.KEYCODE_BACK) { 64 | exit(); 65 | return false; 66 | } 67 | return super.onKeyDown(keyCode, event); 68 | } 69 | 70 | private void exit() { 71 | if ((System.currentTimeMillis() - exitTime) > 2000) { 72 | Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show(); 73 | exitTime = System.currentTimeMillis(); 74 | } else { 75 | finish(); 76 | System.exit(0); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/Multi_Color_Dynamic_Change_Configuration_Activity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | /** 8 | *

Multi_Color_Dynamic_Change_Configuration_Activity

9 | *

Date: 2017/3/31

10 | * 11 | * @author afon 12 | */ 13 | 14 | public class Multi_Color_Dynamic_Change_Configuration_Activity extends BaseActivity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | 20 | // TODO: 2017/4/11 21 | } 22 | 23 | public static Intent createIntent(Context context) { 24 | Intent intent = new Intent(context, Multi_Color_Dynamic_Change_Configuration_Activity.class); 25 | return intent; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/Simple_TimeLine_Example_Activity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import com.wordplat.ikvstockchart.InteractiveKLineView; 8 | import com.wordplat.ikvstockchart.entry.Entry; 9 | import com.wordplat.ikvstockchart.entry.EntrySet; 10 | import com.wordplat.ikvstockchart.render.TimeLineRender; 11 | import com.wordplat.quickstart.R; 12 | import com.wordplat.quickstart.bean.BtcBean; 13 | import com.wordplat.quickstart.mvp.BtcChinaPresenter; 14 | import com.wordplat.quickstart.mvp.LoadingViewListener; 15 | 16 | import org.xutils.view.annotation.ContentView; 17 | import org.xutils.view.annotation.ViewInject; 18 | 19 | /** 20 | *

Simple_TimeLine_Example_Activity

21 | *

Date: 2017/4/16

22 | * 23 | * @author afon 24 | */ 25 | 26 | @ContentView(R.layout.activity_simple_timeline) 27 | public class Simple_TimeLine_Example_Activity extends BaseActivity { 28 | 29 | @ViewInject(R.id.timeLineView) private InteractiveKLineView timeLineView = null; 30 | 31 | private static final int REQUEST_BTC_DATA = 1; 32 | 33 | private final EntrySet entrySet = new EntrySet(); 34 | 35 | private final BtcChinaPresenter presenter = new BtcChinaPresenter(); 36 | 37 | @Override 38 | protected void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | 41 | 42 | } 43 | 44 | @Override 45 | protected void onResume() { 46 | super.onResume(); 47 | 48 | presenter.attachView(btcChinaListener); 49 | presenter.getSimple(REQUEST_BTC_DATA); 50 | } 51 | 52 | @Override 53 | protected void onPause() { 54 | super.onPause(); 55 | 56 | presenter.detachView(); 57 | } 58 | 59 | 60 | private LoadingViewListener btcChinaListener = new LoadingViewListener() { 61 | @Override 62 | public void onStartRequest(int requestCode) { 63 | 64 | } 65 | 66 | @Override 67 | public void onFinishRequest(int requestCode) { 68 | 69 | } 70 | 71 | @Override 72 | public void onSuccess(int requestCode) { 73 | for (BtcBean btcBean : presenter.getBtcList()) { 74 | Entry entry = new Entry(btcBean.getPrice(), (int) btcBean.getAmount(), ""); 75 | entrySet.addEntry(entry); 76 | } 77 | entrySet.getEntryList().get(0).setXLabel("09:30"); 78 | entrySet.getEntryList().get(2).setXLabel("11:30/13:00"); 79 | entrySet.getEntryList().get(4).setXLabel("15:00"); 80 | 81 | timeLineView.notifyDataSetChanged(); 82 | } 83 | 84 | @Override 85 | public void onResultEmpty(int requestCode) { 86 | entrySet.setLoadingStatus(false); 87 | timeLineView.notifyDataSetChanged(); 88 | } 89 | 90 | @Override 91 | public void onNoNetworkError(int requestCode) { 92 | super.onNoNetworkError(requestCode); 93 | onResultEmpty(requestCode); 94 | } 95 | 96 | @Override 97 | public void onNetworkTimeOutError(int requestCode) { 98 | super.onNetworkTimeOutError(requestCode); 99 | onResultEmpty(requestCode); 100 | } 101 | }; 102 | 103 | public static Intent createIntent(Context context) { 104 | Intent intent = new Intent(context, Simple_TimeLine_Example_Activity.class); 105 | return intent; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/TestKLineActivty.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import com.wordplat.ikvstockchart.InteractiveKLineView; 8 | import com.wordplat.ikvstockchart.entry.Entry; 9 | import com.wordplat.ikvstockchart.entry.EntrySet; 10 | import com.wordplat.ikvstockchart.entry.StockDataTest; 11 | import com.wordplat.ikvstockchart.render.TimeLineRender; 12 | import com.wordplat.quickstart.R; 13 | import com.wordplat.quickstart.bean.BtcBean; 14 | import com.wordplat.quickstart.mvp.BtcChinaPresenter; 15 | import com.wordplat.quickstart.mvp.LoadingViewListener; 16 | 17 | import org.xutils.view.annotation.ContentView; 18 | import org.xutils.view.annotation.ViewInject; 19 | 20 | import java.io.InputStream; 21 | 22 | /** 23 | * Created by adminstartor on 2018/4/27. 24 | */ 25 | @ContentView(R.layout.activtiy_test_kline) 26 | public class TestKLineActivty extends BaseActivity { 27 | @ViewInject(R.id.timeLineView) private InteractiveKLineView timeLineView = null; 28 | 29 | private static final int REQUEST_BTC_DATA = 1; 30 | 31 | private EntrySet entrySet = new EntrySet(); 32 | 33 | private final BtcChinaPresenter presenter = new BtcChinaPresenter(); 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | 39 | 40 | loadData(); 41 | } 42 | 43 | @Override 44 | protected void onResume() { 45 | super.onResume(); 46 | 47 | presenter.attachView(btcChinaListener); 48 | presenter.getSimple(REQUEST_BTC_DATA); 49 | } 50 | 51 | private void loadData() 52 | { 53 | String kLineData = ""; 54 | try { 55 | InputStream in = getResources().getAssets().open("kline1.txt"); 56 | int length = in.available(); 57 | byte[] buffer = new byte[length]; 58 | in.read(buffer); 59 | kLineData = new String(buffer, "UTF-8"); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | entrySet = StockDataTest.parseKLineData(kLineData); 64 | timeLineView.notifyDataSetChanged(); 65 | } 66 | 67 | @Override 68 | protected void onPause() { 69 | super.onPause(); 70 | 71 | presenter.detachView(); 72 | } 73 | 74 | 75 | private LoadingViewListener btcChinaListener = new LoadingViewListener() { 76 | @Override 77 | public void onStartRequest(int requestCode) { 78 | 79 | } 80 | 81 | @Override 82 | public void onFinishRequest(int requestCode) { 83 | 84 | } 85 | 86 | @Override 87 | public void onSuccess(int requestCode) { 88 | for (BtcBean btcBean : presenter.getBtcList()) { 89 | Entry entry = new Entry(btcBean.getPrice(), (int) btcBean.getAmount(), ""); 90 | entrySet.addEntry(entry); 91 | } 92 | entrySet.getEntryList().get(0).setXLabel("09:30"); 93 | entrySet.getEntryList().get(2).setXLabel("11:30/13:00"); 94 | entrySet.getEntryList().get(4).setXLabel("15:00"); 95 | 96 | timeLineView.notifyDataSetChanged(); 97 | } 98 | 99 | @Override 100 | public void onResultEmpty(int requestCode) { 101 | entrySet.setLoadingStatus(false); 102 | timeLineView.notifyDataSetChanged(); 103 | } 104 | 105 | @Override 106 | public void onNoNetworkError(int requestCode) { 107 | super.onNoNetworkError(requestCode); 108 | onResultEmpty(requestCode); 109 | } 110 | 111 | @Override 112 | public void onNetworkTimeOutError(int requestCode) { 113 | super.onNetworkTimeOutError(requestCode); 114 | onResultEmpty(requestCode); 115 | } 116 | }; 117 | 118 | public static Intent createIntent(Context context) { 119 | Intent intent = new Intent(context, Simple_TimeLine_Example_Activity.class); 120 | return intent; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/With_Pull_To_Refresh_Example_Activity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import com.chanven.lib.cptr.PtrDefaultHandler; 8 | import com.chanven.lib.cptr.PtrFrameLayout; 9 | import com.wordplat.quickstart.R; 10 | import com.wordplat.quickstart.widget.pulllistview.PullListLayout; 11 | 12 | import org.xutils.view.annotation.ContentView; 13 | import org.xutils.view.annotation.ViewInject; 14 | 15 | /** 16 | *

With_Pull_To_Refresh_Example_Activity

17 | *

Date: 2017/3/31

18 | * 19 | * @author afon 20 | */ 21 | 22 | @ContentView(R.layout.activity_with_pull_to_refresh) 23 | public class With_Pull_To_Refresh_Example_Activity extends Enable_Left_And_Right_Refresh_Activity { 24 | 25 | @ViewInject(R.id.pullListLayout) private PullListLayout pullListLayout = null; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | 31 | initUI(); 32 | } 33 | 34 | private void initUI() { 35 | pullListLayout.setPtrHandler(ptrHandler); 36 | } 37 | 38 | private PtrDefaultHandler ptrHandler = new PtrDefaultHandler() { 39 | @Override 40 | public void onRefreshBegin(PtrFrameLayout frame) { 41 | pullListLayout.postDelayed(new Runnable() { 42 | @Override 43 | public void run() { 44 | pullListLayout.refreshComplete(); 45 | } 46 | }, 2000); 47 | } 48 | }; 49 | 50 | public static Intent createIntent(Context context) { 51 | Intent intent = new Intent(context, With_Pull_To_Refresh_Example_Activity.class); 52 | return intent; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/activity/With_RecyclerView_Example_Activity.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | /** 8 | *

With_RecyclerView_Example_Activity

9 | *

Date: 2017/3/31

10 | * 11 | * @author afon 12 | */ 13 | 14 | public class With_RecyclerView_Example_Activity extends BaseActivity { 15 | 16 | private static final String TAG = "Activity"; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | 22 | // TODO: 2017/4/11 23 | } 24 | 25 | public static Intent createIntent(Context context) { 26 | Intent intent = new Intent(context, With_RecyclerView_Example_Activity.class); 27 | return intent; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/adapter/BaseViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | 7 | import org.xutils.x; 8 | 9 | /** 10 | * Created by afon on 2017/2/5. 11 | */ 12 | 13 | public abstract class BaseViewHolder extends RecyclerView.ViewHolder { 14 | 15 | protected Context mContext; 16 | 17 | public BaseViewHolder(View itemView) { 18 | super(itemView); 19 | 20 | mContext = itemView.getContext(); 21 | 22 | x.view().inject(this, itemView); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/adapter/TextAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.adapter; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.wordplat.quickstart.R; 11 | import com.wordplat.quickstart.activity.Disable_Left_And_Right_Refresh_Activity; 12 | import com.wordplat.quickstart.activity.Enable_Left_And_Right_Refresh_Activity; 13 | import com.wordplat.quickstart.activity.MACD_RSI_KDJ_Show_Together_Activity; 14 | import com.wordplat.quickstart.activity.Multi_Color_Dynamic_Change_Configuration_Activity; 15 | import com.wordplat.quickstart.activity.Simple_TimeLine_Example_Activity; 16 | import com.wordplat.quickstart.activity.TestKLineActivty; 17 | import com.wordplat.quickstart.activity.With_Fragment_And_TabLayout_Switcher_Example_Activity; 18 | import com.wordplat.quickstart.activity.With_Pull_To_Refresh_Example_Activity; 19 | import com.wordplat.quickstart.activity.With_RecyclerView_Example_Activity; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * Created by afon on 2017/2/10. 26 | */ 27 | 28 | public class TextAdapter extends RecyclerView.Adapter { 29 | 30 | private static List textList = new ArrayList<>(); 31 | 32 | static { 33 | textList.add("左滑右滑加载(Enable left and right refresh)"); 34 | textList.add("禁用左滑右滑加载"); 35 | textList.add("多个指标共同显示、联动(MACD, RSI, KDJ)"); 36 | textList.add("在Fragment中使用"); 37 | textList.add("带有下拉刷新的需求中使用"); 38 | // textList.add("动态改变颜色、尺寸配置"); // 还没有准备好 39 | // textList.add("在 RecyclerView 列表中使用"); // 还没有准备好 40 | textList.add("简单分时图"); 41 | textList.add("test"); 42 | } 43 | 44 | private Activity mActivity; 45 | 46 | public TextAdapter(Activity activity) { 47 | mActivity = activity; 48 | } 49 | 50 | @Override 51 | public TextViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 52 | View itemView = LayoutInflater.from(mActivity).inflate(R.layout.item_text, parent, false); 53 | 54 | return new TextViewHolder(itemView); 55 | } 56 | 57 | @Override 58 | public void onBindViewHolder(TextViewHolder holder, final int position) { 59 | holder.text.setText(textList.get(position)); 60 | holder.text.setOnClickListener(new View.OnClickListener() { 61 | @Override 62 | public void onClick(View v) { 63 | Intent intent = null; 64 | switch (position) { 65 | case 0: 66 | intent = Enable_Left_And_Right_Refresh_Activity.createIntent(mActivity); 67 | break; 68 | 69 | case 1: 70 | intent = Disable_Left_And_Right_Refresh_Activity.createIntent(mActivity); 71 | break; 72 | 73 | case 2: 74 | intent = MACD_RSI_KDJ_Show_Together_Activity.createIntent(mActivity); 75 | break; 76 | 77 | case 3: 78 | intent = With_Fragment_And_TabLayout_Switcher_Example_Activity.createIntent(mActivity); 79 | break; 80 | 81 | case 4: 82 | intent = With_Pull_To_Refresh_Example_Activity.createIntent(mActivity); 83 | break; 84 | 85 | // case 5: 86 | // intent = Multi_Color_Dynamic_Change_Configuration_Activity.createIntent(mActivity); 87 | // break; 88 | 89 | // case 6: 90 | // intent = With_RecyclerView_Example_Activity.createIntent(mActivity); 91 | // break; 92 | 93 | case 5: 94 | intent = Simple_TimeLine_Example_Activity.createIntent(mActivity); 95 | break; 96 | case 6: 97 | intent = TestKLineActivty.createIntent(mActivity); 98 | break; 99 | 100 | 101 | default: 102 | break; 103 | } 104 | 105 | if (intent != null) { 106 | mActivity.startActivity(intent); 107 | } 108 | } 109 | }); 110 | } 111 | 112 | @Override 113 | public int getItemCount() { 114 | return textList.size(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/adapter/TextViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.adapter; 2 | 3 | import android.view.View; 4 | import android.widget.TextView; 5 | 6 | import com.wordplat.quickstart.R; 7 | 8 | import org.xutils.view.annotation.ViewInject; 9 | 10 | /** 11 | * Created by afon on 2017/2/10. 12 | */ 13 | 14 | public class TextViewHolder extends BaseViewHolder { 15 | 16 | @ViewInject(R.id.text) TextView text; 17 | 18 | public TextViewHolder(View itemView) { 19 | super(itemView); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/app/App.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.app; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.Application; 5 | import android.content.Context; 6 | import android.support.multidex.MultiDex; 7 | import com.wordplat.quickstart.BuildConfig; 8 | 9 | import org.xutils.x; 10 | 11 | /** 12 | * Created by afon on 2017/1/24. 13 | */ 14 | 15 | public class App extends Application { 16 | 17 | @Override 18 | protected void attachBaseContext(Context base) { 19 | super.attachBaseContext(base); 20 | MultiDex.install(this); 21 | } 22 | 23 | @Override 24 | public void onCreate() { 25 | super.onCreate(); 26 | 27 | if (BuildConfig.APPLICATION_ID.equals(getCurProcessName(this))) { 28 | AppRuntimeInitializer.INSTANCE.initRuntime(this); 29 | } 30 | 31 | x.Ext.init(this); 32 | } 33 | 34 | private String getCurProcessName(Context context) { 35 | int pid = android.os.Process.myPid(); 36 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 37 | for (ActivityManager.RunningAppProcessInfo appProcess : activityManager.getRunningAppProcesses()) { 38 | if (appProcess.pid == pid) { 39 | return appProcess.processName; 40 | } 41 | } 42 | return ""; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/app/AppRuntime.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.app; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import java.lang.ref.WeakReference; 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Created by afon on 2017/1/24. 11 | */ 12 | 13 | public class AppRuntime { 14 | 15 | public static Context sContext; // 静态类型的 Context,你懂的 16 | public static LinkedList sActivities = new LinkedList<>(); // 查找当前的 Activity 栈用的 17 | public static WeakReference sActivityStops = new WeakReference<>(null); // 快速查找位于栈顶的 Activity 用的 18 | 19 | public static String serverVersion = "1.0"; // 与服务器通信接口版本号。本值会自动读取到 gradle.properties 文件中定义的,不需要手动修改 * 20 | public static String appVersion = "1.0.0"; // 本APP的版本号。本值会自动读取到 AndroidManifest.xml 文件中定义的,不需要手动修改 * 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/app/DeviceRuntime.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.app; 2 | 3 | /** 4 | * Created by afon on 2017/2/4. 5 | */ 6 | 7 | public class DeviceRuntime { 8 | 9 | public static String IMEI = ""; 10 | 11 | public static String DEVICE_ID = ""; 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/BtcBean.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean; 2 | 3 | /** 4 | *

BtcBean

5 | *

Date: 2017/4/16

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class BtcBean { 11 | 12 | private long date; 13 | 14 | private float price; 15 | 16 | private float amount; 17 | 18 | private long tid; 19 | 20 | private String type; 21 | 22 | public long getDate() { 23 | return date; 24 | } 25 | 26 | public void setDate(long date) { 27 | this.date = date; 28 | } 29 | 30 | public float getPrice() { 31 | return price; 32 | } 33 | 34 | public void setPrice(float price) { 35 | this.price = price; 36 | } 37 | 38 | public float getAmount() { 39 | return amount; 40 | } 41 | 42 | public void setAmount(float amount) { 43 | this.amount = amount; 44 | } 45 | 46 | public long getTid() { 47 | return tid; 48 | } 49 | 50 | public void setTid(long tid) { 51 | this.tid = tid; 52 | } 53 | 54 | public String getType() { 55 | return type; 56 | } 57 | 58 | public void setType(String type) { 59 | this.type = type; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/KLineBean.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean; 2 | 3 | /** 4 | *

KLineBean

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class KLineBean { 11 | 12 | private float open; 13 | 14 | private float high; 15 | 16 | private float low; 17 | 18 | private float close; 19 | 20 | private int volume; 21 | 22 | private String date; 23 | 24 | public float getOpen() { 25 | return open; 26 | } 27 | 28 | public void setOpen(float open) { 29 | this.open = open; 30 | } 31 | 32 | public float getHigh() { 33 | return high; 34 | } 35 | 36 | public void setHigh(float high) { 37 | this.high = high; 38 | } 39 | 40 | public float getLow() { 41 | return low; 42 | } 43 | 44 | public void setLow(float low) { 45 | this.low = low; 46 | } 47 | 48 | public float getClose() { 49 | return close; 50 | } 51 | 52 | public void setClose(float close) { 53 | this.close = close; 54 | } 55 | 56 | public int getVolume() { 57 | return volume; 58 | } 59 | 60 | public void setVolume(int volume) { 61 | this.volume = volume; 62 | } 63 | 64 | public String getDate() { 65 | return date; 66 | } 67 | 68 | public void setDate(String date) { 69 | this.date = date; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/ResultBean.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean; 2 | 3 | /** 4 | *

ResultBean

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class ResultBean { 11 | 12 | private int resultCode; 13 | 14 | private String resultMessage; 15 | 16 | public int getResultCode() { 17 | return resultCode; 18 | } 19 | 20 | public void setResultCode(int resultCode) { 21 | this.resultCode = resultCode; 22 | } 23 | 24 | public String getResultMessage() { 25 | return resultMessage; 26 | } 27 | 28 | public void setResultMessage(String resultMessage) { 29 | this.resultMessage = resultMessage; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/request/ServerRequestParams.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean.request; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | 6 | import com.alibaba.fastjson.JSONObject; 7 | import com.wordplat.quickstart.BuildConfig; 8 | import com.wordplat.quickstart.app.AppRuntime; 9 | import com.wordplat.quickstart.utils.SSLHelper; 10 | 11 | import org.xutils.http.RequestParams; 12 | 13 | import java.io.File; 14 | 15 | import javax.net.ssl.SSLSocketFactory; 16 | 17 | /** 18 | *

ServerRequestParams

19 | *

Date: 2017/4/5

20 | * 21 | * @author afon 22 | */ 23 | 24 | public class ServerRequestParams extends RequestParams { 25 | private static final String TAG = "ServerRequestParams"; 26 | 27 | private JSONObject params = null; 28 | 29 | private JSONObject requestJson= null; 30 | 31 | private String uploadKey = null; 32 | private Object uploadValue = null; 33 | 34 | public ServerRequestParams(String URL) { 35 | super(URL); 36 | params = new JSONObject(); 37 | 38 | requestJson = new JSONObject(); 39 | 40 | setMaxRetryCount(2); 41 | setConnectTimeout(20000); 42 | 43 | SSLSocketFactory sslSocketFactory = SSLHelper.getSSLSocketFactory(AppRuntime.sContext); 44 | if (sslSocketFactory != null) { 45 | setSslSocketFactory(sslSocketFactory); 46 | } 47 | } 48 | 49 | public void addRequestParams(String key, Object value) { 50 | if (TextUtils.isEmpty(key) || value == null) { 51 | return; 52 | } 53 | 54 | requestJson.put(key, value); 55 | } 56 | 57 | public void addCustomParams(String key, JSONObject jsonObject) { 58 | if (TextUtils.isEmpty(key) || jsonObject == null) { 59 | return; 60 | } 61 | 62 | params.put(key, jsonObject); 63 | } 64 | 65 | /** 66 | * 上传文件 67 | * 68 | * @param value 可以是File, InputStream 或 byte[] 69 | */ 70 | public void upload(Object value) { 71 | uploadKey = "uploadFile"; 72 | uploadValue = value; 73 | } 74 | 75 | /** 76 | * 添加完参数或设置参数后调用此方法 77 | */ 78 | public void commit() { 79 | params.put("RequestParams", requestJson); 80 | 81 | if (BuildConfig.DEBUG) { 82 | Log.i(TAG, "##d 请求数据: " + requestJson.toJSONString()); 83 | } 84 | 85 | addBodyParameter("", requestJson.toJSONString()); 86 | 87 | if (!TextUtils.isEmpty(uploadKey) && uploadValue != null) { 88 | if (uploadValue instanceof org.json.JSONArray) { 89 | addParameter(uploadKey, uploadValue); 90 | 91 | } else if(uploadValue instanceof String) { 92 | addBodyParameter(uploadKey, new File((String) uploadValue)); 93 | 94 | } else if(uploadValue instanceof File) { 95 | addBodyParameter(uploadKey, (File)uploadValue); 96 | 97 | } else { 98 | addBodyParameter(uploadKey, uploadValue, "image/jpeg", System.currentTimeMillis()+".jpg"); 99 | } 100 | } 101 | } 102 | 103 | @Override 104 | public String toString() { 105 | return params.toJSONString(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/response/IResultResponse.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean.response; 2 | 3 | /** 4 | *

IResultResponse

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public interface IResultResponse { 11 | 12 | /** 13 | * 服务器返回的逻辑结果响应码 14 | */ 15 | int getResultCode(); 16 | 17 | /** 18 | * 服务器返回的逻辑结果错误信息 19 | */ 20 | String getResultDescr(); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/response/ServerResponse.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean.response; 2 | 3 | import org.xutils.http.annotation.HttpResponse; 4 | 5 | /** 6 | *

ServerResponse

7 | *

Date: 2017/4/11

8 | * 9 | * @author afon 10 | */ 11 | 12 | @HttpResponse(parser = ServerResponseParser.class) 13 | public class ServerResponse implements IResultResponse { 14 | 15 | @Override 16 | public int getResultCode() { 17 | return 0; 18 | } 19 | 20 | @Override 21 | public String getResultDescr() { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/bean/response/ServerResponseParser.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.bean.response; 2 | 3 | import android.util.Log; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | import com.wordplat.quickstart.BuildConfig; 7 | 8 | import org.xutils.http.app.ResponseParser; 9 | import org.xutils.http.request.UriRequest; 10 | 11 | import java.lang.reflect.Type; 12 | 13 | /** 14 | *

ServerResponseParser

15 | *

Date: 2017/4/11

16 | * 17 | * @author afon 18 | */ 19 | 20 | public class ServerResponseParser implements ResponseParser { 21 | private static final String TAG = "ServerResponseParser"; 22 | 23 | @Override 24 | public void checkResponse(UriRequest request) throws Throwable { 25 | 26 | } 27 | 28 | @Override 29 | public Object parse(Type resultType, Class resultClass, String result) throws Throwable { 30 | if (BuildConfig.DEBUG) { 31 | Log.i(TAG, "##d 服务器返回数据:" + result); 32 | } 33 | 34 | return JSON.parseObject(result, resultClass); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/fragment/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.fragment; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import org.xutils.x; 12 | 13 | public class BaseFragment extends Fragment { 14 | protected Activity mActivity; // 给子类用的 15 | 16 | @Override 17 | public void onCreate(@Nullable Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | mActivity = getActivity(); 20 | } 21 | 22 | @Override 23 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 24 | return x.view().inject(this, inflater, container); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | import android.widget.EditText; 6 | 7 | import com.wordplat.quickstart.BuildConfig; 8 | import com.wordplat.quickstart.R; 9 | import com.wordplat.quickstart.app.AppRuntime; 10 | import com.wordplat.quickstart.mvp.exception.NetworkTimeOutException; 11 | import com.wordplat.quickstart.mvp.exception.NoNetworkException; 12 | import com.wordplat.quickstart.mvp.exception.ResultEmptyException; 13 | import com.wordplat.quickstart.mvp.exception.ResultFailedException; 14 | import com.wordplat.quickstart.mvp.exception.ResultParseException; 15 | 16 | import rx.Subscription; 17 | import rx.subscriptions.CompositeSubscription; 18 | 19 | /** 20 | *

BasePresenter

21 | *

Date: 2017/4/11

22 | * 23 | * @author afon 24 | */ 25 | 26 | public abstract class BasePresenter { 27 | 28 | protected T baseView; 29 | 30 | private CompositeSubscription compositeSubscription; 31 | 32 | /** 33 | * 通常在 onResume 时调用此方法 34 | * 35 | * @param baseView 36 | */ 37 | public void attachView(T baseView) { 38 | this.baseView = baseView; 39 | 40 | if(compositeSubscription == null) { 41 | compositeSubscription = new CompositeSubscription(); 42 | initSubscription(); 43 | } 44 | } 45 | 46 | /** 47 | * 通常在 onPause 时调用此方法 48 | */ 49 | public void detachView() { 50 | if(compositeSubscription != null) { 51 | compositeSubscription.unsubscribe(); 52 | compositeSubscription = null; 53 | } 54 | } 55 | 56 | protected void initSubscription() {} 57 | 58 | protected void addSubscription(Subscription subscription) { 59 | if(compositeSubscription == null) { 60 | subscription.unsubscribe(); 61 | } else { 62 | compositeSubscription.add(subscription); 63 | } 64 | } 65 | 66 | /** 67 | * 取消所有订阅 68 | */ 69 | public void cancel() { 70 | if(compositeSubscription != null) { 71 | compositeSubscription.unsubscribe(); 72 | compositeSubscription = new CompositeSubscription(); 73 | } 74 | } 75 | 76 | public boolean isEmpty(EditText editText) { 77 | if(editText == null || editText.getText() == null || TextUtils.isEmpty(editText.getText().toString())) { 78 | return true; 79 | } 80 | return false; 81 | } 82 | 83 | public String getString(int stringResId) { 84 | if (stringResId != 0) { 85 | if (AppRuntime.sContext != null) { 86 | return AppRuntime.sContext.getResources().getString(stringResId); 87 | } 88 | } 89 | 90 | return ""; 91 | } 92 | 93 | protected void handleError(int requestCode, Throwable throwable) { 94 | final String errMessage; 95 | 96 | if(throwable instanceof NoNetworkException) { // 没有网络 97 | errMessage = "onNoNetworkError --> " + requestCode; 98 | baseView.onNoNetworkError(requestCode); 99 | 100 | } else if(throwable instanceof NetworkTimeOutException) { // 网络超时 101 | errMessage = "onNetworkTimeOutError --> " + requestCode; 102 | baseView.onNetworkTimeOutError(requestCode); 103 | 104 | } else if(throwable instanceof ResultParseException) { // 服务器返回的 JSON 数据解析错误 105 | errMessage = "onResultParseError --> " + requestCode; 106 | baseView.onResultParseError(requestCode); 107 | 108 | } else if(throwable instanceof ResultEmptyException) { // 服务器返回结果为空 109 | errMessage = "onResultEmpty --> " + requestCode; 110 | baseView.onResultEmpty(requestCode); 111 | 112 | } else if(throwable instanceof ResultFailedException) { // 服务器返回错误码 113 | errMessage = "onResultFailed --> " + requestCode; 114 | baseView.onResultFailed(requestCode, 115 | ((ResultFailedException) throwable).getErrCode(), 116 | ((ResultFailedException) throwable).getErrMessage()); 117 | 118 | } else { // 其它不知道的错误,除非在设置UI时发生了错误,否则不会走到这里 119 | errMessage = "Warning_Unknow -->" + requestCode; 120 | baseView.onShowWarning(requestCode, R.string.Warning_Unknow); 121 | } 122 | 123 | if(BuildConfig.DEBUG) { 124 | Log.e("BasePresenter", "##d handleError: " + errMessage); 125 | throwable.printStackTrace(); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/BaseView.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | /** 4 | *

5 | * requestCode 请求编码 的意思是: 6 | * 对每一次 presenter 的调用指定一个唯一编码。 7 | * 比如,一个 Activity 中使用了两个以上的 presenter 方法,在 Activity 中 implement 了本接口, 8 | * 那么此时如果返回结果,就需根据请求编码来作对应的UI呈现。 9 | *

10 | *

Date: 2017/4/11

11 | * 12 | * @author afon 13 | */ 14 | 15 | public interface BaseView { 16 | 17 | /** 18 | * 没有网络 19 | * 20 | * @param requestCode 请求编码 21 | */ 22 | void onNoNetworkError(int requestCode); 23 | 24 | /** 25 | * 网络超时 26 | * 27 | * @param requestCode 请求编码 28 | */ 29 | void onNetworkTimeOutError(int requestCode); 30 | 31 | /** 32 | * 操作成功 33 | * 34 | * @param requestCode 请求编码 35 | */ 36 | void onSuccess(int requestCode); 37 | 38 | /** 39 | * 网络请求结果解析错误 40 | * 41 | * @param requestCode 请求编码 42 | */ 43 | void onResultParseError(int requestCode); 44 | 45 | /** 46 | * 服务器返回失败、返回错误 47 | * 48 | * @param requestCode 请求编码 49 | * @param errCode 服务器返回的错误编码 50 | * @param errMessage 服务器返回的错误信息 51 | */ 52 | void onResultFailed(int requestCode, int errCode, String errMessage); 53 | 54 | /** 55 | * 服务器返回结果为空,或者是解析数据出错,也视为空 56 | * 57 | * @param requestCode 请求编码 58 | */ 59 | void onResultEmpty(int requestCode); 60 | 61 | /** 62 | * 显示一个警告信息 63 | * 64 | * @param requestCode 请求编码 65 | * @param errMessageResId 要显示的错误 String 的资源ID 66 | */ 67 | void onShowWarning(int requestCode, int errMessageResId); 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/BaseViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | import android.text.TextUtils; 4 | import android.widget.Toast; 5 | 6 | import com.wordplat.quickstart.R; 7 | import com.wordplat.quickstart.app.AppRuntime; 8 | 9 | /** 10 | *

BaseViewListener

11 | *

Date: 2017/5/15

12 | * 13 | * @author afon 14 | */ 15 | 16 | public class BaseViewListener implements BaseView { 17 | @Override 18 | public void onNoNetworkError(int requestCode) { 19 | Toast.makeText(AppRuntime.sContext, 20 | AppRuntime.sContext.getResources().getString(R.string.Warning_No_Network), 21 | Toast.LENGTH_SHORT).show(); 22 | } 23 | 24 | @Override 25 | public void onNetworkTimeOutError(int requestCode) { 26 | Toast.makeText(AppRuntime.sContext, 27 | AppRuntime.sContext.getResources().getString(R.string.Warning_Network_Timeout), 28 | Toast.LENGTH_SHORT).show(); 29 | } 30 | 31 | @Override 32 | public void onSuccess(int requestCode) { 33 | 34 | } 35 | 36 | @Override 37 | public void onResultParseError(int requestCode) { 38 | 39 | } 40 | 41 | @Override 42 | public void onResultFailed(int requestCode, int errCode, String errMessage) { 43 | if (!TextUtils.isEmpty(errMessage)) { 44 | Toast.makeText(AppRuntime.sContext, errMessage, Toast.LENGTH_SHORT).show(); 45 | } 46 | } 47 | 48 | @Override 49 | public void onResultEmpty(int requestCode) { 50 | 51 | } 52 | 53 | @Override 54 | public void onShowWarning(int requestCode, int errMessageResId) { 55 | Toast.makeText(AppRuntime.sContext, 56 | AppRuntime.sContext.getResources().getString(errMessageResId), 57 | Toast.LENGTH_SHORT).show(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/BtcChinaApiRequest.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | import android.util.Log; 4 | 5 | import com.wordplat.quickstart.BuildConfig; 6 | import com.wordplat.quickstart.bean.BtcBean; 7 | 8 | import org.xutils.http.RequestParams; 9 | 10 | import java.util.List; 11 | import java.util.Locale; 12 | 13 | import rx.Observable; 14 | import rx.Subscriber; 15 | import rx.schedulers.Schedulers; 16 | 17 | /** 18 | *

BtcChinaApiRequest

19 | *

Date: 2017/4/16

20 | * 21 | * @author afon 22 | */ 23 | 24 | public class BtcChinaApiRequest extends BaseRequest { 25 | private static final String TAG = "BtcChinaApiRequest"; 26 | 27 | private static final String URL = "https://data.btcchina.com/data/historydata?since=%d&limit=%d"; 28 | 29 | public static Observable> getHistoryData(final int id, final int limit) { 30 | return Observable.create(new Observable.OnSubscribe>() { 31 | @Override 32 | public void call(Subscriber> subscriber) { 33 | String url = String.format(Locale.ENGLISH, 34 | URL, 35 | id, 36 | limit); 37 | 38 | if (BuildConfig.DEBUG) { 39 | Log.d(TAG, "##d 请求参数: " + url); 40 | } 41 | 42 | requestArray(subscriber, new RequestParams(url), BtcBean.class); 43 | } 44 | }).subscribeOn(Schedulers.io()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/BtcChinaPresenter.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | import com.wordplat.quickstart.bean.BtcBean; 4 | 5 | import java.util.List; 6 | 7 | import rx.Subscription; 8 | import rx.android.schedulers.AndroidSchedulers; 9 | import rx.functions.Action1; 10 | 11 | /** 12 | *

BtcChinaPresenter

13 | *

Date: 2017/4/16

14 | * 15 | * @author afon 16 | */ 17 | 18 | public class BtcChinaPresenter extends BasePresenter { 19 | 20 | private List btcList; 21 | 22 | public void getSimple(final int requestCode) { 23 | baseView.onStartRequest(requestCode); 24 | 25 | Subscription subscription = BtcChinaApiRequest.getHistoryData(5000, 600) 26 | .observeOn(AndroidSchedulers.mainThread()) 27 | .subscribe(new Action1>() { 28 | @Override 29 | public void call(List response) { 30 | baseView.onFinishRequest(requestCode); 31 | if (response != null && response.size() > 0) { 32 | btcList = response; 33 | 34 | baseView.onSuccess(requestCode); 35 | } else { 36 | baseView.onResultEmpty(requestCode); 37 | } 38 | } 39 | }, new Action1() { 40 | @Override 41 | public void call(Throwable throwable) { 42 | baseView.onFinishRequest(requestCode); 43 | handleError(requestCode, throwable); 44 | } 45 | }); 46 | 47 | addSubscription(subscription); 48 | } 49 | 50 | public List getBtcList() { 51 | return btcList; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/LoadingView.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | /** 4 | *

LoadingView

5 | *

Date: 2017/5/15

6 | * 7 | * @author afon 8 | */ 9 | 10 | public interface LoadingView extends BaseView { 11 | 12 | void onStartRequest(int requestCode); 13 | 14 | void onFinishRequest(int requestCode); 15 | 16 | void onSuccess(int requestCode); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/LoadingViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | /** 4 | *

LoadingViewListener

5 | *

Date: 2017/5/22

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class LoadingViewListener extends BaseViewListener implements LoadingView { 11 | 12 | @Override 13 | public void onStartRequest(int requestCode) { 14 | 15 | } 16 | 17 | @Override 18 | public void onFinishRequest(int requestCode) { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/StockApiRequest.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp; 2 | 3 | import com.wordplat.quickstart.bean.KLineBean; 4 | import com.wordplat.quickstart.bean.request.ServerRequestParams; 5 | 6 | import java.text.SimpleDateFormat; 7 | import java.util.Date; 8 | import java.util.List; 9 | import java.util.Locale; 10 | 11 | import rx.Observable; 12 | import rx.Subscriber; 13 | import rx.schedulers.Schedulers; 14 | 15 | /** 16 | *

自己搭建的股票 API 服务器接口

17 | *

Date: 2017/4/11

18 | * 19 | * @author afon 20 | */ 21 | 22 | public class StockApiRequest extends BaseRequest { 23 | private static final String TAG = "StockApiRequest"; 24 | 25 | private static final String URL = "https://api.wordplat.com/ts/v1/get_k_data/%s"; 26 | 27 | private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd"); 28 | 29 | 30 | public static Observable> getKLine(final String stockCode, 31 | final Date startDate, 32 | final Date endData, 33 | final String type) { 34 | return Observable.create(new Observable.OnSubscribe>() { 35 | @Override 36 | public void call(Subscriber> subscriber) { 37 | String url = String.format(Locale.ENGLISH, URL, stockCode); 38 | 39 | ServerRequestParams requestParams = new ServerRequestParams(url); 40 | requestParams.addRequestParams("start", sDateFormat.format(startDate)); 41 | requestParams.addRequestParams("end", sDateFormat.format(endData)); 42 | requestParams.addRequestParams("ktype", type); 43 | requestParams.commit(); 44 | 45 | requestArray(subscriber, requestParams, KLineBean.class); 46 | } 47 | }).subscribeOn(Schedulers.io()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/exception/NetworkTimeOutException.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp.exception; 2 | 3 | /** 4 | *

网络超时错误

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class NetworkTimeOutException extends Exception { 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/exception/NoNetworkException.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp.exception; 2 | 3 | /** 4 | *

没有网络

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class NoNetworkException extends Exception { 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/exception/ResultEmptyException.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp.exception; 2 | 3 | /** 4 | *

服务器返回结果为空

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class ResultEmptyException extends Exception { 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/exception/ResultFailedException.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp.exception; 2 | 3 | /** 4 | *

服务器返回错误码

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class ResultFailedException extends Exception { 11 | 12 | private int errCode; 13 | 14 | private String errMessage; 15 | 16 | public ResultFailedException(int errCode, String errMessage) { 17 | this.errCode = errCode; 18 | this.errMessage = errMessage; 19 | } 20 | 21 | public int getErrCode() { 22 | return errCode; 23 | } 24 | 25 | public String getErrMessage() { 26 | return errMessage; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/mvp/exception/ResultParseException.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.mvp.exception; 2 | 3 | /** 4 | *

解析服务器返回的数据失败

5 | *

Date: 2017/4/11

6 | * 7 | * @author afon 8 | */ 9 | 10 | public class ResultParseException extends Exception { 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/utils/AppUtils.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.utils; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | 7 | /** 8 | * APP工具 9 | * 10 | * @author liutao 11 | */ 12 | 13 | public class AppUtils { 14 | 15 | /** 16 | * 网络是否连接 17 | * 18 | * @param context 19 | */ 20 | public static boolean isConnected(Context context) { 21 | ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 22 | NetworkInfo netInfo = connManager.getActiveNetworkInfo(); 23 | 24 | return netInfo == null || !netInfo.isConnected() ? false : true; 25 | } 26 | 27 | /** 28 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 29 | */ 30 | public static int dpTopx(Context context, float dpValue) { 31 | final float scale = context.getResources().getDisplayMetrics().density; 32 | return (int) (dpValue * scale + 0.5f); 33 | } 34 | 35 | /** 36 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 37 | */ 38 | public static int pxTodp(Context context, float pxValue) { 39 | final float scale = context.getResources().getDisplayMetrics().density; 40 | return (int) (pxValue / scale + 0.5f); 41 | } 42 | 43 | /** 44 | * 获取App版本号 45 | */ 46 | public static String getAppVersionName(Context context) { 47 | String packageName = null; 48 | String versionName = null; 49 | int versionCode = 0; 50 | try { 51 | packageName = context.getPackageName(); 52 | 53 | versionName = context.getPackageManager().getPackageInfo(packageName, 0).versionName; 54 | 55 | versionCode = context.getPackageManager().getPackageInfo(packageName, 0).versionCode; 56 | 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } 60 | return versionName; 61 | } 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/utils/SSLHelper.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.utils; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.wordplat.quickstart.R; 7 | 8 | import java.io.InputStream; 9 | import java.security.KeyStore; 10 | 11 | import javax.net.ssl.KeyManagerFactory; 12 | import javax.net.ssl.SSLContext; 13 | import javax.net.ssl.SSLSocketFactory; 14 | import javax.net.ssl.TrustManagerFactory; 15 | 16 | /** 17 | *

SSLHelper

18 | *

Date: 2017/5/29

19 | * 20 | * @author afon 21 | */ 22 | 23 | public class SSLHelper { 24 | private static final String KEY_STORE_TYPE_BKS = "bks"; // 证书类型 固定值 25 | private static final String KEY_STORE_TYPE_P12 = "PKCS12"; // 证书类型 固定值 26 | 27 | private static final int KEY_STORE_CLIENT_PATH = R.raw.client; // 客户端要给服务器端认证的证书 28 | private static final String KEY_STORE_PASSWORD = "123456"; // 证书密码 29 | 30 | private static final int KEY_STORE_TRUST_PATH = R.raw.mytruststore; // 客户端验证服务器端的证书库 31 | private static final String KEY_STORE_TRUST_PASSWORD = "123456"; // 证书库密码 32 | 33 | /** 34 | * 获取SSLContext 35 | * 36 | * @param context 上下文 37 | * @return SSLContext 38 | */ 39 | public static SSLSocketFactory getSSLSocketFactory(Context context) { 40 | try { 41 | // 服务器端需要验证的客户端证书 42 | KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12); 43 | // 客户端信任的服务器端证书 44 | KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS); 45 | 46 | InputStream ksIn = context.getResources().openRawResource(KEY_STORE_CLIENT_PATH); 47 | InputStream tsIn = context.getResources().openRawResource(KEY_STORE_TRUST_PATH); 48 | try { 49 | keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray()); 50 | trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray()); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } finally { 54 | try { 55 | ksIn.close(); 56 | } catch (Exception ignore) { 57 | } 58 | try { 59 | tsIn.close(); 60 | } catch (Exception ignore) { 61 | } 62 | } 63 | 64 | SSLContext sslContext = SSLContext.getInstance("TLS"); 65 | TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 66 | trustManagerFactory.init(trustStore); 67 | 68 | KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509"); 69 | keyManagerFactory.init(keyStore, KEY_STORE_PASSWORD.toCharArray()); 70 | 71 | sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); 72 | return sslContext.getSocketFactory(); 73 | 74 | } catch (Exception e) { 75 | Log.e("SSLHelper", e.getMessage(), e); 76 | } 77 | return null; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/widget/TabButton.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.widget; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Paint; 8 | import android.graphics.drawable.Drawable; 9 | import android.util.AttributeSet; 10 | import android.widget.RadioButton; 11 | 12 | import com.wordplat.quickstart.R; 13 | import com.wordplat.quickstart.utils.AppUtils; 14 | 15 | /** 16 | * 带提示红点的Tab按键 17 | * 18 | * @author liutao 19 | */ 20 | public class TabButton extends RadioButton { 21 | private int radius = 0; 22 | private int offset = 0; 23 | private Paint paint = null; 24 | private boolean isShow = false; 25 | 26 | private int topDrawableWidth = 0; 27 | 28 | public TabButton(Context context) { 29 | this(context, null); 30 | } 31 | 32 | public TabButton(Context context, AttributeSet attrs) { 33 | this(context, attrs, android.R.attr.radioButtonStyle); 34 | } 35 | 36 | public TabButton(Context context, AttributeSet attrs, int defStyle) { 37 | super(context, attrs, defStyle); 38 | setButtonDrawable(null); 39 | 40 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabButton); 41 | radius = (int) a.getDimension(R.styleable.TabButton_dotSize, AppUtils.dpTopx(context, 4)); 42 | a.recycle(); 43 | 44 | paint = new Paint(); 45 | paint.setColor(Color.RED); 46 | paint.setAntiAlias(true); 47 | offset = radius * 2; 48 | 49 | Drawable[] drawables = null; 50 | try { 51 | drawables = getCompoundDrawables(); 52 | 53 | if(drawables == null || drawables[1] == null){ 54 | return; 55 | } 56 | 57 | topDrawableWidth = drawables[1].getIntrinsicWidth(); 58 | }catch (Exception e) { 59 | e.printStackTrace(); 60 | }finally { 61 | drawables = null; 62 | } 63 | } 64 | 65 | @Override 66 | protected void onDraw(Canvas canvas) { 67 | super.onDraw(canvas); 68 | if(isShow) { 69 | canvas.drawCircle((getWidth()/2+topDrawableWidth/2), offset, radius, paint); 70 | } 71 | } 72 | 73 | public void setShowTag(boolean isShow) { 74 | this.isShow = isShow; 75 | invalidate(); 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/widget/pulllistview/LoadMoreViewFooter.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.widget.pulllistview; 2 | 3 | import android.view.View; 4 | import android.widget.ProgressBar; 5 | import android.widget.TextView; 6 | 7 | import com.chanven.lib.cptr.loadmore.ILoadMoreViewFactory; 8 | 9 | /** 10 | * Created by afon on 2016/12/9. 11 | */ 12 | 13 | public class LoadMoreViewFooter implements ILoadMoreViewFactory { 14 | 15 | private LoadMoreHelper loadMoreHelper; 16 | 17 | public LoadMoreHelper getLoadMoreView() { 18 | return loadMoreHelper; 19 | } 20 | 21 | @Override 22 | public ILoadMoreView madeLoadMoreView() { 23 | loadMoreHelper = new LoadMoreHelper(); 24 | return loadMoreHelper; 25 | } 26 | 27 | public static class LoadMoreHelper implements ILoadMoreView { 28 | 29 | protected View footerView; 30 | protected TextView footerTv; 31 | protected ProgressBar footerBar; 32 | 33 | protected View.OnClickListener onClickRefreshListener; 34 | 35 | @Override 36 | public void init(FootViewAdder footViewHolder, View.OnClickListener onClickRefreshListener) { 37 | footerView = footViewHolder.addFootView(com.chanven.lib.cptr.R.layout.loadmore_default_footer); 38 | footerTv = (TextView) footerView.findViewById(com.chanven.lib.cptr.R.id.loadmore_default_footer_tv); 39 | footerBar = (ProgressBar) footerView.findViewById(com.chanven.lib.cptr.R.id.loadmore_default_footer_progressbar); 40 | footerView.setClickable(true); 41 | footerView.setFocusable(true); 42 | footerView.setFocusableInTouchMode(true); 43 | this.onClickRefreshListener = onClickRefreshListener; 44 | showNormal(); 45 | } 46 | 47 | @Override 48 | public void showNormal() { 49 | footerTv.setText("点击加载更多"); 50 | footerBar.setVisibility(View.GONE); 51 | footerView.setOnClickListener(onClickRefreshListener); 52 | } 53 | 54 | @Override 55 | public void showLoading() { 56 | footerTv.setText("正在加载中..."); 57 | footerBar.setVisibility(View.VISIBLE); 58 | footerView.setOnClickListener(null); 59 | } 60 | 61 | @Override 62 | public void showFail(Exception exception) { 63 | footerTv.setText("加载失败,点击重新加载"); 64 | footerBar.setVisibility(View.GONE); 65 | footerView.setOnClickListener(onClickRefreshListener); 66 | } 67 | 68 | @Override 69 | public void showNomore() { 70 | footerTv.setText("已经加载完毕"); 71 | footerBar.setVisibility(View.GONE); 72 | footerView.setOnClickListener(null); 73 | } 74 | 75 | @Override 76 | public void setFooterVisibility(boolean isVisible) { 77 | footerView.setVisibility(isVisible ? View.VISIBLE : View.GONE); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/wordplat/quickstart/widget/pulllistview/PullListLayout.java: -------------------------------------------------------------------------------- 1 | package com.wordplat.quickstart.widget.pulllistview; 2 | 3 | import android.content.Context; 4 | import android.support.v4.view.MotionEventCompat; 5 | import android.util.AttributeSet; 6 | import android.view.MotionEvent; 7 | 8 | import com.chanven.lib.cptr.PtrFrameLayout; 9 | import com.chanven.lib.cptr.loadmore.DefaultLoadMoreViewFooter; 10 | import com.chanven.lib.cptr.loadmore.ILoadMoreViewFactory; 11 | import com.wordplat.ikvstockchart.compat.GestureMoveActionCompat; 12 | 13 | /** 14 | * Created by liutao on 16/9/6. 15 | */ 16 | 17 | public class PullListLayout extends PtrFrameLayout { 18 | private ListRefreshView listRefreshView = null; 19 | 20 | private boolean isRefresh = true; 21 | 22 | private GestureMoveActionCompat gestureCompat; 23 | 24 | public PullListLayout(Context context) { 25 | this(context, null); 26 | } 27 | 28 | public PullListLayout(Context context, AttributeSet attrs) { 29 | this(context, attrs, 0); 30 | } 31 | 32 | public PullListLayout(Context context, AttributeSet attrs, int defStyle) { 33 | super(context, attrs, defStyle); 34 | initUI(); 35 | } 36 | 37 | private void initUI() { 38 | gestureCompat = new GestureMoveActionCompat(null); 39 | 40 | setRatioOfHeaderHeightToRefresh(1f); 41 | setResistance(3f); 42 | setDurationToCloseHeader(500); 43 | 44 | listRefreshView = new ListRefreshView(getContext()); 45 | setHeaderView(listRefreshView); 46 | addPtrUIHandler(listRefreshView); 47 | 48 | ILoadMoreViewFactory loadMoreViewFactory = new DefaultLoadMoreViewFooter(); 49 | setFooterView(loadMoreViewFactory); 50 | } 51 | 52 | public void setStatusHintColor(int colorResId) { 53 | listRefreshView.setStatusHintColor(colorResId); 54 | } 55 | 56 | public void setUpdateTimeColor(int colorResId) { 57 | listRefreshView.setUpdateTimeColor(colorResId); 58 | } 59 | 60 | public void setPullRefresh(boolean isRefresh) { 61 | this.isRefresh = isRefresh; 62 | } 63 | 64 | @Override 65 | public boolean dispatchTouchEvent(MotionEvent e) { 66 | // 解决 PullListLayout 垂直滑动(下拉刷新)与横向滑动冲突 67 | if (gestureCompat.onTouchEvent(e, e.getRawX(), e.getRawY())) { 68 | return dispatchTouchEventSupper(e); 69 | } 70 | // 解决双指缩放的冲突 71 | if (MotionEventCompat.getActionMasked(e) == MotionEvent.ACTION_POINTER_DOWN) { 72 | isRefresh = false; 73 | } 74 | 75 | if (isRefresh) { 76 | return super.dispatchTouchEvent(e); 77 | } 78 | 79 | switch (e.getAction()) { 80 | case MotionEvent.ACTION_UP: 81 | case MotionEvent.ACTION_CANCEL: 82 | isRefresh = true; 83 | return super.dispatchTouchEvent(e); 84 | } 85 | 86 | return dispatchTouchEventSupper(e); 87 | } 88 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/dialog_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/dialog_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/animator/loading_rotation.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/btn_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_ad_image_mark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_default.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/text_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/vector_drawable_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/vector_drawable_loading2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 40 | 42 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/vector_drawable_loading2_anim.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/vector_drawable_loading_anim.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_left_and_right_refresh.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 25 | 26 | 36 | 37 | 46 | 47 | 57 | 58 | 66 | 67 | 72 | 73 | 78 | 79 | 84 | 85 | 90 | 91 | 92 | 93 | 101 | 102 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_macd_rsi_kdj_show_together.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 20 | 21 | 30 | 31 | 42 | 43 | 54 | 55 | 66 | 67 | 68 | 76 | 77 | 82 | 83 | 88 | 89 | 94 | 95 | 100 | 101 | 106 | 107 | 108 | 109 |