├── .gradle ├── 4.3.1 │ ├── fileChanges │ │ └── last-build.bin │ ├── fileContent │ │ └── fileContent.lock │ ├── fileHashes │ │ ├── fileHashes.bin │ │ ├── fileHashes.lock │ │ └── resourceHashesCache.bin │ ├── javaCompile │ │ ├── classAnalysis.bin │ │ ├── jarAnalysis.bin │ │ ├── javaCompile.lock │ │ ├── taskHistory.bin │ │ └── taskJars.bin │ └── taskHistory │ │ ├── taskHistory.bin │ │ └── taskHistory.lock ├── 4.6 │ ├── fileChanges │ │ └── last-build.bin │ ├── fileContent │ │ └── fileContent.lock │ ├── fileHashes │ │ ├── fileHashes.bin │ │ ├── fileHashes.lock │ │ └── resourceHashesCache.bin │ ├── javaCompile │ │ ├── classAnalysis.bin │ │ ├── jarAnalysis.bin │ │ ├── javaCompile.lock │ │ ├── taskHistory.bin │ │ └── taskJars.bin │ └── taskHistory │ │ ├── taskHistory.bin │ │ └── taskHistory.lock ├── buildOutputCleanup │ ├── buildOutputCleanup.lock │ ├── cache.properties │ └── outputFiles.bin └── vcsWorkingDirs │ └── gc.properties ├── .idea ├── caches │ └── build_file_checksums.ser ├── codeStyles │ └── Project.xml ├── gradle.xml ├── libraries │ ├── Gradle__com_android_support_animated_vector_drawable_26_0_0.xml │ ├── Gradle__com_android_support_appcompat_v7_26_0_0.xml │ ├── Gradle__com_android_support_recyclerview_v7_26_0_0.xml │ ├── Gradle__com_android_support_support_annotations_26_0_0_jar.xml │ ├── Gradle__com_android_support_support_compat_26_0_0.xml │ ├── Gradle__com_android_support_support_core_ui_26_0_0.xml │ ├── Gradle__com_android_support_support_core_utils_26_0_0.xml │ ├── Gradle__com_android_support_support_fragment_26_0_0.xml │ ├── Gradle__com_android_support_support_media_compat_26_0_0.xml │ ├── Gradle__com_android_support_support_v4_26_0_0.xml │ ├── Gradle__com_android_support_support_vector_drawable_26_0_0.xml │ ├── Gradle__com_android_support_test_espresso_espresso_core_2_2_2.xml │ ├── Gradle__com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml │ ├── Gradle__com_android_support_test_exposed_instrumentation_api_publish_0_5.xml │ ├── Gradle__com_android_support_test_rules_0_5.xml │ ├── Gradle__com_android_support_test_runner_0_5.xml │ ├── Gradle__com_github_CymChad_BaseRecyclerViewAdapterHelper_2_9_34.xml │ ├── Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml │ ├── Gradle__com_squareup_javawriter_2_1_1_jar.xml │ ├── Gradle__javax_annotation_javax_annotation_api_1_2_jar.xml │ ├── Gradle__javax_inject_javax_inject_1_jar.xml │ ├── Gradle__junit_junit_4_12_jar.xml │ ├── Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml │ ├── Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml │ └── Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── AndroidCustomView.iml ├── README.md ├── animation_button.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── stormdzh │ │ └── androidcustomview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── stormdzh │ │ │ └── androidcustomview │ │ │ ├── activity │ │ │ ├── AnimationBtnActivity.java │ │ │ ├── AnimationViewActivity.java │ │ │ ├── BannerActivity.java │ │ │ ├── BubbleViewActivity.java │ │ │ ├── DragBallActivity.java │ │ │ ├── FingerprintActivity.java │ │ │ ├── HoverItemActivity.java │ │ │ ├── ItemCenterRVActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MediaCameraActivity.java │ │ │ ├── PayPsdViewActivity.java │ │ │ ├── ProgressBarActivity.java │ │ │ ├── RadarActivity.java │ │ │ ├── SurfaceViewBubbleActivity.java │ │ │ ├── TestActivity.java │ │ │ ├── WaveByBezierActivity.java │ │ │ └── WaveBySinCosActivity.java │ │ │ ├── adapter │ │ │ ├── HoverAdapter.java │ │ │ ├── ItemCenter2Adapter.java │ │ │ ├── ItemCenterAdapter.java │ │ │ └── MainAdapter.java │ │ │ ├── bean │ │ │ ├── CircleBean.java │ │ │ ├── TypeBean.java │ │ │ ├── UserBean.java │ │ │ └── WaveBean.java │ │ │ ├── tagview │ │ │ ├── TagActivity.java │ │ │ ├── TagAdapter.java │ │ │ ├── TagBean.java │ │ │ └── recyclerview.md │ │ │ ├── utils │ │ │ ├── BezierUtil.java │ │ │ ├── CharacterParser.java │ │ │ ├── DisplayUtils.java │ │ │ ├── FingerprintUtil.java │ │ │ ├── PinyinComparator.java │ │ │ └── mediacamera │ │ │ │ ├── FileUtils.java │ │ │ │ └── helper │ │ │ │ ├── MediaHelper.java │ │ │ │ └── PermissionHelper.java │ │ │ └── widget │ │ │ ├── AnimationButton.java │ │ │ ├── BaseView.java │ │ │ ├── BubbleView.java │ │ │ ├── BubbleView2.java │ │ │ ├── CircleProgressBarView.java │ │ │ ├── DividerItemDecoration.java │ │ │ ├── DragBallView.java │ │ │ ├── FadeInTextView.java │ │ │ ├── HorizontalProgressBar.java │ │ │ ├── HoverItemDecoration.java │ │ │ ├── IndexView.java │ │ │ ├── IndicatorView.java │ │ │ ├── ItemCenterRecyclerView.java │ │ │ ├── LoadingButton.java │ │ │ ├── LoadingLineView.java │ │ │ ├── LoadingView.java │ │ │ ├── PayPsdInputView.java │ │ │ ├── ProductProgressBar.java │ │ │ ├── RadarWaveView.java │ │ │ ├── SuperDividerItemDecoration.java │ │ │ ├── SurfaceBubbleView.java │ │ │ ├── TXWaveViewByBezier.java │ │ │ ├── TxBubbleLayout.java │ │ │ ├── WaveViewByBezier.java │ │ │ ├── WaveViewBySinCos.java │ │ │ └── banner │ │ │ ├── BannerView.java │ │ │ ├── PagerOptions.java │ │ │ ├── adapter │ │ │ └── BannerViewPagerAdapter.java │ │ │ ├── holder │ │ │ ├── BannerViewHolder.java │ │ │ └── BannerViewHolderCreator.java │ │ │ └── listener │ │ │ ├── OnPageChangeListener.java │ │ │ └── OnPageClickListener.java │ └── res │ │ ├── drawable │ │ ├── background_gradual_assarts.xml │ │ ├── progress_color_horizontal.xml │ │ ├── ripple_circle.xml │ │ ├── shape_circle_bg.xml │ │ ├── tag_bg_selector.xml │ │ ├── tag_checked_bg.xml │ │ ├── tag_normal_bg.xml │ │ ├── tag_text_selector.xml │ │ └── video_seekbar.xml │ │ ├── layout │ │ ├── activity_animation_btn.xml │ │ ├── activity_animation_view.xml │ │ ├── activity_banner.xml │ │ ├── activity_bubble_view.xml │ │ ├── activity_drag_ball.xml │ │ ├── activity_finger_print.xml │ │ ├── activity_hover_item.xml │ │ ├── activity_item_center.xml │ │ ├── activity_main.xml │ │ ├── activity_mediacamera.xml │ │ ├── activity_pay_psd_view.xml │ │ ├── activity_pregress_bar.xml │ │ ├── activity_radar.xml │ │ ├── activity_surfaceview_bubble.xml │ │ ├── activity_tag.xml │ │ ├── activity_test.xml │ │ ├── activity_wave_by_bezier.xml │ │ ├── activity_wave_by_sin_cos.xml │ │ ├── activity_webview.xml │ │ ├── adapter_item_center.xml │ │ ├── adapter_item_center2.xml │ │ ├── adapter_item_hover_user.xml │ │ ├── adapter_item_main.xml │ │ ├── banner_item.xml │ │ ├── banner_view_layout.xml │ │ └── tag_layout.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ ├── beijing2x.jpg │ │ ├── ic_launcher.png │ │ └── start_logo_group.png │ │ ├── mipmap-xxhdpi │ │ ├── app_download.png │ │ ├── banner_point_disabled.png │ │ ├── banner_point_enabled.png │ │ ├── bt_start.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── icon_back_white.png │ │ ├── icon_fanzhuan.png │ │ ├── icon_video_ing.png │ │ ├── kaibo_icon_huakuai.png │ │ ├── live_close_icon.png │ │ └── progress_tip_icon.png │ │ ├── mipmap-xxxhdpi │ │ ├── beijing.jpg │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── stormdzh │ └── androidcustomview │ └── ExampleUnitTest.java ├── build.gradle ├── build └── android-profile │ ├── profile-2019-07-17-10-53-57-206.json │ ├── profile-2019-07-17-10-53-57-206.rawproto │ ├── profile-2019-07-17-10-55-29-933.json │ ├── profile-2019-07-17-10-55-29-933.rawproto │ ├── profile-2019-07-17-10-57-05-746.json │ ├── profile-2019-07-17-10-57-05-746.rawproto │ ├── profile-2019-07-17-10-57-33-584.json │ ├── profile-2019-07-17-10-57-33-584.rawproto │ ├── profile-2019-07-17-10-58-43-275.json │ ├── profile-2019-07-17-10-58-43-275.rawproto │ ├── profile-2019-07-17-11-03-43-295.json │ ├── profile-2019-07-17-11-03-43-295.rawproto │ ├── profile-2019-07-17-11-04-59-548.json │ ├── profile-2019-07-17-11-04-59-548.rawproto │ ├── profile-2019-07-17-11-11-52-506.json │ ├── profile-2019-07-17-11-11-52-506.rawproto │ ├── profile-2019-07-17-11-28-03-355.json │ ├── profile-2019-07-17-11-28-03-355.rawproto │ ├── profile-2019-07-17-11-28-33-124.json │ ├── profile-2019-07-17-11-28-33-124.rawproto │ ├── profile-2019-07-18-09-52-36-364.json │ ├── profile-2019-07-18-09-52-36-364.rawproto │ ├── profile-2019-07-18-09-52-39-201.json │ ├── profile-2019-07-18-09-52-39-201.rawproto │ ├── profile-2019-07-18-10-16-24-458.json │ ├── profile-2019-07-18-10-16-24-458.rawproto │ ├── profile-2019-07-18-10-17-14-983.json │ ├── profile-2019-07-18-10-17-14-983.rawproto │ ├── profile-2019-07-18-10-18-41-458.json │ ├── profile-2019-07-18-10-18-41-458.rawproto │ ├── profile-2019-07-18-10-19-19-448.json │ ├── profile-2019-07-18-10-19-19-448.rawproto │ ├── profile-2019-07-18-10-20-12-501.json │ ├── profile-2019-07-18-10-20-12-501.rawproto │ ├── profile-2019-07-18-10-23-14-475.json │ ├── profile-2019-07-18-10-23-14-475.rawproto │ ├── profile-2019-07-18-10-24-21-603.json │ ├── profile-2019-07-18-10-24-21-603.rawproto │ ├── profile-2019-07-18-10-24-28-045.json │ ├── profile-2019-07-18-10-24-28-045.rawproto │ ├── profile-2019-07-18-10-27-24-008.json │ ├── profile-2019-07-18-10-27-24-008.rawproto │ ├── profile-2019-07-18-10-28-46-717.json │ ├── profile-2019-07-18-10-28-46-717.rawproto │ ├── profile-2019-07-18-10-30-21-252.json │ ├── profile-2019-07-18-10-30-21-252.rawproto │ ├── profile-2019-07-18-10-30-59-125.json │ ├── profile-2019-07-18-10-30-59-125.rawproto │ ├── profile-2019-07-18-10-33-59-198.json │ ├── profile-2019-07-18-10-33-59-198.rawproto │ ├── profile-2019-07-18-10-34-40-195.json │ ├── profile-2019-07-18-10-34-40-195.rawproto │ ├── profile-2019-07-18-10-38-07-106.json │ ├── profile-2019-07-18-10-38-07-106.rawproto │ ├── profile-2019-07-18-10-38-34-907.json │ ├── profile-2019-07-18-10-38-34-907.rawproto │ ├── profile-2019-07-18-10-39-02-918.json │ ├── profile-2019-07-18-10-39-02-918.rawproto │ ├── profile-2019-07-18-10-39-29-007.json │ ├── profile-2019-07-18-10-39-29-007.rawproto │ ├── profile-2019-07-18-10-39-46-545.json │ ├── profile-2019-07-18-10-39-46-545.rawproto │ ├── profile-2019-07-18-10-40-41-007.json │ ├── profile-2019-07-18-10-40-41-007.rawproto │ ├── profile-2019-07-18-10-44-05-090.json │ ├── profile-2019-07-18-10-44-05-090.rawproto │ ├── profile-2019-07-18-10-44-43-192.json │ ├── profile-2019-07-18-10-44-43-192.rawproto │ ├── profile-2019-07-18-10-58-22-308.json │ ├── profile-2019-07-18-10-58-22-308.rawproto │ ├── profile-2019-07-18-11-01-10-802.json │ ├── profile-2019-07-18-11-01-10-802.rawproto │ ├── profile-2019-07-18-11-01-11-954.json │ ├── profile-2019-07-18-11-01-11-954.rawproto │ ├── profile-2019-07-18-11-15-24-083.json │ ├── profile-2019-07-18-11-15-24-083.rawproto │ ├── profile-2019-07-18-11-16-35-190.json │ ├── profile-2019-07-18-11-16-35-190.rawproto │ ├── profile-2019-07-18-11-16-48-169.json │ └── profile-2019-07-18-11-16-48-169.rawproto ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties ├── pay_psd_input_view.md ├── progress.md └── settings.gradle /.gradle/4.3.1/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/4.3.1/fileContent/fileContent.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/fileContent/fileContent.lock -------------------------------------------------------------------------------- /.gradle/4.3.1/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /.gradle/4.3.1/fileHashes/resourceHashesCache.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/fileHashes/resourceHashesCache.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/javaCompile/classAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/javaCompile/classAnalysis.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/javaCompile/jarAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/javaCompile/jarAnalysis.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/javaCompile/javaCompile.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/javaCompile/javaCompile.lock -------------------------------------------------------------------------------- /.gradle/4.3.1/javaCompile/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/javaCompile/taskHistory.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/javaCompile/taskJars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/javaCompile/taskJars.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/taskHistory/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/taskHistory/taskHistory.bin -------------------------------------------------------------------------------- /.gradle/4.3.1/taskHistory/taskHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.3.1/taskHistory/taskHistory.lock -------------------------------------------------------------------------------- /.gradle/4.6/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/4.6/fileContent/fileContent.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/fileContent/fileContent.lock -------------------------------------------------------------------------------- /.gradle/4.6/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/4.6/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /.gradle/4.6/fileHashes/resourceHashesCache.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/fileHashes/resourceHashesCache.bin -------------------------------------------------------------------------------- /.gradle/4.6/javaCompile/classAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/javaCompile/classAnalysis.bin -------------------------------------------------------------------------------- /.gradle/4.6/javaCompile/jarAnalysis.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/javaCompile/jarAnalysis.bin -------------------------------------------------------------------------------- /.gradle/4.6/javaCompile/javaCompile.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/javaCompile/javaCompile.lock -------------------------------------------------------------------------------- /.gradle/4.6/javaCompile/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/javaCompile/taskHistory.bin -------------------------------------------------------------------------------- /.gradle/4.6/javaCompile/taskJars.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/javaCompile/taskJars.bin -------------------------------------------------------------------------------- /.gradle/4.6/taskHistory/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/taskHistory/taskHistory.bin -------------------------------------------------------------------------------- /.gradle/4.6/taskHistory/taskHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/4.6/taskHistory/taskHistory.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Wed Jul 17 10:16:53 CST 2019 2 | gradle.version=4.3.1 3 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/outputFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/buildOutputCleanup/outputFiles.bin -------------------------------------------------------------------------------- /.gradle/vcsWorkingDirs/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.gradle/vcsWorkingDirs/gc.properties -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stormdzh/AndroidCustomView/88e2dd2d889b6212228ad5292b92b978b975bc97/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_animated_vector_drawable_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_appcompat_v7_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_recyclerview_v7_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_annotations_26_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_compat_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_core_ui_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_core_utils_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_fragment_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_media_compat_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_v4_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_support_vector_drawable_26_0_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_test_espresso_espresso_core_2_2_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_test_espresso_espresso_idling_resource_2_2_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_test_exposed_instrumentation_api_publish_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_test_rules_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_android_support_test_runner_0_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_github_CymChad_BaseRecyclerViewAdapterHelper_2_9_34.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__javax_annotation_javax_annotation_api_1_2_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__junit_junit_4_12_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AndroidCustomView.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # [**炫酷的提交按钮**](https://github.com/lygttpod/AndroidCustomView/blob/master/animation_button.md) 3 | ![99.gif](http://upload-images.jianshu.io/upload_images/2057501-0d1119721429bf71.gif?imageMogr2/auto-orient/strip) 4 | 5 | 6 | # [**仿微信支付宝等风格的支付密码输入框的实现**](https://github.com/lygttpod/AndroidCustomView/blob/master/pay_psd_input_view.md) 7 | ![两种样式供你选择](http://upload-images.jianshu.io/upload_images/2057501-3ca764c315dcdea2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/320) 8 | 9 | # [**炫酷的进度条**](https://github.com/lygttpod/AndroidCustomView/blob/master/progress.md) 10 | ![progress.gif](http://upload-images.jianshu.io/upload_images/2057501-615ad5fe97faf782.gif?imageMogr2/auto-orient/strip) 11 | 12 | # [**TextView实现打印机逐个显示的效果**](http://www.jianshu.com/p/4d987769785c) 13 | ![FadeInTextView.gif](http://upload-images.jianshu.io/upload_images/2057501-a7a751b456b25494.gif?imageMogr2/auto-orient/strip) 14 | 15 | # [**水波动画效果多种实现方式详解**](http://www.jianshu.com/p/0cd1c1d47f4a) 16 | ![wave.gif](http://upload-images.jianshu.io/upload_images/2057501-43358432099e1e71.gif?imageMogr2/auto-orient/strip) 17 | 18 | # [**仿QQ未读消息拖拽效果详解**](http://www.jianshu.com/p/ed2721286778) 19 | ![拖拽粘性小球.gif](http://upload-images.jianshu.io/upload_images/2057501-7df462b80a11f7e2.gif?imageMogr2/auto-orient/strip) 20 | 21 | # [**炫酷的欢迎页**] 22 | ![欢迎页.gif](http://osnoex6vf.bkt.clouddn.com/welcome.gif) 23 | 24 | # [**进度条**] 25 | ![进度条.gif](http://osnoex6vf.bkt.clouddn.com/loading.gif) 26 | 27 | # [**一行代码实现吸顶悬停效果**] 28 | ![吸顶悬停.gif](http://osnoex6vf.bkt.clouddn.com/hover_view.gif) 29 | 30 | # [**在水波中晃动的小船,周围还有各种小气泡**] 31 | ![boat_wava.gif](https://github.com/stormdzh/AndroidCustomView/blob/master/pre/boat_wava.gif) 32 | 33 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /debug 3 | .idea/ 4 | *.iml 5 | .gradle 6 | /local.properties 7 | /.idea/workspace.xml 8 | /.idea/libraries 9 | .DS_Store 10 | /captures 11 | .externalNativeBuild 12 | /.idea 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "com.stormdzh.androidcustomview" 7 | targetSdkVersion 26 8 | minSdkVersion 17 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | productFlavors { 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(include: ['*.jar'], dir: 'libs') 25 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 26 | exclude group: 'com.android.support', module: 'support-annotations' 27 | }) 28 | compile 'com.android.support:appcompat-v7:26.0.0' 29 | compile 'com.android.support:recyclerview-v7:26.0.0' 30 | testCompile 'junit:junit:4.12' 31 | compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34' 32 | } 33 | -------------------------------------------------------------------------------- /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 D:\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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/stormdzh/androidcustomview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.stormdzh.androidcustomview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/AnimationBtnActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.widget.Toast; 6 | 7 | import com.stormdzh.androidcustomview.R; 8 | import com.stormdzh.androidcustomview.widget.AnimationButton; 9 | 10 | public class AnimationBtnActivity extends AppCompatActivity { 11 | 12 | private AnimationButton animationButton; 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_animation_btn); 18 | animationButton = (AnimationButton) findViewById(R.id.animation_btn); 19 | animationButton.setAnimationButtonListener(new AnimationButton.AnimationButtonListener() { 20 | @Override 21 | public void onClickListener() { 22 | animationButton.start(); 23 | } 24 | 25 | @Override 26 | public void animationFinish() { 27 | Toast.makeText(AnimationBtnActivity.this,"动画执行完毕",Toast.LENGTH_SHORT).show(); 28 | // finish(); 29 | animationButton.reset(); 30 | } 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/AnimationViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.Toast; 7 | 8 | import com.stormdzh.androidcustomview.R; 9 | import com.stormdzh.androidcustomview.widget.FadeInTextView; 10 | import com.stormdzh.androidcustomview.widget.LoadingButton; 11 | 12 | public class AnimationViewActivity extends AppCompatActivity { 13 | 14 | private FadeInTextView fadeInTextView; 15 | private LoadingButton loadingButton; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_animation_view); 21 | 22 | fadeInTextView = (FadeInTextView) findViewById(R.id.fade_in_tv); 23 | loadingButton = (LoadingButton) findViewById(R.id.loading_btn); 24 | 25 | fadeInTextView 26 | .setTextString("自定义view实现字符串逐字显示,后边的文字是为了测试换行是否正常显示!") 27 | .setTextAnimationListener(new FadeInTextView.TextAnimationListener() { 28 | @Override 29 | public void animationFinish() { 30 | loadingButton.stopLoading(); 31 | } 32 | }); 33 | 34 | loadingButton.setOnClickListener(new View.OnClickListener() { 35 | @Override 36 | public void onClick(View v) { 37 | loadingButton.startLoading(); 38 | fadeInTextView.startFadeInAnimation(); 39 | } 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/BannerActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.view.ViewPager; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.widget.ImageView; 12 | import android.widget.Toast; 13 | 14 | import com.stormdzh.androidcustomview.R; 15 | import com.stormdzh.androidcustomview.widget.banner.BannerView; 16 | import com.stormdzh.androidcustomview.widget.banner.listener.OnPageChangeListener; 17 | import com.stormdzh.androidcustomview.widget.banner.listener.OnPageClickListener; 18 | import com.stormdzh.androidcustomview.widget.banner.PagerOptions; 19 | import com.stormdzh.androidcustomview.widget.banner.holder.BannerViewHolder; 20 | import com.stormdzh.androidcustomview.widget.banner.holder.BannerViewHolderCreator; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | *
27 |  *      @author : xiaoyao
28 |  *      e-mail  : xiaoyao@51vest.com
29 |  *      date    : 2018/03/09
30 |  *      desc    :
31 |  *      version : 1.0
32 |  * 
33 | */ 34 | 35 | public class BannerActivity extends AppCompatActivity { 36 | 37 | private BannerView bannerView; 38 | private List datas = new ArrayList<>(); 39 | @Override 40 | protected void onCreate(@Nullable Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_banner); 43 | 44 | datas.add("http://7xi8d6.com1.z0.glb.clouddn.com/20180109085038_4A7atU_rakukoo_9_1_2018_8_50_25_276.jpeg"); 45 | datas.add("http://7xi8d6.com1.z0.glb.clouddn.com/20180102083655_3t4ytm_Screenshot.jpeg"); 46 | datas.add("http://7xi8d6.com1.z0.glb.clouddn.com/20171228085004_5yEHju_Screenshot.jpeg"); 47 | 48 | bannerView = (BannerView) findViewById(R.id.banner_view); 49 | 50 | PagerOptions options = new PagerOptions 51 | .Builder(this) 52 | .setPageMargin(20) 53 | .setPrePagerWidth(50) 54 | .setIndicatorDrawable(R.mipmap.banner_point_disabled,R.mipmap.banner_point_enabled) 55 | // .setIndicatorColor(Color.YELLOW,Color.RED) 56 | .setOnPageClickListener(new OnPageClickListener() { 57 | @Override 58 | public void onPageClick(View view, int position) { 59 | Toast.makeText(BannerActivity.this,"Click"+position,Toast.LENGTH_SHORT).show(); 60 | } 61 | }) 62 | .build(); 63 | 64 | 65 | bannerView.setPagerOptions(options) 66 | .setPages(datas, new BannerViewHolderCreator() { 67 | @Override 68 | public MyBanner createViewHolder() { 69 | return new MyBanner(); 70 | } 71 | }); 72 | 73 | } 74 | 75 | public class MyBanner implements BannerViewHolder{ 76 | 77 | private ImageView imageView; 78 | @Override 79 | public View createView(Context context) { 80 | View view = LayoutInflater.from(context).inflate(R.layout.banner_item,null); 81 | return view; 82 | } 83 | 84 | @Override 85 | public void onBind(Context context, int position, String data) { 86 | 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/DragBallActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.text.TextUtils; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.EditText; 10 | import android.widget.Toast; 11 | 12 | import com.stormdzh.androidcustomview.R; 13 | import com.stormdzh.androidcustomview.widget.DragBallView; 14 | 15 | 16 | public class DragBallActivity extends AppCompatActivity { 17 | 18 | 19 | private Button resetBtn, msgCountBtn; 20 | private DragBallView dragBallView; 21 | private EditText msgCountEt; 22 | 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_drag_ball); 27 | resetBtn = (Button) findViewById(R.id.reset_btn); 28 | msgCountBtn = (Button) findViewById(R.id.msg_count_btn); 29 | dragBallView = (DragBallView) findViewById(R.id.drag_ball_view); 30 | 31 | msgCountEt = (EditText) findViewById(R.id.msg_count_et); 32 | 33 | resetBtn.setOnClickListener(new View.OnClickListener() { 34 | @Override 35 | public void onClick(View v) { 36 | dragBallView.reset(); 37 | } 38 | }); 39 | 40 | msgCountBtn.setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | if (!TextUtils.isEmpty(msgCountEt.getText().toString().trim())) { 44 | int count = Integer.valueOf(msgCountEt.getText().toString().trim()); 45 | dragBallView.setMsgCount(count); 46 | } 47 | } 48 | }); 49 | 50 | dragBallView.setOnDragBallListener(new DragBallView.OnDragBallListener() { 51 | @Override 52 | public void onDisappear() { 53 | Toast.makeText(DragBallActivity.this, "消失了", Toast.LENGTH_SHORT).show(); 54 | } 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/FingerprintActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.hardware.fingerprint.FingerprintManagerCompat; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.util.Log; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | import android.widget.Toast; 11 | 12 | import com.stormdzh.androidcustomview.R; 13 | import com.stormdzh.androidcustomview.utils.FingerprintUtil; 14 | 15 | /** 16 | * Created by xiaoyao on 2017/9/14. 17 | */ 18 | 19 | public class FingerprintActivity extends AppCompatActivity { 20 | 21 | private static final String TAG = "allen"; 22 | 23 | 24 | TextView resultTv; 25 | @Override 26 | protected void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | 29 | setContentView(R.layout.activity_finger_print); 30 | 31 | resultTv = (TextView) findViewById(R.id.result_tv); 32 | findViewById(R.id.open_finger_btn).setOnClickListener(new View.OnClickListener() { 33 | @Override 34 | public void onClick(View v) { 35 | openFinger(); 36 | } 37 | }); 38 | 39 | 40 | findViewById(R.id.cancel_finger_btn).setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | FingerprintUtil.cancel(); 44 | } 45 | }); 46 | 47 | 48 | } 49 | 50 | private void openFinger() { 51 | 52 | FingerprintUtil.callFingerPrint(this, new FingerprintUtil.OnCallBackListener() { 53 | @Override 54 | public void onSupportFailed() { 55 | Toast.makeText(FingerprintActivity.this, "当前设备不支持指纹", Toast.LENGTH_LONG).show(); 56 | Log.e(TAG, "当前设备不支持指纹"); 57 | } 58 | 59 | @Override 60 | public void onInsecurity() { 61 | Toast.makeText(FingerprintActivity.this, "当前设备未处于安全保护中", Toast.LENGTH_LONG).show(); 62 | Log.e(TAG, "当前设备未处于安全保护中"); 63 | } 64 | 65 | @Override 66 | public void onEnrollFailed() { 67 | Toast.makeText(FingerprintActivity.this, "请到设置中设置指纹", Toast.LENGTH_LONG).show(); 68 | Log.e(TAG, "请到设置中设置指纹"); 69 | } 70 | 71 | @Override 72 | public void onAuthenticationStart() { 73 | Toast.makeText(FingerprintActivity.this, "验证开始", Toast.LENGTH_LONG).show(); 74 | 75 | Log.e(TAG, "onAuthenticationStart: "); 76 | } 77 | 78 | @Override 79 | public void onAuthenticationError(int errMsgId, CharSequence errString) { 80 | Toast.makeText(FingerprintActivity.this, errString, Toast.LENGTH_LONG).show(); 81 | Log.e(TAG, "onAuthenticationError: "); 82 | } 83 | 84 | @Override 85 | public void onAuthenticationFailed() { 86 | Toast.makeText(FingerprintActivity.this, "解锁失败", Toast.LENGTH_LONG).show(); 87 | 88 | Log.e(TAG, "解锁失败"); 89 | } 90 | 91 | @Override 92 | public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { 93 | Toast.makeText(FingerprintActivity.this, helpString, Toast.LENGTH_LONG).show(); 94 | 95 | Log.e(TAG, "onAuthenticationHelp: "); 96 | } 97 | 98 | @Override 99 | public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) { 100 | Toast.makeText(FingerprintActivity.this, "解锁成功", Toast.LENGTH_LONG).show(); 101 | Log.e(TAG, "解锁成功"); 102 | resultTv.setText(result.getClass().getName()); 103 | } 104 | }); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/HoverItemActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.widget.TextView; 9 | 10 | import com.stormdzh.androidcustomview.R; 11 | import com.stormdzh.androidcustomview.adapter.HoverAdapter; 12 | import com.stormdzh.androidcustomview.bean.UserBean; 13 | import com.stormdzh.androidcustomview.utils.CharacterParser; 14 | import com.stormdzh.androidcustomview.utils.PinyinComparator; 15 | import com.stormdzh.androidcustomview.widget.HoverItemDecoration; 16 | import com.stormdzh.androidcustomview.widget.IndexView; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | /** 23 | *
 24 |  *      @author : xiaoyao
 25 |  *      e-mail  : xiaoyao@51vest.com
 26 |  *      date    : 2018/04/16
 27 |  *      desc    :
 28 |  *      version : 1.0
 29 |  * 
30 | */ 31 | 32 | public class HoverItemActivity extends AppCompatActivity { 33 | private RecyclerView recyclerView; 34 | private IndexView indexView; 35 | private TextView showTextDialog; 36 | 37 | private HoverAdapter adapter; 38 | 39 | private List userBeans = new ArrayList<>(); 40 | 41 | private String[] names = new String[]{"阿妹", "打黑牛", "张三", "李四", "王五", "田鸡", "孙五"}; 42 | 43 | /** 44 | * 汉字转换成拼音的类 45 | */ 46 | private CharacterParser characterParser; 47 | /** 48 | * 根据拼音来排列ListView里面的数据类 49 | */ 50 | private PinyinComparator pinyinComparator; 51 | 52 | private LinearLayoutManager layoutManager; 53 | 54 | @Override 55 | protected void onCreate(@Nullable Bundle savedInstanceState) { 56 | super.onCreate(savedInstanceState); 57 | setContentView(R.layout.activity_hover_item); 58 | 59 | characterParser = CharacterParser.getInstance(); 60 | pinyinComparator = new PinyinComparator(); 61 | 62 | 63 | userBeans = filledData(getData()); 64 | 65 | recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 66 | indexView = (IndexView) findViewById(R.id.index_view); 67 | showTextDialog = (TextView) findViewById(R.id.show_text_dialog); 68 | 69 | layoutManager = new LinearLayoutManager(this); 70 | recyclerView.setLayoutManager(layoutManager); 71 | //一行代码实现吸顶悬浮的效果 72 | recyclerView.addItemDecoration(new HoverItemDecoration(this, new HoverItemDecoration.BindItemTextCallback() { 73 | @Override 74 | public String getItemText(int position) { 75 | //悬浮的信息 76 | return userBeans.get(position).getSortLetters(); 77 | } 78 | })); 79 | 80 | adapter = new HoverAdapter(userBeans); 81 | 82 | recyclerView.setAdapter(adapter); 83 | 84 | initIndexView(); 85 | } 86 | 87 | /** 88 | * 初始化右边字幕索引view 89 | */ 90 | private void initIndexView() { 91 | indexView.setShowTextDialog(showTextDialog); 92 | indexView.setOnTouchingLetterChangedListener(new IndexView.OnTouchingLetterChangedListener() { 93 | @Override 94 | public void onTouchingLetterChanged(String letter) { 95 | // 该字母首次出现的位置 96 | int position = getPositionForSection(letter); 97 | if (position != -1) { 98 | layoutManager.scrollToPositionWithOffset(position, 0); 99 | layoutManager.setStackFromEnd(false); 100 | } 101 | } 102 | }); 103 | } 104 | 105 | public int getPositionForSection(String section) { 106 | for (int i = 0; i < userBeans.size(); i++) { 107 | String sortStr = userBeans.get(i).getSortLetters(); 108 | if (sortStr.equals(section)) { 109 | return i; 110 | } 111 | } 112 | return -1; 113 | } 114 | 115 | private List getData() { 116 | List userBeans = new ArrayList<>(); 117 | for (int i = 0; i < 50; i++) { 118 | UserBean userBean = new UserBean(); 119 | userBean.setUserName(names[i % 7]); 120 | userBeans.add(userBean); 121 | } 122 | 123 | return userBeans; 124 | } 125 | 126 | private List filledData(List sortList) { 127 | 128 | for (int i = 0; i < sortList.size(); i++) { 129 | 130 | if ("".equals(sortList.get(i).getUserName())) { 131 | sortList.get(i).setSortLetters("#"); 132 | } else { 133 | // 汉字转换成拼音 134 | String pinyin = characterParser.getSelling(sortList.get(i).getUserName()); 135 | String sortString = pinyin.substring(0, 1).toUpperCase(); 136 | 137 | // 正则表达式,判断首字母是否是英文字母 138 | if (sortString.matches("[A-Z]")) { 139 | sortList.get(i).setSortLetters(sortString.toUpperCase()); 140 | } else { 141 | sortList.get(i).setSortLetters("#"); 142 | } 143 | } 144 | 145 | } 146 | 147 | // 根据a-z进行排序源数据 148 | Collections.sort(sortList, pinyinComparator); 149 | 150 | return sortList; 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/ItemCenterRVActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.DividerItemDecoration; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.LinearSnapHelper; 9 | import android.support.v7.widget.RecyclerView; 10 | 11 | import com.stormdzh.androidcustomview.R; 12 | import com.stormdzh.androidcustomview.adapter.ItemCenter2Adapter; 13 | import com.stormdzh.androidcustomview.adapter.ItemCenterAdapter; 14 | import com.stormdzh.androidcustomview.widget.ItemCenterRecyclerView; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | *
21 |  *      @author : xiaoyao
22 |  *      e-mail  : xiaoyao@51vest.com
23 |  *      date    : 2018/05/07
24 |  *      desc    :
25 |  *      version : 1.0
26 |  * 
27 | */ 28 | 29 | public class ItemCenterRVActivity extends AppCompatActivity { 30 | private ItemCenterRecyclerView recyclerView; 31 | private ItemCenterRecyclerView recyclerView2; 32 | private ItemCenterAdapter adapter; 33 | private ItemCenter2Adapter adapter2; 34 | @Override 35 | protected void onCreate(@Nullable Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.activity_item_center); 38 | 39 | 40 | recyclerView = (ItemCenterRecyclerView) findViewById(R.id.recycler_view); 41 | recyclerView2 = (ItemCenterRecyclerView) findViewById(R.id.recycler_view_2); 42 | 43 | initRv(recyclerView); 44 | initRv(recyclerView2); 45 | recyclerView.setAdapter(adapter); 46 | recyclerView2.setAdapter(adapter2); 47 | 48 | // recyclerView2.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.HORIZONTAL_LIST)); 49 | setSyncScroll(recyclerView,recyclerView2); 50 | 51 | } 52 | 53 | private void initRv(ItemCenterRecyclerView recyclerView) { 54 | LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false); 55 | recyclerView.setLayoutManager(layoutManager); 56 | 57 | LinearSnapHelper linearSnapHelper = new LinearSnapHelper(); 58 | linearSnapHelper.attachToRecyclerView(recyclerView); 59 | 60 | adapter = new ItemCenterAdapter(this,recyclerView,getData()); 61 | adapter2 = new ItemCenter2Adapter(this,recyclerView,getData()); 62 | } 63 | 64 | private List getData() { 65 | List strings = new ArrayList<>(); 66 | for (int i = 0; i < 20; i++) { 67 | strings.add(""); 68 | } 69 | return strings; 70 | } 71 | 72 | public void setSyncScroll(final RecyclerView leftList, final RecyclerView rightList) { 73 | leftList.addOnScrollListener(new RecyclerView.OnScrollListener() { 74 | @Override 75 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 76 | if (recyclerView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { 77 | rightList.scrollBy(dx, dy); 78 | } 79 | } 80 | }); 81 | 82 | rightList.addOnScrollListener(new RecyclerView.OnScrollListener() { 83 | @Override 84 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 85 | if (recyclerView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { 86 | leftList.scrollBy(dx, dy); 87 | } 88 | } 89 | }); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/PayPsdViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.widget.Toast; 6 | 7 | import com.stormdzh.androidcustomview.R; 8 | import com.stormdzh.androidcustomview.widget.PayPsdInputView; 9 | 10 | public class PayPsdViewActivity extends AppCompatActivity { 11 | private PayPsdInputView passwordInputView; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_pay_psd_view); 17 | 18 | passwordInputView = (PayPsdInputView) findViewById(R.id.password); 19 | 20 | passwordInputView.setComparePassword( new PayPsdInputView.onPasswordListener() { 21 | 22 | @Override 23 | public void onDifference(String oldPsd, String newPsd) { 24 | // TODO: 2018/1/22 和上次输入的密码不一致 做相应的业务逻辑处理 25 | Toast.makeText(PayPsdViewActivity.this, "两次密码输入不同" + oldPsd + "!=" + newPsd, Toast.LENGTH_SHORT).show(); 26 | passwordInputView.cleanPsd(); 27 | } 28 | 29 | @Override 30 | public void onEqual(String psd) { 31 | // TODO: 2017/5/7 两次输入密码相同,那就去进行支付楼 32 | Toast.makeText(PayPsdViewActivity.this, "密码相同" + psd, Toast.LENGTH_SHORT).show(); 33 | passwordInputView.setComparePassword(""); 34 | passwordInputView.cleanPsd(); 35 | } 36 | 37 | @Override 38 | public void inputFinished(String inputPsd) { 39 | // TODO: 2018/1/3 输完逻辑 40 | Toast.makeText(PayPsdViewActivity.this, "输入完毕:" + inputPsd, Toast.LENGTH_SHORT).show(); 41 | passwordInputView.setComparePassword(inputPsd); 42 | } 43 | }); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/ProgressBarActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.TextView; 9 | 10 | import com.stormdzh.androidcustomview.R; 11 | import com.stormdzh.androidcustomview.widget.CircleProgressBarView; 12 | import com.stormdzh.androidcustomview.widget.HorizontalProgressBar; 13 | import com.stormdzh.androidcustomview.widget.LoadingLineView; 14 | import com.stormdzh.androidcustomview.widget.LoadingView; 15 | import com.stormdzh.androidcustomview.widget.ProductProgressBar; 16 | 17 | public class ProgressBarActivity extends AppCompatActivity { 18 | 19 | CircleProgressBarView circleProgressBarView; 20 | HorizontalProgressBar horizontalProgressBar; 21 | ProductProgressBar productProgressBar; 22 | LoadingView loadingView; 23 | TextView textView; 24 | LoadingLineView loadingLineView; 25 | 26 | Button button; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_pregress_bar); 32 | 33 | circleProgressBarView = (CircleProgressBarView) findViewById(R.id.circle_progress_view); 34 | 35 | horizontalProgressBar = (HorizontalProgressBar) findViewById(R.id.horizontal_progress_view); 36 | productProgressBar = (ProductProgressBar) findViewById(R.id.product_progress_view); 37 | loadingView = (LoadingView) findViewById(R.id.loading_view); 38 | loadingLineView = (LoadingLineView) findViewById(R.id.loading_line_view); 39 | 40 | textView = (TextView) findViewById(R.id.progress_tv); 41 | button = (Button) findViewById(R.id.startAnimationBtn); 42 | 43 | circleProgressBarView.setProgressWithAnimation(60); 44 | circleProgressBarView.setProgressListener(new CircleProgressBarView.ProgressListener() { 45 | @Override 46 | public void currentProgressListener(float currentProgress) { 47 | textView.setText("当前进度:" + currentProgress); 48 | } 49 | }); 50 | circleProgressBarView.startProgressAnimation(); 51 | 52 | horizontalProgressBar.setProgressWithAnimation(60).setProgressListener(new HorizontalProgressBar.ProgressListener() { 53 | @Override 54 | public void currentProgressListener(float currentProgress) { 55 | } 56 | }); 57 | horizontalProgressBar.startProgressAnimation(); 58 | 59 | productProgressBar.setProgress(60).setProgressListener(new ProductProgressBar.ProgressListener() { 60 | @Override 61 | public void currentProgressListener(float currentProgress) { 62 | Log.e("allen", "currentProgressListener: " + currentProgress); 63 | } 64 | }); 65 | 66 | loadingView.startAnimation(); 67 | 68 | button.setOnClickListener(new View.OnClickListener() { 69 | @Override 70 | public void onClick(View v) { 71 | loadingLineView.stopLoading(); 72 | loadingView.startAnimation(); 73 | horizontalProgressBar.setProgressWithAnimation(100); 74 | productProgressBar.setProgress(100); 75 | circleProgressBarView.setProgressWithAnimation(60).startProgressAnimation(); 76 | circleProgressBarView.setProgressListener(new CircleProgressBarView.ProgressListener() { 77 | @Override 78 | public void currentProgressListener(float currentProgress) { 79 | textView.setText("当前进度:" + currentProgress); 80 | } 81 | }); 82 | } 83 | }); 84 | } 85 | 86 | @Override 87 | protected void onResume() { 88 | super.onResume(); 89 | circleProgressBarView.resumeProgressAnimation(); 90 | } 91 | 92 | @Override 93 | protected void onPause() { 94 | super.onPause(); 95 | circleProgressBarView.pauseProgressAnimation(); 96 | } 97 | 98 | @Override 99 | protected void onDestroy() { 100 | super.onDestroy(); 101 | circleProgressBarView.stopProgressAnimation(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/RadarActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | import com.stormdzh.androidcustomview.R; 7 | import com.stormdzh.androidcustomview.widget.RadarWaveView; 8 | 9 | public class RadarActivity extends AppCompatActivity { 10 | 11 | private RadarWaveView radarView; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_radar); 17 | 18 | radarView = (RadarWaveView) findViewById(R.id.radar_view); 19 | } 20 | 21 | @Override 22 | protected void onResume() { 23 | super.onResume(); 24 | radarView.start(); 25 | } 26 | 27 | @Override 28 | protected void onPause() { 29 | super.onPause(); 30 | radarView.pause(); 31 | } 32 | 33 | @Override 34 | protected void onDestroy() { 35 | super.onDestroy(); 36 | radarView.stop(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/SurfaceViewBubbleActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | 7 | import com.stormdzh.androidcustomview.R; 8 | import com.stormdzh.androidcustomview.widget.SurfaceBubbleView; 9 | 10 | /** 11 | * @Description: 描述 12 | * @Author: dzh 13 | * @CreateDate: 2019/7/18 9:54 AM 14 | */ 15 | public class SurfaceViewBubbleActivity extends Activity { 16 | 17 | private SurfaceBubbleView mSurfaceBubbleView; 18 | 19 | @Override 20 | protected void onCreate(@Nullable Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | 23 | setContentView(R.layout.activity_surfaceview_bubble); 24 | 25 | 26 | mSurfaceBubbleView = findViewById(R.id.mSurfaceBubbleView); 27 | } 28 | 29 | @Override 30 | protected void onResume() { 31 | super.onResume(); 32 | // if(mSurfaceBubbleView!=null){ 33 | // mSurfaceBubbleView.resume(); 34 | // } 35 | } 36 | 37 | @Override 38 | protected void onPause() { 39 | if(mSurfaceBubbleView!=null){ 40 | mSurfaceBubbleView.pause(); 41 | } 42 | super.onPause(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/TestActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.animation.AnimatorSet; 4 | import android.animation.ObjectAnimator; 5 | import android.animation.ValueAnimator; 6 | import android.os.Bundle; 7 | import android.support.annotation.Nullable; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.view.animation.Animation; 10 | import android.view.animation.AnimationSet; 11 | import android.view.animation.CycleInterpolator; 12 | import android.view.animation.LinearInterpolator; 13 | import android.view.animation.TranslateAnimation; 14 | import android.widget.ImageView; 15 | 16 | import com.stormdzh.androidcustomview.R; 17 | import com.stormdzh.androidcustomview.widget.TXWaveViewByBezier; 18 | 19 | /** 20 | * Created by a111 on 2018/6/15. 21 | * 实现水波动画 22 | */ 23 | 24 | public class TestActivity extends AppCompatActivity { 25 | 26 | 27 | private TXWaveViewByBezier waveViewByBezier1, waveViewByBezier2; 28 | 29 | private ImageView img_1; 30 | private ImageView img_2; 31 | 32 | @Override 33 | protected void onCreate(@Nullable Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_test); 36 | 37 | waveViewByBezier1 = findViewById(R.id.wave_bezier1); 38 | waveViewByBezier2 = findViewById(R.id.wave_bezier2); 39 | 40 | waveViewByBezier1.setWaveType(TXWaveViewByBezier.SIN); 41 | waveViewByBezier1.startAnimation(); 42 | 43 | waveViewByBezier2.setWaveType(TXWaveViewByBezier.COS); 44 | waveViewByBezier2.startAnimation(); 45 | 46 | 47 | img_1=findViewById(R.id.img_1); 48 | img_2=findViewById(R.id.img_2); 49 | startAimation(); 50 | } 51 | 52 | private void startAimation() { 53 | // AnimationSet aset=new AnimationSet(true); 54 | // 55 | // int dy=100; 56 | // 57 | // TranslateAnimation translateAnimation1=new TranslateAnimation(0,0,0,dy); 58 | // 59 | // TranslateAnimation translateAnimation2=new TranslateAnimation(0,0,0,-dy); 60 | // 61 | // aset.addAnimation(translateAnimation1); 62 | // aset.addAnimation(translateAnimation2); 63 | // 64 | // 65 | // 66 | // //设置插值器 67 | // aset.setInterpolator(new LinearInterpolator()); 68 | // //设置动画持续时长 69 | // aset.setDuration(3000); 70 | // //设置动画结束之后是否保持动画的目标状态 71 | // aset.setFillAfter(true); 72 | // //设置动画结束之后是否保持动画开始时的状态 73 | // aset.setFillBefore(true); 74 | // //设置重复模式 75 | // aset.setRepeatMode(AnimationSet.REVERSE); 76 | // //aset 77 | // aset.setRepeatCount(AnimationSet.INFINITE); 78 | // //设置动画延时时间 79 | // aset.setStartOffset(2000); 80 | // //取消动画 81 | //// aset.cancel(); 82 | // //释放资源 83 | //// aset.reset(); 84 | // 85 | // 86 | // img_1.startAnimation(aset); 87 | 88 | 89 | // ObjectAnimator animator1=ObjectAnimator.ofFloat(img_1, "rotation", 0,360f); 90 | // ObjectAnimator animator2=ObjectAnimator.ofFloat(img_1, "translationX", 0,200f); 91 | // ObjectAnimator animator3=ObjectAnimator.ofFloat(img_1, "translationY", 0,200f); 92 | 93 | 94 | // float dy=100l; 95 | // 96 | // ObjectAnimator animator1=ObjectAnimator.ofFloat(img_1, "translationY", 0,200f); 97 | // ObjectAnimator animator2=ObjectAnimator.ofFloat(img_1, "translationY", 0,0f); 98 | // ObjectAnimator animator3=ObjectAnimator.ofFloat(img_1, "translationY", 0,-200f); 99 | // ObjectAnimator animator4=ObjectAnimator.ofFloat(img_1, "translationY", 0,0f); 100 | // 101 | // AnimatorSet set=new AnimatorSet(); 102 | // //set.playTogether(animator1,animator2,animator3); 103 | // set.playSequentially(animator1,animator2,animator3,animator4); 104 | // set.setDuration(4000); 105 | // set.start(); 106 | 107 | 108 | // ObjectAnimator animator1=ObjectAnimator.ofFloat(img_1, "translationY", -100f,100f); 109 | // ObjectAnimator animator2=ObjectAnimator.ofFloat(img_1, "translationY", 100f,-100f); 110 | // 111 | // animator1.setRepeatCount(ValueAnimator.INFINITE); 112 | // animator1.setDuration(2000); 113 | // 114 | // animator2.setRepeatCount(ValueAnimator.INFINITE); 115 | // animator2.setDuration(2000); 116 | // 117 | // AnimatorSet handAnimSet = new AnimatorSet(); 118 | // handAnimSet.setDuration(4000); 119 | // 120 | // 121 | // handAnimSet.play(animator1).after(animator2); 122 | // 123 | // handAnimSet.start(); 124 | 125 | Animation animation = shakeAnimation(5); 126 | img_1.startAnimation(animation); 127 | img_2.startAnimation(animation); 128 | } 129 | 130 | 131 | public static Animation shakeAnimation(int counts) { 132 | Animation translateAnimation = new TranslateAnimation(0, 0, -15, 15); 133 | translateAnimation.setInterpolator(new CycleInterpolator(counts)); 134 | translateAnimation.setDuration(8000); 135 | translateAnimation.setRepeatCount(ValueAnimator.INFINITE); 136 | return translateAnimation; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/WaveByBezierActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | import com.stormdzh.androidcustomview.R; 7 | import com.stormdzh.androidcustomview.widget.WaveViewByBezier; 8 | 9 | public class WaveByBezierActivity extends AppCompatActivity { 10 | 11 | private WaveViewByBezier waveViewByBezier; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_wave_by_bezier); 17 | 18 | waveViewByBezier = (WaveViewByBezier) findViewById(R.id.wave_bezier); 19 | 20 | waveViewByBezier.startAnimation(); 21 | } 22 | 23 | @Override 24 | protected void onPause() { 25 | super.onPause(); 26 | waveViewByBezier.pauseAnimation(); 27 | } 28 | 29 | @Override 30 | protected void onResume() { 31 | super.onResume(); 32 | waveViewByBezier.resumeAnimation(); 33 | } 34 | 35 | 36 | @Override 37 | protected void onDestroy() { 38 | super.onDestroy(); 39 | waveViewByBezier.stopAnimation(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/activity/WaveBySinCosActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.activity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | import com.stormdzh.androidcustomview.R; 7 | 8 | public class WaveBySinCosActivity extends AppCompatActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_wave_by_sin_cos); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/adapter/HoverAdapter.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.adapter; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | import com.stormdzh.androidcustomview.R; 6 | import com.stormdzh.androidcustomview.bean.UserBean; 7 | import com.chad.library.adapter.base.BaseQuickAdapter; 8 | import com.chad.library.adapter.base.BaseViewHolder; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *
14 |  *      @author : xiaoyao
15 |  *      e-mail  : xiaoyao@51vest.com
16 |  *      date    : 2018/04/16
17 |  *      desc    :
18 |  *      version : 1.0
19 |  * 
20 | */ 21 | 22 | public class HoverAdapter extends BaseQuickAdapter { 23 | 24 | public HoverAdapter( @Nullable List data) { 25 | super(R.layout.adapter_item_hover_user, data); 26 | } 27 | 28 | @Override 29 | protected void convert(BaseViewHolder helper, UserBean item) { 30 | helper.setText(R.id.user_name_tv,item.getUserName()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/adapter/ItemCenter2Adapter.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.stormdzh.androidcustomview.R; 9 | import com.stormdzh.androidcustomview.utils.DisplayUtils; 10 | import com.stormdzh.androidcustomview.widget.ItemCenterRecyclerView; 11 | import com.chad.library.adapter.base.BaseQuickAdapter; 12 | import com.chad.library.adapter.base.BaseViewHolder; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | *
18 |  *      @author : xiaoyao
19 |  *      e-mail  : xiaoyao@51vest.com
20 |  *      date    : 2018/05/07
21 |  *      desc    :
22 |  *      version : 1.0
23 |  * 
24 | */ 25 | 26 | public class ItemCenter2Adapter extends BaseQuickAdapter { 27 | 28 | private ItemCenterRecyclerView recyclerView; 29 | private ViewGroup.MarginLayoutParams p; 30 | private int mRecyclerViewWidth; 31 | private List data; 32 | 33 | public ItemCenter2Adapter(Context context, ItemCenterRecyclerView recyclerView, @Nullable List data) { 34 | super(R.layout.adapter_item_center2, data); 35 | mRecyclerViewWidth = DisplayUtils.getDisplayWidth(context); 36 | this.data = data; 37 | this.recyclerView = recyclerView; 38 | } 39 | 40 | @Override 41 | protected void convert(BaseViewHolder helper, String item) { 42 | View itemRoot = helper.getView(R.id.item_root); 43 | p = (ViewGroup.MarginLayoutParams) itemRoot.getLayoutParams(); 44 | // 为了居中, 第一个条目leftMagrin、最后一个条目的rightMargin是(recyclerView宽度减去一个条目的宽度)/2 45 | int margin = (mRecyclerViewWidth - p.width) / 2; 46 | if (helper.getLayoutPosition() == 0) { 47 | p.leftMargin = margin; 48 | p.rightMargin = 0; 49 | itemRoot.setLayoutParams(p); 50 | } else if (helper.getLayoutPosition() == data.size() - 1) { 51 | p.leftMargin = 0; 52 | p.rightMargin = margin; 53 | itemRoot.setLayoutParams(p); 54 | } else { 55 | p.leftMargin = 0; 56 | p.rightMargin = 0; 57 | itemRoot.setLayoutParams(p); 58 | } 59 | 60 | itemRoot.setOnClickListener(new View.OnClickListener() { 61 | @Override 62 | public void onClick(View v) { 63 | setClickToCenter(v); 64 | } 65 | }); 66 | } 67 | 68 | private void setClickToCenter(View view) { 69 | int[] location = new int[2]; 70 | view.getLocationOnScreen(location); 71 | int currentX = location[0]; 72 | int currentCenterX = (int) (currentX + p.width / 2 * 0.8f);//因为除了中间外的其他条目是被缩放为0.8的状态 73 | int recyclerViewCenterX = mRecyclerViewWidth / 2; 74 | int offX = currentCenterX - recyclerViewCenterX; 75 | 76 | if (Math.abs(offX) > p.width / 2 * 0.21f) {//因为已经居中的Item,已经被放大到比例1了 77 | recyclerView.smoothScrollBy(offX, 0); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/adapter/ItemCenterAdapter.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.stormdzh.androidcustomview.R; 9 | import com.stormdzh.androidcustomview.utils.DisplayUtils; 10 | import com.stormdzh.androidcustomview.widget.ItemCenterRecyclerView; 11 | import com.chad.library.adapter.base.BaseQuickAdapter; 12 | import com.chad.library.adapter.base.BaseViewHolder; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | *
18 |  *      @author : xiaoyao
19 |  *      e-mail  : xiaoyao@51vest.com
20 |  *      date    : 2018/05/07
21 |  *      desc    :
22 |  *      version : 1.0
23 |  * 
24 | */ 25 | 26 | public class ItemCenterAdapter extends BaseQuickAdapter { 27 | private ItemCenterRecyclerView recyclerView; 28 | private ViewGroup.MarginLayoutParams p; 29 | private int mRecyclerViewWidth; 30 | private List data; 31 | 32 | public ItemCenterAdapter(Context context, ItemCenterRecyclerView recyclerView, @Nullable List data) { 33 | super(R.layout.adapter_item_center, data); 34 | mRecyclerViewWidth = DisplayUtils.getDisplayWidth(context); 35 | this.data = data; 36 | this.recyclerView = recyclerView; 37 | } 38 | 39 | @Override 40 | protected void convert(BaseViewHolder helper, String item) { 41 | 42 | View itemRoot = helper.getView(R.id.item_root); 43 | p = (ViewGroup.MarginLayoutParams) itemRoot.getLayoutParams(); 44 | // 为了居中, 第一个条目leftMagrin、最后一个条目的rightMargin是(recyclerView宽度减去一个条目的宽度)/2 45 | int margin = (mRecyclerViewWidth - p.width) / 2; 46 | if (helper.getLayoutPosition() == 0) { 47 | p.leftMargin = margin; 48 | p.rightMargin = 0; 49 | itemRoot.setLayoutParams(p); 50 | } else if (helper.getLayoutPosition() == data.size() - 1) { 51 | p.leftMargin = 0; 52 | p.rightMargin = margin; 53 | itemRoot.setLayoutParams(p); 54 | } else { 55 | p.leftMargin = 0; 56 | p.rightMargin = 0; 57 | itemRoot.setLayoutParams(p); 58 | } 59 | 60 | itemRoot.setOnClickListener(new View.OnClickListener() { 61 | @Override 62 | public void onClick(View v) { 63 | setClickToCenter(v); 64 | } 65 | }); 66 | } 67 | 68 | private void setClickToCenter(View view) { 69 | int[] location = new int[2]; 70 | view.getLocationOnScreen(location); 71 | int currentX = location[0]; 72 | int currentCenterX = (int) (currentX + p.width / 2 * 0.8f);//因为除了中间外的其他条目是被缩放为0.8的状态 73 | int recyclerViewCenterX = mRecyclerViewWidth / 2; 74 | int offX = currentCenterX - recyclerViewCenterX; 75 | 76 | if (Math.abs(offX) > p.width / 2 * 0.21f) {//因为已经居中的Item,已经被放大到比例1了 77 | recyclerView.smoothScrollBy(offX, 0); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/adapter/MainAdapter.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.adapter; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | import com.stormdzh.androidcustomview.R; 6 | import com.stormdzh.androidcustomview.bean.TypeBean; 7 | import com.chad.library.adapter.base.BaseQuickAdapter; 8 | import com.chad.library.adapter.base.BaseViewHolder; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *
14 |  *      @author : xiaoyao
15 |  *      e-mail  : xiaoyao@51vest.com
16 |  *      date    : 2018/05/14
17 |  *      desc    :
18 |  *      version : 1.0
19 |  * 
20 | */ 21 | 22 | public class MainAdapter extends BaseQuickAdapter { 23 | 24 | public MainAdapter( @Nullable List data) { 25 | super(R.layout.adapter_item_main, data); 26 | } 27 | 28 | @Override 29 | protected void convert(BaseViewHolder helper, TypeBean item) { 30 | helper.setText(R.id.title_tv,item.getTitle()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/bean/CircleBean.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.bean; 2 | 3 | import android.graphics.PointF; 4 | 5 | /** 6 | * Created by allen on 2016/12/9. 7 | */ 8 | 9 | public class CircleBean { 10 | 11 | /** 12 | * 真实轨迹坐标点 13 | */ 14 | PointF p; 15 | /** 16 | * 起点坐标 17 | */ 18 | PointF p0; 19 | /** 20 | * 进入动画的控制点坐标 21 | */ 22 | PointF p1; 23 | /** 24 | * 到达中心点做坐标 25 | */ 26 | PointF p2; 27 | /** 28 | * 飞出动画控制点的坐标 29 | */ 30 | PointF p3; 31 | /** 32 | * 结束位置坐标 33 | */ 34 | PointF p4; 35 | 36 | /** 37 | * 小球半径 38 | */ 39 | private float radius; 40 | /** 41 | * 圆圈的透明度 42 | */ 43 | private int alpha; 44 | 45 | 46 | public CircleBean(PointF p0, PointF p1, PointF p2, PointF p3, PointF p4, float radius, int alpha) { 47 | this.p0 = p0; 48 | this.p1 = p1; 49 | this.p2 = p2; 50 | this.p3 = p3; 51 | this.p4 = p4; 52 | this.radius = radius; 53 | this.alpha = alpha; 54 | } 55 | 56 | public int getAlpha() { 57 | return alpha; 58 | } 59 | 60 | public void setAlpha(int alpha) { 61 | this.alpha = alpha; 62 | } 63 | 64 | public PointF getP4() { 65 | return p4; 66 | } 67 | 68 | public void setP4(PointF p4) { 69 | this.p4 = p4; 70 | } 71 | 72 | public PointF getP3() { 73 | return p3; 74 | } 75 | 76 | public void setP3(PointF p3) { 77 | this.p3 = p3; 78 | } 79 | 80 | public PointF getP2() { 81 | return p2; 82 | } 83 | 84 | public void setP2(PointF p2) { 85 | this.p2 = p2; 86 | } 87 | 88 | public PointF getP1() { 89 | return p1; 90 | } 91 | 92 | public void setP1(PointF p1) { 93 | this.p1 = p1; 94 | } 95 | 96 | public PointF getP0() { 97 | return p0; 98 | } 99 | 100 | public void setP0(PointF p0) { 101 | this.p0 = p0; 102 | } 103 | 104 | public PointF getP() { 105 | return p; 106 | } 107 | 108 | public void setP(PointF p) { 109 | this.p = p; 110 | } 111 | 112 | public float getRadius() { 113 | return radius; 114 | } 115 | 116 | public void setRadius(float radius) { 117 | this.radius = radius; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/bean/TypeBean.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.bean; 2 | 3 | /** 4 | *
 5 |  *      @author : xiaoyao
 6 |  *      e-mail  : xiaoyao@51vest.com
 7 |  *      date    : 2018/05/14
 8 |  *      desc    :
 9 |  *      version : 1.0
10 |  * 
11 | */ 12 | 13 | public class TypeBean { 14 | private String title; 15 | private int type; 16 | 17 | public TypeBean(String title, int type) { 18 | this.title = title; 19 | this.type = type; 20 | } 21 | 22 | public String getTitle() { 23 | return title; 24 | } 25 | 26 | public void setTitle(String title) { 27 | this.title = title; 28 | } 29 | 30 | public int getType() { 31 | return type; 32 | } 33 | 34 | public void setType(int type) { 35 | this.type = type; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/bean/UserBean.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.bean; 2 | 3 | /** 4 | *
 5 |  *      @author : xiaoyao
 6 |  *      e-mail  : xiaoyao@51vest.com
 7 |  *      date    : 2018/04/16
 8 |  *      desc    :
 9 |  *      version : 1.0
10 |  * 
11 | */ 12 | 13 | public class UserBean { 14 | private String userName; 15 | private String sortLetters=""; 16 | 17 | 18 | public String getUserName() { 19 | return userName; 20 | } 21 | 22 | public void setUserName(String userName) { 23 | this.userName = userName; 24 | } 25 | 26 | public String getSortLetters() { 27 | return sortLetters; 28 | } 29 | 30 | public void setSortLetters(String sortLetters) { 31 | this.sortLetters = sortLetters; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/bean/WaveBean.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.bean; 2 | 3 | /** 4 | * Created by allen on 2016/12/14. 5 | * 水波参数的实体 6 | */ 7 | 8 | public class WaveBean { 9 | 10 | private int waveLength; 11 | 12 | private int waveAmplitude; 13 | 14 | private int waveColor; 15 | 16 | private int waveType; 17 | 18 | private int duration; 19 | 20 | public int getWaveLength() { 21 | return waveLength; 22 | } 23 | 24 | public void setWaveLength(int waveLength) { 25 | this.waveLength = waveLength; 26 | } 27 | 28 | public int getWaveAmplitude() { 29 | return waveAmplitude; 30 | } 31 | 32 | public void setWaveAmplitude(int waveAmplitude) { 33 | this.waveAmplitude = waveAmplitude; 34 | } 35 | 36 | public int getWaveColor() { 37 | return waveColor; 38 | } 39 | 40 | public void setWaveColor(int waveColor) { 41 | this.waveColor = waveColor; 42 | } 43 | 44 | public int getWaveType() { 45 | return waveType; 46 | } 47 | 48 | public void setWaveType(int waveType) { 49 | this.waveType = waveType; 50 | } 51 | 52 | public int getDuration() { 53 | return duration; 54 | } 55 | 56 | public void setDuration(int duration) { 57 | this.duration = duration; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/tagview/TagActivity.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.tagview; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.support.v7.widget.GridLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | 8 | import com.stormdzh.androidcustomview.R; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class TagActivity extends AppCompatActivity { 14 | 15 | private RecyclerView tagRecyclerView; 16 | 17 | private static final int MAX = 9; 18 | private List tagBeanList = new ArrayList<>(); 19 | 20 | private TagAdapter tagAdapter; 21 | 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_tag); 27 | 28 | initView(); 29 | initData(); 30 | setRecyclerView(); 31 | } 32 | 33 | private void initData() { 34 | tagBeanList.add(new TagBean("1","准时")); 35 | tagBeanList.add(new TagBean("2","非常绅士")); 36 | tagBeanList.add(new TagBean("3","非常有礼貌")); 37 | tagBeanList.add(new TagBean("4","很会照顾女生")); 38 | tagBeanList.add(new TagBean("5","我的男神是个大暖男哦")); 39 | tagBeanList.add(new TagBean("6","谈吐优雅")); 40 | tagBeanList.add(new TagBean("7","送我到楼下")); 41 | tagBeanList.add(new TagBean("9","迟到")); 42 | tagBeanList.add(new TagBean("10","态度恶劣")); 43 | tagBeanList.add(new TagBean("11","有不礼貌行为")); 44 | tagBeanList.add(new TagBean("12","有侮辱性语言有暴力倾向")); 45 | tagBeanList.add(new TagBean("13","人身攻击")); 46 | tagBeanList.add(new TagBean("14","临时改变行程")); 47 | tagBeanList.add(new TagBean("15","客户迟到并无理要求延长约会时间")); 48 | } 49 | 50 | private void setRecyclerView() { 51 | GridLayoutManager layoutManage = new GridLayoutManager(this, 2); 52 | layoutManage.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 53 | @Override 54 | public int getSpanSize(int position) { 55 | if (tagBeanList.get(position).getTag_name().length()>MAX) 56 | return 2; 57 | return 1; 58 | } 59 | }); 60 | tagRecyclerView.setLayoutManager(layoutManage); 61 | tagAdapter = new TagAdapter(tagBeanList); 62 | tagRecyclerView.setAdapter(tagAdapter); 63 | 64 | } 65 | 66 | private void initView() { 67 | tagRecyclerView = (RecyclerView) findViewById(R.id.tag_rv); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/tagview/TagAdapter.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.tagview; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | 10 | import com.stormdzh.androidcustomview.R; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by Allen on 2017/4/14. 17 | * 18 | * 评论页面的适配器 19 | */ 20 | 21 | public class TagAdapter extends RecyclerView.Adapter { 22 | 23 | private List tagList; 24 | 25 | private boolean isSelected = false; 26 | 27 | private List selectList; 28 | 29 | public TagAdapter(List tagList) { 30 | this.tagList = tagList; 31 | selectList = new ArrayList<>(); 32 | } 33 | 34 | @Override 35 | public TagAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 36 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.tag_layout, parent, false); 37 | ViewHolder vh = new ViewHolder(view); 38 | return vh; 39 | } 40 | 41 | @Override 42 | public void onBindViewHolder(final TagAdapter.ViewHolder holder, final int position) { 43 | holder.mTextView.setText(tagList.get(position).getTag_name()); 44 | holder.itemView.setTag(tagList.get(position)); 45 | holder.mTextView.setOnClickListener(new View.OnClickListener() { 46 | @Override 47 | public void onClick(View v) { 48 | isSelected = !holder.mTextView.isSelected(); 49 | if (isSelected) { 50 | holder.mTextView.setSelected(true); 51 | holder.mTextView.setBackgroundResource(R.drawable.tag_checked_bg); 52 | selectList.add(tagList.get(position)); 53 | } else { 54 | holder.mTextView.setSelected(false); 55 | holder.mTextView.setBackgroundResource(R.drawable.tag_normal_bg); 56 | selectList.remove(tagList.get(position)); 57 | } 58 | } 59 | }); 60 | 61 | } 62 | 63 | @Override 64 | public int getItemCount() { 65 | return tagList.size(); 66 | } 67 | 68 | public class ViewHolder extends RecyclerView.ViewHolder { 69 | public TextView mTextView; 70 | 71 | public ViewHolder(View view) { 72 | super(view); 73 | mTextView = (TextView) view.findViewById(R.id.tag_tv); 74 | } 75 | } 76 | 77 | public List getSelectData(){ 78 | return selectList; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/tagview/TagBean.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.tagview; 2 | 3 | /** 4 | * Created by Allen on 2017/4/15. 5 | * 6 | */ 7 | 8 | public class TagBean { 9 | 10 | public TagBean(String tag_id, String tag_name) { 11 | this.tag_id = tag_id; 12 | this.tag_name = tag_name; 13 | } 14 | 15 | /** 16 | * tag_id : 55 17 | * tag_name : 准时 18 | */ 19 | 20 | 21 | private String tag_id; 22 | private String tag_name; 23 | 24 | public String getTag_id() { 25 | return tag_id; 26 | } 27 | 28 | public void setTag_id(String tag_id) { 29 | this.tag_id = tag_id; 30 | } 31 | 32 | public String getTag_name() { 33 | return tag_name; 34 | } 35 | 36 | public void setTag_name(String tag_name) { 37 | this.tag_name = tag_name; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/tagview/recyclerview.md: -------------------------------------------------------------------------------- 1 | ###一、需求解析 2 | 1、先说下项目需求,不管是好评还是差评下边的Tag标签有不同的展示类型,有的字数多的会单独占一行处理(这边其实也可以扩充,比如说两三个字的可以一行显示三个Tag标签),第一眼看到这个需求准备使用网上的开源库TagLayout去实现,但是尝试了一下后发现其实他们实现的效果同项目要的效果还是有蛮大差距的,可以看到效果图里边是要求文字是居中对齐的,左右对称的。 3 | 2、想到使用GridView实现这个功能,定义adapter去实现没问题,问题是什么时候显示一行什么时候显示两行三行并不能确定,毕竟有时候服务端返回的没有类型标示只有tag_name和tag_id,你要根据什么设置类型呐,而且自从recyclerview之后现在要是还用GridView的话岂不是太落伍了。下边就重点介绍一下使用recyclerview实现如图效果。 4 | ###二、功能实现 5 | 我们知道recyclerview实现GridView效果只需配置一下参数就行了 6 | 7 | GridLayoutManager layoutManage = new GridLayoutManager(getContext(), 2); 8 | recycerView.setLayoutManager(layoutManage); 9 | 10 | 可以看到GridLayoutManager需要传递两个参数,一个是上下文对象,另一个是一行显示几列的参数常量,既然这个常量可以指定那么是不是这个值可以去控制呐,答案当然是yes 11 | 12 | 我们会注意到GridLayoutManager里边有个setSpanSizeLookup方法,本篇的重点就是这个方法(这个方法具体意义大家可以网上搜索,会有很多相关介绍,以及通过它实现一些复杂的布局,再次不做过多讨论) 13 | 14 | layoutManage.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 15 | @Override 16 | public int getSpanSize(int position) { 17 | return 0; 18 | } 19 | }); 20 | 21 | 其实getSpanSize返回值就是控制每行有几列的,根据这个思路我们不妨试试。因为recyclerview填充数据是根据adapter实现的,我们就把给adapter的数据源同样在setSpanSizeLookup这个方法里边判断一下不就行了吗? 22 | 根据这个思路于是有了下面的代码 23 | 24 | 25 | /** 26 | * 如果单个item显示的字数大于指定某个值就显示一列 默认2列 27 | */ 28 | 29 | //设置item数据大于多少字只显示一行 默认 超过九个字的程度只显示一列 30 | 31 | private static final int MAX = 9; 32 | 33 | 34 | private int setSpanSize(int position, List listEntities) { 35 | int count; 36 | if (listEntities.get(position).getTag_name().length() > MAX) { 37 | count = 2; 38 | } else { 39 | count = 1; 40 | } 41 | 42 | return count; 43 | } 44 | 45 | 46 | layoutManage.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 47 | @Override 48 | public int getSpanSize(int position) { 49 | return setSpanSize(position,list); 50 | } 51 | }); 52 | 53 | 54 | 核心代码就这么多,我们可以根据自己的需求随意定制样式 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/utils/BezierUtil.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.utils; 2 | 3 | import android.graphics.PointF; 4 | 5 | /** 6 | * Created by allen on 2016/12/15. 7 | *

8 | * 贝塞尔曲线计算工具类 9 | */ 10 | 11 | public class BezierUtil { 12 | 13 | 14 | /** 15 | * 二阶贝塞尔曲线 16 | * B(t) = Po*(1-t)^2 + 2*p1*t*(1-t)+t^2*p2 17 | * 18 | * @param t 曲线长度比例 19 | * @param p0 起始点 20 | * @param p1 控制点 21 | * @param p2 终止点 22 | * @return t对应的点 23 | */ 24 | public static PointF CalculateBezierPointForQuadratic(float t, PointF p0, PointF p1, PointF p2) { 25 | PointF point = new PointF(); 26 | float temp = 1 - t; 27 | // point.x = temp * temp * p0.x + 2 * t * temp * p1.x + t * t * p2.x; 28 | // point.y = temp * temp * p0.y + 2 * t * temp * p1.y + t * t * p2.y; 29 | point.x = (float) (Math.pow(temp, 2) * p0.x + 2 * t * temp * p1.x + Math.pow(t, 2) * p2.x); 30 | point.y = (float) (Math.pow(temp, 2) * p0.y + 2 * t * temp * p1.y + Math.pow(t, 2) * p2.y); 31 | return point; 32 | } 33 | 34 | /** 35 | * 三 36 | * 阶贝塞尔曲线 37 | * B(t) = Po*(1-t)^3 + 3*p1*t*(1-t)^2+3*p2*t^2*(1-t)+p3*t^3, 38 | * 39 | * @param t 曲线长度比例 40 | * @param p0 起始点 41 | * @param p1 控制点1 42 | * @param p2 控制点2 43 | * @param p3 终止点 44 | * @return t对应的点 45 | */ 46 | public static PointF CalculateBezierPointForCubic(float t, PointF p0, PointF p1, PointF p2, PointF p3) { 47 | PointF point = new PointF(); 48 | float temp = 1 - t; 49 | // point.x = p0.x * temp * temp * temp + 3 * p1.x * t * temp * temp + 3 * p2.x * t * t * temp + p3.x * t * t * t; 50 | // point.y = p0.y * temp * temp * temp + 3 * p1.y * t * temp * temp + 3 * p2.y * t * t * temp + p3.y * t * t * t; 51 | point.x = (float) (p0.x * Math.pow(temp, 3) + 3 * p1.x * t * Math.pow(temp, 2) + 3 * p2.x * Math.pow(t, 2) * temp + p3.x * Math.pow(t, 3)); 52 | point.y = (float) (p0.y * Math.pow(temp, 3) + 3 * p1.y * t * Math.pow(temp, 2) + 3 * p2.y * Math.pow(t, 2) * temp + p3.y * Math.pow(t, 3)); 53 | return point; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/utils/DisplayUtils.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.utils; 2 | 3 | import android.content.Context; 4 | import android.util.DisplayMetrics; 5 | import android.view.WindowManager; 6 | 7 | /** 8 | * 与屏幕信息有关的类,包括屏幕的长宽、分辨率、长度换算 9 | * 10 | */ 11 | public class DisplayUtils { 12 | 13 | 14 | /** 15 | * 获取屏幕分辨率 16 | * @param context 17 | * @return 18 | */ 19 | public static int[] getScreenDispaly(Context context) { 20 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 21 | int width = windowManager.getDefaultDisplay().getWidth();// 手机屏幕的宽度 22 | int height = windowManager.getDefaultDisplay().getHeight();// 手机屏幕的高度 23 | int result[] = { width, height }; 24 | return result; 25 | } 26 | 27 | /** 获取屏幕宽度 */ 28 | public static int getDisplayWidth(Context context) { 29 | if (context != null) { 30 | DisplayMetrics dm = context.getResources().getDisplayMetrics(); 31 | int w_screen = dm.widthPixels; 32 | // int h_screen = dm.heightPixels; 33 | return w_screen; 34 | } 35 | return 720; 36 | } 37 | 38 | /** 获取屏幕高度 */ 39 | public static int getDisplayHight(Context context) { 40 | if (context != null) { 41 | DisplayMetrics dm = context.getResources().getDisplayMetrics(); 42 | // int w_screen = dm.widthPixels; 43 | int h_screen = dm.heightPixels; 44 | return h_screen; 45 | } 46 | return 1280; 47 | } 48 | 49 | public static int dip2px(Context context, float dipValue) { 50 | final float scale = context.getResources().getDisplayMetrics().density; 51 | return (int) (dipValue * scale + 0.5f); 52 | } 53 | 54 | public static int px2dip(Context context, float pxValue) { 55 | final float scale = context.getResources().getDisplayMetrics().density; 56 | return (int) (pxValue / scale + 0.5f); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/utils/FingerprintUtil.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.utils; 2 | 3 | import android.app.KeyguardManager; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.os.Bundle; 7 | import android.support.v4.hardware.fingerprint.FingerprintManagerCompat; 8 | import android.support.v4.os.CancellationSignal; 9 | 10 | /** 11 | * Created by xiaoyao on 2017/9/14. 12 | * 指纹识别工具类 13 | */ 14 | 15 | public class FingerprintUtil { 16 | 17 | private static CancellationSignal cancellationSignal; 18 | 19 | public static void callFingerPrint(Context context, final OnCallBackListener listener) { 20 | 21 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 22 | return; 23 | } 24 | FingerprintManagerCompat managerCompat = FingerprintManagerCompat.from(context); 25 | if (!managerCompat.isHardwareDetected()) { //判断设备是否支持 26 | if (listener != null) 27 | listener.onSupportFailed(); 28 | return; 29 | } 30 | 31 | KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); 32 | if (!keyguardManager.isKeyguardSecure()) {//判断设备是否处于安全保护中 33 | if (listener != null) 34 | listener.onInsecurity(); 35 | return; 36 | } 37 | 38 | if (!managerCompat.hasEnrolledFingerprints()) { //判断设备是否已经注册过指纹 39 | if (listener != null) 40 | listener.onEnrollFailed(); //未注册 41 | return; 42 | } 43 | 44 | if (listener != null) 45 | listener.onAuthenticationStart(); //开始指纹识别 46 | 47 | cancellationSignal = new CancellationSignal(); //必须重新实例化,否则cancel 过一次就不能再使用了 48 | 49 | managerCompat.authenticate(null, 0, cancellationSignal, new FingerprintManagerCompat.AuthenticationCallback() { 50 | // 当出现错误的时候回调此函数,比如多次尝试都失败了的时候,errString是错误信息,比如华为的提示就是:尝试次数过多,请稍后再试。 51 | @Override 52 | public void onAuthenticationError(int errMsgId, CharSequence errString) { 53 | if (listener != null) 54 | listener.onAuthenticationError(errMsgId, errString); 55 | } 56 | 57 | // 当指纹验证失败的时候会回调此函数,失败之后允许多次尝试,失败次数过多会停止响应一段时间然后再停止sensor的工作 58 | @Override 59 | public void onAuthenticationFailed() { 60 | if (listener != null) 61 | listener.onAuthenticationFailed(); 62 | } 63 | 64 | @Override 65 | public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { 66 | if (listener != null) 67 | listener.onAuthenticationHelp(helpMsgId, helpString); 68 | } 69 | 70 | // 当验证的指纹成功时会回调此函数,然后不再监听指纹sensor 71 | @Override 72 | public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) { 73 | if (listener != null) 74 | listener.onAuthenticationSucceeded(result); 75 | } 76 | }, null); 77 | 78 | } 79 | 80 | public interface OnCallBackListener { 81 | void onSupportFailed(); 82 | 83 | void onInsecurity(); 84 | 85 | void onEnrollFailed(); 86 | 87 | void onAuthenticationStart(); 88 | 89 | void onAuthenticationError(int errMsgId, CharSequence errString); 90 | 91 | void onAuthenticationFailed(); 92 | 93 | void onAuthenticationHelp(int helpMsgId, CharSequence helpString); 94 | 95 | void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result); 96 | } 97 | 98 | public static void cancel() { 99 | if (cancellationSignal != null) 100 | cancellationSignal.cancel(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/utils/PinyinComparator.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.utils; 2 | 3 | 4 | import com.stormdzh.androidcustomview.bean.UserBean; 5 | 6 | import java.util.Comparator; 7 | 8 | public class PinyinComparator implements Comparator { 9 | 10 | @Override 11 | public int compare(UserBean o1, UserBean o2) { 12 | if (o1.getSortLetters().equals("@") 13 | || o2.getSortLetters().equals("#")) { 14 | return -1; 15 | } else if (o1.getSortLetters().equals("#") 16 | || o2.getSortLetters().equals("@")) { 17 | return 1; 18 | } else { 19 | return o1.getSortLetters().compareTo(o2.getSortLetters()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/utils/mediacamera/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.utils.mediacamera; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | import java.io.File; 6 | 7 | public class FileUtils { 8 | /** 9 | * sd卡的根目录 10 | */ 11 | private static String mSdRootPath = Environment.getExternalStorageDirectory().getPath(); 12 | /** 13 | * 手机的缓存根目录 14 | */ 15 | private static String mDataRootPath = null; 16 | /** 17 | * 保存Image的目录名 18 | */ 19 | private final static String FOLDER_NAME = "/ffmpeg"; 20 | 21 | public final static String IMAGE_NAME = "/cache"; 22 | 23 | public FileUtils(Context context){ 24 | mDataRootPath = context.getCacheDir().getPath(); 25 | makeAppDir(); 26 | } 27 | 28 | public String makeAppDir(){ 29 | String path = getStorageDirectory(); 30 | File folderFile = new File(path); 31 | if(!folderFile.exists()){ 32 | folderFile.mkdir(); 33 | } 34 | path = path + IMAGE_NAME; 35 | folderFile = new File(path); 36 | if(!folderFile.exists()){ 37 | folderFile.mkdir(); 38 | } 39 | return path; 40 | } 41 | 42 | /** 43 | * 获取储存Image的目录 44 | * @return 45 | */ 46 | public String getStorageDirectory(){ 47 | String localPath = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ? 48 | mSdRootPath + FOLDER_NAME : mDataRootPath + FOLDER_NAME; 49 | File folderFile = new File(localPath); 50 | if(!folderFile.exists()){ 51 | folderFile.mkdir(); 52 | } 53 | return localPath; 54 | } 55 | 56 | public String getMediaVideoPath(){ 57 | String directory = getStorageDirectory(); 58 | directory += "/video"; 59 | File file = new File(directory); 60 | if(!file.exists()){ 61 | file.mkdir(); 62 | } 63 | return directory; 64 | } 65 | 66 | /** 67 | * 删除文件 68 | */ 69 | public void deleteFile(String deletePath,String videoPath) { 70 | File file = new File(deletePath); 71 | if (file.exists()) { 72 | File[] files = file.listFiles(); 73 | for (File f : files) { 74 | if(f.isDirectory()){ 75 | if(f.listFiles().length==0){ 76 | f.delete(); 77 | }else{ 78 | deleteFile(f.getAbsolutePath(),videoPath); 79 | } 80 | }else if(!f.getAbsolutePath().equals(videoPath)){ 81 | f.delete(); 82 | } 83 | } 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/utils/mediacamera/helper/PermissionHelper.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.utils.mediacamera.helper; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageManager; 5 | import android.support.v4.content.ContextCompat; 6 | 7 | /** 8 | * 检查权限的工具类 9 | *

10 | * Created by dzh on 2019/8/2. 11 | */ 12 | public class PermissionHelper { 13 | private final Context mContext; 14 | 15 | public PermissionHelper(Context context) { 16 | mContext = context.getApplicationContext(); 17 | } 18 | 19 | // 判断权限集合 20 | public boolean lacksPermissions(String... permissions) { 21 | for (String permission : permissions) { 22 | if (lacksPermission(permission)) { 23 | return true; 24 | } 25 | } 26 | return false; 27 | } 28 | 29 | // 判断是否缺少权限 30 | private boolean lacksPermission(String permission) { 31 | return ContextCompat.checkSelfPermission(mContext, permission) == 32 | PackageManager.PERMISSION_DENIED; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/BaseView.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Paint; 5 | import android.support.annotation.Nullable; 6 | import android.util.AttributeSet; 7 | import android.util.TypedValue; 8 | import android.view.View; 9 | 10 | /** 11 | * Created by xiaoyao on 2017/5/23. 12 | */ 13 | 14 | public class BaseView extends View { 15 | 16 | public int mWidth; 17 | public int mHeight; 18 | public int mViewHeight; 19 | 20 | 21 | public BaseView(Context context) { 22 | this(context, null); 23 | 24 | mViewHeight = dp2px(45); 25 | } 26 | 27 | public BaseView(Context context, @Nullable AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | 31 | @Override 32 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 33 | int widthMode = MeasureSpec.getMode(widthMeasureSpec); 34 | int width = MeasureSpec.getSize(widthMeasureSpec); 35 | 36 | int heightMode = MeasureSpec.getMode(heightMeasureSpec); 37 | int height = MeasureSpec.getSize(heightMeasureSpec); 38 | 39 | setMeasuredDimension(measureWidth(widthMode, width), measureHeight(heightMode, height)); 40 | } 41 | 42 | /** 43 | * 测量宽度 44 | * 45 | * @param mode 46 | * @param width 47 | * @return 48 | */ 49 | private int measureWidth(int mode, int width) { 50 | switch (mode) { 51 | case MeasureSpec.UNSPECIFIED: 52 | case MeasureSpec.AT_MOST: 53 | break; 54 | case MeasureSpec.EXACTLY: 55 | mWidth = width; 56 | break; 57 | } 58 | return mWidth; 59 | } 60 | 61 | /** 62 | * 测量高度 63 | * 64 | * @param mode 65 | * @param height 66 | * @return 67 | */ 68 | private int measureHeight(int mode, int height) { 69 | switch (mode) { 70 | case MeasureSpec.UNSPECIFIED: 71 | case MeasureSpec.AT_MOST: 72 | mHeight = mViewHeight; 73 | break; 74 | case MeasureSpec.EXACTLY: 75 | mHeight = height; 76 | break; 77 | } 78 | return mHeight; 79 | } 80 | 81 | /** 82 | * 统一处理paint 83 | * @param strokeWidth 84 | * @param color 85 | * @param style 86 | * @return 87 | */ 88 | public Paint getPaint(int strokeWidth, int color, Paint.Style style) { 89 | Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 90 | paint.setStrokeWidth(strokeWidth); 91 | paint.setColor(color); 92 | paint.setAntiAlias(true); 93 | paint.setStrokeCap(Paint.Cap.ROUND); 94 | paint.setStyle(style); 95 | return paint; 96 | } 97 | 98 | 99 | /** 100 | * dp 2 px 101 | * 102 | * @param dpVal 103 | */ 104 | protected int dp2px(int dpVal) { 105 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 106 | dpVal, getResources().getDisplayMetrics()); 107 | } 108 | 109 | /** 110 | * sp 2 px 111 | * 112 | * @param spVal 113 | * @return 114 | */ 115 | protected int sp2px(int spVal) { 116 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 117 | spVal, getResources().getDisplayMetrics()); 118 | 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/DividerItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.view.View; 11 | 12 | /** 13 | *

 14 |  *      @author : xiaoyao
 15 |  *      e-mail  : xiaoyao@51vest.com
 16 |  *      date    : 2018/02/05
 17 |  *      desc    : recyclerview的分割线
 18 |  *      version : 1.0
 19 |  * 
20 | */ 21 | 22 | public class DividerItemDecoration extends RecyclerView.ItemDecoration { 23 | private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; 24 | 25 | public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; 26 | 27 | public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; 28 | 29 | 30 | private Drawable mDivider; 31 | 32 | private int mOrientation; 33 | 34 | private Context context; 35 | 36 | public DividerItemDecoration(Context context, int orientation) { 37 | final TypedArray a = context.obtainStyledAttributes(ATTRS); 38 | mDivider = a.getDrawable(0); 39 | this.context = context; 40 | a.recycle(); 41 | setOrientation(orientation); 42 | } 43 | 44 | public void setOrientation(int orientation) { 45 | if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { 46 | throw new IllegalArgumentException("invalid orientation"); 47 | } 48 | mOrientation = orientation; 49 | } 50 | 51 | @Override 52 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { 53 | super.onDraw(c, parent, state); 54 | if (mOrientation == VERTICAL_LIST) { 55 | drawVertical(c, parent); 56 | } else { 57 | drawHorizontal(c, parent); 58 | } 59 | } 60 | 61 | public void drawVertical(Canvas c, RecyclerView parent) { 62 | final int left = parent.getPaddingLeft() + dip2px(context, 0); 63 | final int right = parent.getWidth() - parent.getPaddingRight() - dip2px(context, 0); 64 | 65 | final int childCount = parent.getChildCount(); 66 | 67 | for (int i = 0; i < childCount; i++) { 68 | final View child = parent.getChildAt(i); 69 | android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView( 70 | parent.getContext()); 71 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 72 | .getLayoutParams(); 73 | final int top = child.getBottom() + params.bottomMargin; 74 | final int bottom = top + mDivider.getIntrinsicHeight(); 75 | mDivider.setBounds(left, top, right, bottom); 76 | mDivider.draw(c); 77 | } 78 | } 79 | 80 | public void drawHorizontal(Canvas c, RecyclerView parent) { 81 | final int top = parent.getPaddingTop(); 82 | final int bottom = parent.getHeight() - parent.getPaddingBottom(); 83 | 84 | final int childCount = parent.getChildCount(); 85 | for (int i = 0; i < childCount; i++) { 86 | final View child = parent.getChildAt(i); 87 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 88 | .getLayoutParams(); 89 | final int left = child.getRight() + params.rightMargin; 90 | final int right = left + mDivider.getIntrinsicHeight(); 91 | mDivider.setBounds(left, top, right, bottom); 92 | mDivider.draw(c); 93 | } 94 | } 95 | 96 | @Override 97 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 98 | super.getItemOffsets(outRect, view, parent, state); 99 | if (mOrientation == VERTICAL_LIST) { 100 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); 101 | } else { 102 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); 103 | } 104 | } 105 | 106 | /** 107 | * 单位转换工具类 108 | * 109 | * @param context 上下文对象 110 | * @param dipValue 值 111 | * @return 返回值 112 | */ 113 | private int dip2px(Context context, float dipValue) { 114 | final float scale = context.getResources().getDisplayMetrics().density; 115 | return (int) (dipValue * scale + 0.5f); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/IndexView.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.util.AttributeSet; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | /** 12 | * Created by allen on 2016/10/26. 13 | */ 14 | 15 | public class IndexView extends View { 16 | 17 | private Context mContext; 18 | private TextView mShowTextDialog; 19 | 20 | 21 | private Paint mPaint; 22 | 23 | private int mWidth; 24 | private int mHeight; 25 | 26 | private int mCellWidth; 27 | private int mCellHeight; 28 | 29 | private int mWordSize; 30 | private int mwordColor; 31 | private int mChoose = -1;// 选中 32 | 33 | 34 | private int GRAY = 0xFFe8e8e8; 35 | private int DEFAULT_TEXT_COLOR = 0xFF999999; 36 | 37 | private static final String[] WORDS = new String[]{ 38 | "↑", "☆", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", 39 | "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", 40 | "X", "Y", "Z", "#" 41 | }; 42 | 43 | private OnTouchingLetterChangedListener mOnTouchingLetterChangedListener; 44 | 45 | public IndexView(Context context) { 46 | this(context, null); 47 | } 48 | 49 | public IndexView(Context context, AttributeSet attrs) { 50 | this(context, attrs, 0); 51 | } 52 | 53 | public IndexView(Context context, AttributeSet attrs, int defStyleAttr) { 54 | super(context, attrs, defStyleAttr); 55 | mContext = context; 56 | mWordSize = sp2px(mContext, 12); 57 | mwordColor = 0; 58 | initPaint(); 59 | } 60 | 61 | 62 | public void setShowTextDialog(TextView textDialog) { 63 | this.mShowTextDialog = textDialog; 64 | } 65 | 66 | private void initPaint() { 67 | mPaint = new Paint(); 68 | mPaint.setColor(DEFAULT_TEXT_COLOR); 69 | mPaint.setAntiAlias(true); 70 | mPaint.setTextSize(mWordSize); 71 | } 72 | 73 | @Override 74 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 75 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 76 | mWidth = getMeasuredWidth(); 77 | mHeight = getMeasuredHeight(); 78 | 79 | mCellHeight = mHeight / WORDS.length; 80 | } 81 | 82 | @Override 83 | protected void onDraw(Canvas canvas) { 84 | super.onDraw(canvas); 85 | for (int i = 0; i < WORDS.length; i++) { 86 | float xPos = mWidth / 2 - mPaint.measureText(WORDS[i]) / 2; 87 | float yPos = mCellHeight * i + mCellHeight; 88 | canvas.drawText(WORDS[i], xPos, yPos, mPaint); 89 | } 90 | 91 | } 92 | 93 | @Override 94 | public boolean onTouchEvent(MotionEvent event) { 95 | final int action = event.getAction(); 96 | final float y = event.getY();// 点击y坐标 97 | final int oldChoose = mChoose; 98 | final int c = (int) (y / getHeight() * WORDS.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数. 99 | 100 | 101 | switch (action) { 102 | case MotionEvent.ACTION_UP: 103 | setBackgroundColor(0x00000000); 104 | mChoose = -1;// 105 | invalidate(); 106 | if (mShowTextDialog != null) { 107 | mShowTextDialog.setVisibility(View.INVISIBLE); 108 | } 109 | break; 110 | 111 | default: 112 | setBackgroundColor(GRAY); 113 | if (oldChoose != c) { 114 | if (c >= 0 && c < WORDS.length) { 115 | if (mOnTouchingLetterChangedListener != null) { 116 | mOnTouchingLetterChangedListener.onTouchingLetterChanged(WORDS[c]); 117 | } 118 | if (mShowTextDialog != null) { 119 | mShowTextDialog.setText(WORDS[c]); 120 | mShowTextDialog.setVisibility(View.VISIBLE); 121 | } 122 | 123 | mChoose = c; 124 | invalidate(); 125 | } 126 | } 127 | 128 | break; 129 | } 130 | return true; 131 | } 132 | 133 | 134 | public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener letterChangedListener) { 135 | mOnTouchingLetterChangedListener = letterChangedListener; 136 | 137 | } 138 | 139 | public interface OnTouchingLetterChangedListener { 140 | void onTouchingLetterChanged(String letter); 141 | } 142 | 143 | /** 144 | * 文字字体大小sp转换px 145 | * 146 | * @param context 上下文对象 147 | * @param spValue sp的值 148 | * @return 返回值 149 | */ 150 | public int sp2px(Context context, float spValue) { 151 | final float scale = context.getResources().getDisplayMetrics().scaledDensity; 152 | return (int) (spValue * scale + 0.5f); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/ItemCenterRecyclerView.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.AttributeSet; 7 | import android.util.Log; 8 | import android.view.View; 9 | 10 | /** 11 | *
12 |  *      @author : xiaoyao
13 |  *      e-mail  : xiaoyao@51vest.com
14 |  *      date    : 2018/05/07
15 |  *      desc    :
16 |  *      version : 1.0
17 |  * 
18 | */ 19 | 20 | public class ItemCenterRecyclerView extends RecyclerView { 21 | 22 | 23 | public ItemCenterRecyclerView(Context context) { 24 | super(context); 25 | } 26 | 27 | public ItemCenterRecyclerView(Context context, @Nullable AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | 31 | public ItemCenterRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { 32 | super(context, attrs, defStyle); 33 | } 34 | 35 | @Override 36 | public void onScrolled(int dx, int dy) { 37 | super.onScrolled(dx, dy); 38 | 39 | int childCount = getChildCount(); 40 | Log.e("allen", childCount + ""); 41 | 42 | int[] location = new int[2]; 43 | for (int i = 0; i < childCount; i++) { 44 | View v = getChildAt(i); 45 | v.getLocationOnScreen(location); 46 | 47 | int recyclerViewCenterX = getLeft() + getWidth() / 2; 48 | int itemCenterX = location[0] + v.getWidth() / 2; 49 | 50 | //★两边的图片缩放比例 51 | float scale = 0.8f; 52 | //★某个item中心X坐标距recyclerView中心X坐标的偏移量 53 | int offX = Math.abs(itemCenterX - recyclerViewCenterX); 54 | //★在一个item的宽度范围内,item从1缩放至scale,那么改变了(1-scale), 55 | //从下列公式算出随着offX变化,item的变化缩放百分比 56 | float percent = offX * (1 - scale) / v.getWidth(); 57 | //★取反哟 58 | float interpretateScale = 1 - percent; 59 | //这个if不走的话,得到的是多级渐变模式 60 | if (interpretateScale < scale) { 61 | interpretateScale = scale; 62 | } 63 | v.setScaleX((interpretateScale)); 64 | v.setScaleY((interpretateScale)); 65 | } 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/SurfaceBubbleView.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.PixelFormat; 8 | import android.graphics.PorterDuff; 9 | import android.util.AttributeSet; 10 | import android.util.Log; 11 | import android.view.SurfaceHolder; 12 | import android.view.SurfaceView; 13 | 14 | /** 15 | * 使用参考:https://blog.csdn.net/qq_38261174/article/details/80057833 16 | * 17 | * @Description: 描述 18 | * @Author: dzh 19 | * @CreateDate: 2019/7/18 9:57 AM 20 | */ 21 | public class SurfaceBubbleView extends SurfaceView implements SurfaceHolder.Callback { 22 | 23 | private SurfaceHolder holder; 24 | private UpdateViewThread updatethread; 25 | private boolean hasSurface; 26 | private Paint mPain; 27 | 28 | public SurfaceBubbleView(Context context) { 29 | this(context, null); 30 | } 31 | 32 | public SurfaceBubbleView(Context context, AttributeSet attrs) { 33 | this(context, attrs, 0); 34 | } 35 | 36 | public SurfaceBubbleView(Context context, AttributeSet attrs, int defStyleAttr) { 37 | super(context, attrs, defStyleAttr); 38 | init(); 39 | } 40 | 41 | private void init() { 42 | holder = getHolder(); 43 | holder.addCallback(this);//以自身作为callback,回调方法 44 | 45 | // 绘制透明 46 | setZOrderOnTop(true); 47 | getHolder().setFormat(PixelFormat.TRANSLUCENT); 48 | 49 | mPain = new Paint(); 50 | mPain.setColor(Color.RED); 51 | } 52 | 53 | public void resume() { 54 | //创建和启动 图片更新线程 55 | if (updatethread == null) { 56 | updatethread = new UpdateViewThread(); 57 | if (hasSurface == true) { 58 | updatethread.start(); 59 | } 60 | } 61 | } 62 | 63 | public void pause() { 64 | //停止 图像更新线程 65 | if (updatethread != null) { 66 | updatethread.requestExitAndWait(); 67 | updatethread = null; 68 | } 69 | } 70 | 71 | @Override 72 | public void surfaceCreated(SurfaceHolder surfaceHolder) { 73 | hasSurface = true; 74 | resume(); //开启线程更新 75 | } 76 | 77 | @Override 78 | public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { 79 | if (updatethread != null) { 80 | updatethread.onWindowResize(width, height); 81 | } 82 | 83 | } 84 | 85 | @Override 86 | public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 87 | hasSurface = false; 88 | pause(); //停止线程更新 89 | } 90 | 91 | 92 | class UpdateViewThread extends Thread { 93 | 94 | //定义图像是否更新完成的标志 95 | private boolean done; 96 | 97 | public UpdateViewThread() { 98 | super(); 99 | done = false; 100 | 101 | } 102 | 103 | @Override 104 | public void run() { 105 | Log.i("test", "run"); 106 | SurfaceHolder surfaceholder = holder; 107 | 108 | while (!done) { 109 | Canvas canvas = surfaceholder.lockCanvas();//锁定surfaceview,准备绘制 110 | canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); 111 | 112 | 113 | canvas.drawText("你好呀", 100, 100, mPain); 114 | 115 | surfaceholder.unlockCanvasAndPost(canvas);//解锁canvas,渲染绘制图像 116 | } 117 | 118 | 119 | //循环绘制,直到线程停止 120 | // while (!done) { 121 | // Canvas canvas = surfaceholder.lockCanvas();//锁定surfaceview,准备绘制 122 | // //绘制背景 123 | // canvas.drawBitmap(back, 0, 0, null); 124 | // //鱼游出屏幕外,重新初始化鱼的位置 125 | // if (fishx < 0) { 126 | // fishx = 778; 127 | // fishy = 500; 128 | // fishAngle = new Random().nextInt(60); 129 | // } 130 | // if (fishy < 0) { 131 | // fishx = 778; 132 | // fishy = 500; 133 | // fishAngle = new Random().nextInt(60); 134 | // } 135 | // //用matrix控制鱼的旋转角度和位置 136 | // matrix.reset(); 137 | // matrix.setRotate(fishAngle);//下面的位置计算看图片的解释如下: 138 | // matrix.postTranslate(fishx -= fishSpeed * Math.cos(Math.toRadians(fishAngle)), fishy -= fishSpeed * Math.sin(Math.toRadians(fishAngle))); 139 | // canvas.drawBitmap(fishs[fishIndex++ % fishs.length], matrix, null); 140 | // surfaceholder.unlockCanvasAndPost(canvas);//解锁canvas,渲染绘制图像 141 | // try { 142 | // Thread.sleep(60); 143 | // } catch (Exception e) { 144 | // e.printStackTrace(); 145 | // } 146 | // 147 | // } 148 | } 149 | 150 | 151 | public void requestExitAndWait() { 152 | //将绘制线程 标记为完成 ,并合并到主线程中 153 | done = true; 154 | try { 155 | join(); 156 | } catch (Exception e) { 157 | e.printStackTrace(); 158 | } 159 | } 160 | 161 | public void onWindowResize(int width, int height) { 162 | //处理surfaceview的大小改变事件 163 | } 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/banner/adapter/BannerViewPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget.banner.adapter; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.v4.view.PagerAdapter; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.stormdzh.androidcustomview.widget.banner.listener.OnPageClickListener; 9 | import com.stormdzh.androidcustomview.widget.banner.holder.BannerViewHolder; 10 | import com.stormdzh.androidcustomview.widget.banner.holder.BannerViewHolderCreator; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | *
 17 |  *      @author : xiaoyao
 18 |  *      e-mail  : xiaoyao@51vest.com
 19 |  *      date    : 2018/03/02
 20 |  *      desc    :
 21 |  *      version : 1.0
 22 |  * 
23 | */ 24 | 25 | public class BannerViewPagerAdapter extends PagerAdapter { 26 | 27 | private List mData; 28 | private BannerViewHolderCreator mCreator; 29 | private OnPageClickListener mPageClickListener; 30 | 31 | public BannerViewPagerAdapter(@NonNull List data, @NonNull BannerViewHolderCreator creator) { 32 | 33 | if (mData == null) { 34 | mData = new ArrayList<>(); 35 | } 36 | mData = data; 37 | mCreator = creator; 38 | } 39 | 40 | @Override 41 | public boolean isViewFromObject(View view, Object object) { 42 | return view == object; 43 | } 44 | 45 | @Override 46 | public Object instantiateItem(ViewGroup container, final int position) { 47 | View view = getView(position, container); 48 | container.addView(view); 49 | return view; 50 | } 51 | 52 | @Override 53 | public void destroyItem(ViewGroup container, int position, Object object) { 54 | container.removeView((View) object); 55 | } 56 | 57 | 58 | 59 | /** 60 | * 获取真实的Count 61 | * 62 | * @return 63 | */ 64 | public int getRealCount() { 65 | return mData == null ? 0 : mData.size(); 66 | } 67 | 68 | @Override 69 | public int getCount() { 70 | return getRealCount(); 71 | } 72 | 73 | /** 74 | * @param position 75 | * @param container 76 | * @return 77 | */ 78 | private View getView(int position, ViewGroup container) { 79 | 80 | final int realPosition = position % getRealCount(); 81 | BannerViewHolder holder = null; 82 | // create holder 83 | holder = mCreator.createViewHolder(); 84 | 85 | if (holder == null) { 86 | throw new RuntimeException("can not return a null holder"); 87 | } 88 | // create View 89 | View view = holder.createView(container.getContext()); 90 | 91 | if (mData != null && mData.size() > 0) { 92 | holder.onBind(container.getContext(), realPosition, mData.get(realPosition)); 93 | } 94 | 95 | // 添加page点击事件 96 | if (view != null) { 97 | view.setOnClickListener(new View.OnClickListener() { 98 | @Override 99 | public void onClick(View v) { 100 | if (mPageClickListener != null) { 101 | mPageClickListener.onPageClick(v, realPosition); 102 | } 103 | } 104 | }); 105 | } 106 | 107 | return view; 108 | } 109 | 110 | 111 | public List getData() { 112 | return mData; 113 | } 114 | 115 | public void setData(List mData) { 116 | this.mData = mData; 117 | } 118 | 119 | public void setPageClickListener(OnPageClickListener pageClickListener) { 120 | this.mPageClickListener = pageClickListener; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/banner/holder/BannerViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget.banner.holder; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | /** 7 | *
 8 |  *      @author : xiaoyao
 9 |  *      e-mail  : xiaoyao@51vest.com
10 |  *      date    : 2018/03/02
11 |  *      desc    :
12 |  *      version : 1.0
13 |  * 
14 | */ 15 | 16 | public interface BannerViewHolder { 17 | 18 | /** 19 | * 创建View 20 | * @param context 21 | * @return 22 | */ 23 | View createView(Context context); 24 | 25 | /** 26 | * 绑定数据 27 | * @param context 28 | * @param position 29 | * @param data 30 | */ 31 | void onBind(Context context, int position, T data); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/banner/holder/BannerViewHolderCreator.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget.banner.holder; 2 | 3 | /** 4 | *
 5 |  *      @author : xiaoyao
 6 |  *      e-mail  : xiaoyao@51vest.com
 7 |  *      date    : 2018/03/02
 8 |  *      desc    :
 9 |  *      version : 1.0
10 |  * 
11 | */ 12 | 13 | public interface BannerViewHolderCreator { 14 | /** 15 | * 创建 BannerViewHolder 16 | * 17 | * @return BannerViewHolder 18 | */ 19 | VH createViewHolder(); 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/banner/listener/OnPageChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget.banner.listener; 2 | 3 | /** 4 | *
 5 |  *      @author : xiaoyao
 6 |  *      e-mail  : xiaoyao@51vest.com
 7 |  *      date    : 2018/03/09
 8 |  *      desc    :
 9 |  *      version : 1.0
10 |  * 
11 | */ 12 | 13 | public interface OnPageChangeListener { 14 | 15 | /** 16 | * item 选中事件 17 | * 18 | * @param position position 19 | */ 20 | void onPageSelected(int position); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/stormdzh/androidcustomview/widget/banner/listener/OnPageClickListener.java: -------------------------------------------------------------------------------- 1 | package com.stormdzh.androidcustomview.widget.banner.listener; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | *
 7 |  *      @author : xiaoyao
 8 |  *      e-mail  : xiaoyao@51vest.com
 9 |  *      date    : 2018/03/02
10 |  *      desc    :
11 |  *      version : 1.0
12 |  * 
13 | */ 14 | 15 | public interface OnPageClickListener { 16 | 17 | /** 18 | * item 点击事件 19 | * 20 | * @param view view 21 | * @param position position 22 | */ 23 | void onPageClick(View view, int position); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_gradual_assarts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_color_horizontal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ripple_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_circle_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tag_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tag_checked_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tag_normal_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tag_text_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/video_seekbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_animation_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_animation_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 |