├── .gitignore ├── .idea ├── .name ├── codeStyles │ └── Project.xml ├── compiler.xml ├── deploymentTargetDropDown.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── player │ │ └── movie │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── player │ │ │ ├── common │ │ │ └── Constants.java │ │ │ ├── http │ │ │ ├── RequestUtils.java │ │ │ ├── ResultEntity.java │ │ │ └── TokenHeaderInterceptor.java │ │ │ ├── movie │ │ │ ├── BaseApplication.java │ │ │ ├── activity │ │ │ │ ├── LaunchActivity.java │ │ │ │ ├── LoginActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── MovieDetailActivity.java │ │ │ │ ├── MoviePlayActivity.java │ │ │ │ ├── RegisterActivity.java │ │ │ │ ├── SearchActivity.java │ │ │ │ ├── UserActivity.java │ │ │ │ └── WebViewActivity.java │ │ │ ├── adapter │ │ │ │ ├── CategoryRecyclerViewAdapter.java │ │ │ │ ├── GridRecyclerViewAdapter.java │ │ │ │ ├── SearchRecyclerViewAdapter.java │ │ │ │ └── StarRecyclerViewAdapter.java │ │ │ ├── api │ │ │ │ └── Api.java │ │ │ ├── dao │ │ │ │ └── SearchWordDao.java │ │ │ ├── database │ │ │ │ └── SearchWordDatabase.java │ │ │ ├── dialog │ │ │ │ ├── BottomMenu.java │ │ │ │ ├── CustomDialogFragment.java │ │ │ │ ├── DatePickerFragment.java │ │ │ │ └── PlugCamera.java │ │ │ ├── entity │ │ │ │ ├── CategoryEntity.java │ │ │ │ ├── EditEntity.java │ │ │ │ ├── MovieEntity.java │ │ │ │ ├── MovieStarEntity.java │ │ │ │ ├── MovieUrlEntity.java │ │ │ │ ├── SearchWordEntity.java │ │ │ │ └── UserEntity.java │ │ │ ├── fragment │ │ │ │ ├── CategoryFragment.java │ │ │ │ ├── HomeFragment.java │ │ │ │ ├── LikeMovieFragment.java │ │ │ │ ├── MovieFragment.java │ │ │ │ ├── RecommendMovieFragment.java │ │ │ │ ├── SearchFragment.java │ │ │ │ ├── TVFragment.java │ │ │ │ └── UserFragment.java │ │ │ ├── myinterface │ │ │ │ ├── JavaScriptinterface.java │ │ │ │ └── UrlClickListener.java │ │ │ ├── receiver │ │ │ │ └── UpdateUserReciver.java │ │ │ ├── service │ │ │ │ └── RequestMusicService.java │ │ │ ├── utils │ │ │ │ ├── ActivityCollectorUtil.java │ │ │ │ ├── CMAppGlideModule.java │ │ │ │ ├── CommonUtils.java │ │ │ │ ├── Converters.java │ │ │ │ ├── MD5.java │ │ │ │ └── SharedPreferencesUtils.java │ │ │ └── view │ │ │ │ ├── ButtomMenuDialog.java │ │ │ │ ├── FlowLayout.java │ │ │ │ ├── MyImageView.java │ │ │ │ ├── NoScrollGridView.java │ │ │ │ ├── ReflectHelper.java │ │ │ │ ├── RoundImageView.java │ │ │ │ ├── TabLayout.java │ │ │ │ └── WrapContentHeightViewPager.java │ │ │ └── music │ │ │ ├── activity │ │ │ ├── MusicActivity.java │ │ │ └── MusicSearchActivity.java │ │ │ ├── api │ │ │ └── Api.java │ │ │ ├── entity │ │ │ └── MusicEntity.java │ │ │ ├── fragment │ │ │ ├── MusicCircleFragment.java │ │ │ ├── MusicHomeFragment.java │ │ │ ├── MusicRecommentFragment.java │ │ │ ├── MusicSearchFragment.java │ │ │ └── MusicUserFragment.java │ │ │ └── service │ │ │ └── RequestMusicService.java │ └── res │ │ ├── anim │ │ ├── slide_in_bottom.xml │ │ └── slide_out_bottom.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── bg_button_cancel.xml │ │ ├── bg_button_cancel_shape.xml │ │ ├── bg_button_disabled_shape.xml │ │ ├── bg_button_sure.xml │ │ ├── bg_button_sure_disabled.xml │ │ ├── bg_button_sure_normal.xml │ │ ├── bg_button_sure_normal_shape.xml │ │ ├── border_radius.xml │ │ ├── bottom_border.xml │ │ ├── btn_radius_blue_decoration.xml │ │ ├── btn_radius_red_decoration.xml │ │ ├── edit_input_decoration.xml │ │ ├── ic_launcher_background.xml │ │ ├── movie_img_border_radius.xml │ │ ├── right_border_stroke_white.xml │ │ ├── rounded_border_btn.xml │ │ ├── rounded_corner_search_box.xml │ │ ├── search_input_decoration.xml │ │ ├── search_record_item_decoration.xml │ │ ├── sm_active_border_decoration.xml │ │ ├── sm_border_decoration.xml │ │ ├── tab_left_active.xml │ │ ├── tab_left_normal.xml │ │ ├── tab_middle_active.xml │ │ ├── tab_middle_normal.xml │ │ ├── tab_right_active.xml │ │ ├── tab_right_normal.xml │ │ ├── title_background.xml │ │ └── top_border_stroke_white.xml │ │ ├── layout │ │ ├── activity_launch.xml │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_movie_detail.xml │ │ ├── activity_movie_play.xml │ │ ├── activity_music.xml │ │ ├── activity_music_search.xml │ │ ├── activity_register.xml │ │ ├── activity_search.xml │ │ ├── activity_user.xml │ │ ├── activity_web_view.xml │ │ ├── bottom_border.xml │ │ ├── category_fragment.xml │ │ ├── custom_dialog.xml │ │ ├── dialog_bottom_menu.xml │ │ ├── edit_user_input.xml │ │ ├── fraction_like_movie.xml │ │ ├── fraction_recommend_movie.xml │ │ ├── fragment_home.xml │ │ ├── fragment_movie.xml │ │ ├── fragment_music_circle.xml │ │ ├── fragment_music_home.xml │ │ ├── fragment_music_recommend.xml │ │ ├── fragment_music_search.xml │ │ ├── fragment_music_user.xml │ │ ├── fragment_search.xml │ │ ├── fragment_tv.xml │ │ ├── fragment_user.xml │ │ ├── layout_loading.xml │ │ ├── logout_text.xml │ │ ├── module_title.xml │ │ ├── movie_item.xml │ │ ├── movie_row.xml │ │ ├── network_security_policy.xml │ │ ├── search_movie_item.xml │ │ ├── search_record_item.xml │ │ ├── underline.xml │ │ ├── url_linear_layout.xml │ │ └── url_row.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── default_avater.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── icon_app.png │ │ ├── icon_arrow.png │ │ ├── icon_avater.png │ │ ├── icon_back.png │ │ ├── icon_classify.png │ │ ├── icon_clear.png │ │ ├── icon_collection.png │ │ ├── icon_collection_active.png │ │ ├── icon_comment.png │ │ ├── icon_comment_white.png │ │ ├── icon_delete.png │ │ ├── icon_detail_play.png │ │ ├── icon_down.png │ │ ├── icon_edit.png │ │ ├── icon_empty_star.png │ │ ├── icon_full_star.png │ │ ├── icon_half_star.png │ │ ├── icon_history.png │ │ ├── icon_home.png │ │ ├── icon_home_active.png │ │ ├── icon_hot.png │ │ ├── icon_like.png │ │ ├── icon_like_active.png │ │ ├── icon_like_white.png │ │ ├── icon_logo.png │ │ ├── icon_menu_add.png │ │ ├── icon_movie.png │ │ ├── icon_movie_active.png │ │ ├── icon_music.png │ │ ├── icon_music_add.png │ │ ├── icon_music_circle.png │ │ ├── icon_music_circle_active.png │ │ ├── icon_music_classics.png │ │ ├── icon_music_classify.png │ │ ├── icon_music_like.png │ │ ├── icon_music_menu.png │ │ ├── icon_music_play.png │ │ ├── icon_music_rank.png │ │ ├── icon_music_singer.png │ │ ├── icon_no1.png │ │ ├── icon_no2.png │ │ ├── icon_no3.png │ │ ├── icon_password.png │ │ ├── icon_play.png │ │ ├── icon_play_record.png │ │ ├── icon_recomment.png │ │ ├── icon_recomment_active.png │ │ ├── icon_record.png │ │ ├── icon_search.png │ │ ├── icon_share.png │ │ ├── icon_talk.png │ │ ├── icon_top.png │ │ ├── icon_tv.png │ │ ├── icon_tv_active.png │ │ ├── icon_user.png │ │ └── icon_user_active.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── diemens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── player │ └── movie │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── 一键提交到gitee.bat ├── 一键提交到github.bat ├── 分类歌曲.png ├── 外网映射正常访问提示.png ├── 新版电影APP整体预览图.jpg ├── 电影app整体预览.jpg ├── 电影app整体预览2.jpg ├── 电影预览1.png ├── 电影预览10.png ├── 电影预览11.png ├── 电影预览12.png ├── 电影预览13.jpg ├── 电影预览14.jpg ├── 电影预览15.png ├── 电影预览2.png ├── 电影预览3.png ├── 电影预览4.png ├── 电影预览5.png ├── 电影预览6.png ├── 电影预览7.png ├── 电影预览8.png ├── 电影预览9-1.png ├── 电影预览9-2.png ├── 电影预览9-3.png ├── 电影预览9-4.png ├── 电影预览9.png ├── 音乐分享-权限选择.png ├── 音乐分享.png ├── 音乐列表页.png ├── 音乐圈评论.png ├── 音乐我的1.jpg ├── 音乐我的2.png ├── 音乐推荐.jpg ├── 音乐搜索列表.png ├── 音乐搜索记录.png ├── 音乐播放页-创建收藏夹.png ├── 音乐播放页-播放模式切换.png ├── 音乐播放页-收藏音乐.png ├── 音乐播放页-评论.png ├── 音乐播放页.png ├── 音乐收藏列表.png ├── 音乐朋友圈1.jpg ├── 音乐朋友圈2.png ├── 音乐歌手专辑页.png ├── 音乐歌手页.png ├── 音乐歌词页.png ├── 音乐点赞和评论.png └── 音乐首页.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | movie -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | 98 |
99 |
100 | 101 | 102 | 103 | .* 104 | 105 | .* 106 | 107 | 108 | BY_NAME 109 | 110 |
111 |
112 |
113 |
114 |
115 |
-------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | 39 | 40 | 44 | 45 | 49 | 50 | 54 | 55 | 59 | 60 | 64 | 65 | 69 | 70 | 74 | 75 | 79 | 80 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # android电影APP 2 | 3 | 开发者:吴怨吴悔 4 | 5 | 6 | =============================界面预览(如果无法预览,请查看项目根目录png文件)========================== 7 | 8 | ![app首页](./新版电影APP整体预览图.jpg) 9 | ![app首页](电影预览1.png) 10 | ![app首页](电影预览2.png) 11 | ![app首页](电影预览3.png) 12 | ![app首页](电影预览4.png) 13 | ![app首页](电影预览5.png) 14 | ![app首页](电影预览6.png) 15 | ![app首页](电影预览7.png) 16 | ![app首页](电影预览8.png) 17 | ![app首页](电影预览9.png) 18 | ![app首页](电影预览9-1.png) 19 | ![app首页](电影预览9-2.png) 20 | ![app首页](电影预览9-3.png) 21 | ![app首页](电影预览9-4.png) 22 | ![app首页](电影预览10.png) 23 | ![app首页](电影预览11.png) 24 | ![app首页](电影预览12.png) 25 | ![app首页](电影预览13.jpg) 26 | ![app首页](电影预览14.jpg) 27 | ![app首页](电影预览15.png) 28 | ![app首页](音乐首页.jpg) 29 | ![app首页](音乐推荐.jpg) 30 | ![app首页](音乐朋友圈1.jpg) 31 | ![app首页](音乐朋友圈2.png) 32 | ![app首页](音乐我的1.jpg) 33 | ![app首页](音乐我的2.png) 34 | ![app首页](音乐播放页.png) 35 | ![app首页](音乐播放页-播放模式切换.png) 36 | ![app首页](音乐播放页-收藏音乐.png) 37 | ![app首页](音乐播放页-创建收藏夹.png) 38 | ![app首页](音乐播放页-评论.png) 39 | ![app首页](音乐分享.png) 40 | ![app首页](音乐分享-权限选择.png) 41 | ![app首页](音乐歌词页.png) 42 | ![app首页](音乐歌手页.png) 43 | ![app首页](音乐歌手专辑页.png) 44 | ![app首页](音乐搜索记录.png) 45 | ![app首页](音乐搜索列表.png) 46 | ![app首页](音乐点赞和评论.png) 47 | ![app首页](音乐圈评论.png) 48 | ![app首页](音乐收藏列表.png) 49 | ![app首页](音乐列表页.png) 50 | ![app首页](分类歌曲.png) 51 | =============================界面预览(如果无法预览,请查看项目根目录png文件)========================== 52 | 53 | 54 | 所有影片数据来自第三方电影网站,使用python爬虫实时抓取,然后存入到自己的mysql数据库中,所有接口均采用java开发 55 | 56 | 后端接口项目和sql语句:https://github.com/wuyuanwuhui99/springboot-app-service 57 | 58 | 59 | flutter版本参见: 60 | https://github.com/wuyuanwuhui99/flutter-movie-app-ui 61 | https://gitee.com/wuyuanwuhui99/flutter-movie-app-ui 62 | 63 | react native版本参见: 64 | https://github.com/wuyuanwuhui99/react-native-app-ui 65 | 66 | 在线音乐和电影后端接口项目和sql语句: 67 | https://github.com/wuyuanwuhui99/springboot-app-service 68 | https://gitee.com/wuyuanwuhui99/springboot-app-service 69 | 70 | harmony鸿蒙java版本参见: 71 | https://github.com/wuyuanwuhui99/Harmony_movie_app_ui 72 | https://gitee.com/wuyuanwuhui99/Harmony_movie_app_ui 73 | 74 | harmony鸿蒙arkts版本参见: 75 | https://github.com/wuyuanwuhui99/Harmony-arkts-movie-music-app-ui 76 | https://gitee.com/wuyuanwuhui99/Harmony-arkts-movie-music-app-ui 77 | 78 | java安卓原生版本参见: 79 | https://github.com/wuyuanwuhui99/android-java-movie-app-ui 80 | https://gitee.com/wuyuanwuhui99/android-java-movie-app-ui 81 | 82 | kotlin安卓原生版本参见: 83 | https://github.com/wuyuanwuhui99/android-kotlin-jetpack-movie-app 84 | 85 | 微信小程序版本参见: 86 | https://github.com/wuyuanwuhui99/weixin-movie-app-ui 87 | https://gitee.com/wuyuanwuhui99/weixin-movie-app-ui 88 | 89 | uniapp版本参见: 90 | https://github.com/wuyuanwuhui99/uniapp-vite-vue3-ts-movie-app-ui 91 | https://gitee.com/wuyuanwuhui99/uniapp-vite-vue3-ts-movie-app-ui 92 | 93 | vue2在线音乐项目: 94 | https://github.com/wuyuanwuhui99/vue-music-app-ui 95 | 96 | 在线音乐后端项目: 97 | https://github.com/wuyuanwuhui99/koa2-music-app-service 98 | 99 | vue3+ts明日头条项目: 100 | https://github.com/wuyuanwuhui99/vue3-ts-toutiao-app-ui 101 | 102 | 本地调试请把 http://192.168.0.5:5001 改成 http://254a2y1767.qicp.vip 103 | 该地址是映射到本人电脑的地址,需要本人电脑开机才能访问,一般在工作日晚上八点半之后或者周末白天会开机 104 | 如需了解是否已开机,请用浏览器直接打开该地址:http://254a2y1767.qicp.vip,如出现以下提示,则正常使用 105 | ![外网映射正常访问提示](外网映射正常访问提示.png) 106 | 107 | 本站所有视频和图片均来自互联网收集而来,版权归原创者所有,本网站只提供web页面服务,并不提供资源存储,也不参与录制、上传 若本站收录的节目无意侵犯了贵司版权,请联系 108 | 109 | 联系方式:(微信)wuwenqiang_99、(邮箱)275018723@qq.com 110 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | buildToolsVersion "30.0.3" 6 | defaultConfig { 7 | applicationId "com.player.movie" 8 | minSdkVersion 19 9 | targetSdkVersion 30 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | compileOptions { 21 | sourceCompatibility JavaVersion.VERSION_1_8 22 | targetCompatibility JavaVersion.VERSION_1_8 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | implementation 'androidx.appcompat:appcompat:1.0.2' 29 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 30 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 31 | implementation 'com.google.android.material:material:1.4.0' 32 | implementation 'androidx.fragment:fragment:1.4.1' 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'androidx.test.ext:junit:1.1.0' 35 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 36 | 37 | implementation 'com.squareup.okhttp3:okhttp:3.4.1' 38 | implementation 'com.android.support:design:25.2.0' 39 | 40 | implementation 'com.youth.banner:banner:2.1.0' 41 | implementation 'com.youth.banner:banner:2.0.10' 42 | implementation 'com.github.bumptech.glide:glide:4.11.0' 43 | annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' 44 | implementation 'com.android.support:recyclerview-v7:28.0.0' 45 | 46 | implementation 'com.squareup.retrofit2:converter-gson:2.0.2' // 用Gson解析json的转换器 47 | implementation 'com.squareup.retrofit2:retrofit:2.0.2' 48 | 49 | implementation 'com.alibaba:fastjson:1.1.34.android' 50 | implementation 'com.makeramen:roundedimageview:2.2.1' 51 | 52 | implementation 'androidx.room:room-runtime:2.2.5' 53 | annotationProcessor 'androidx.room:room-compiler:2.2.5' 54 | } 55 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/player/movie/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.player.movie; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.player.movie", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 17 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/common/Constants.java: -------------------------------------------------------------------------------- 1 | package com.player.common; 2 | 3 | 4 | public class Constants { 5 | public static final String HOST = "http://169.254.32.117:5001"; 6 | public final static String SUCCESS = "SUCCESS"; 7 | public final static String TOKEN = "TOKEN"; 8 | public static final String FAIL = "FAIL"; 9 | public static final String PASSWORD = "PASSWORD"; 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/http/RequestUtils.java: -------------------------------------------------------------------------------- 1 | package com.player.http; 2 | 3 | import com.player.common.Constants; 4 | import com.player.movie.api.Api; 5 | import com.player.movie.service.RequestMusicService; 6 | 7 | import retrofit2.Retrofit; 8 | import retrofit2.converter.gson.GsonConverterFactory; 9 | 10 | public class RequestUtils { 11 | 12 | static public RequestMusicService getMovieInstance(){ 13 | return new Retrofit.Builder() 14 | .baseUrl(Constants.HOST) 15 | .client(new TokenHeaderInterceptor().getClient().build()) 16 | .addConverterFactory(GsonConverterFactory.create()) 17 | .build().create(RequestMusicService.class); 18 | } 19 | 20 | static public com.player.music.service.RequestMusicService getMusicInstance(){ 21 | return new Retrofit.Builder() 22 | .baseUrl(Constants.HOST) 23 | .client(new TokenHeaderInterceptor().getClient().build()) 24 | .addConverterFactory(GsonConverterFactory.create()) 25 | .build().create(com.player.music.service.RequestMusicService.class); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/http/ResultEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.http; 2 | 3 | public class ResultEntity { 4 | private Object data; 5 | private String status; 6 | private String msg; 7 | private int total; 8 | private String token; 9 | 10 | public Object getData() { 11 | return data; 12 | } 13 | 14 | public void setData(Object data) { 15 | this.data = data; 16 | } 17 | 18 | public String getStatus() { 19 | return status; 20 | } 21 | 22 | public void setStatus(String status) { 23 | this.status = status; 24 | } 25 | 26 | public String getMsg() { 27 | return msg; 28 | } 29 | 30 | public void setMsg(String msg) { 31 | this.msg = msg; 32 | } 33 | 34 | public int getTotal() { 35 | return total; 36 | } 37 | 38 | public void setTotal(int total) { 39 | this.total = total; 40 | } 41 | 42 | public String getToken() { 43 | return token; 44 | } 45 | 46 | public void setToken(String token) { 47 | this.token = token; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/http/TokenHeaderInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.player.http; 2 | 3 | import com.player.movie.BaseApplication; 4 | 5 | import java.io.IOException; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import okhttp3.Interceptor; 9 | import okhttp3.OkHttpClient; 10 | import okhttp3.Request; 11 | import okhttp3.Response; 12 | 13 | public class TokenHeaderInterceptor implements Interceptor { 14 | 15 | @Override 16 | public Response intercept(Chain chain) throws IOException { 17 | return null; 18 | } 19 | 20 | public OkHttpClient.Builder getClient(){ 21 | OkHttpClient.Builder builder = new OkHttpClient.Builder(); 22 | builder.connectTimeout(15, TimeUnit.SECONDS); 23 | String token = BaseApplication.getInstance().getToken(); 24 | builder.addInterceptor(chain -> { 25 | Request build = chain.request().newBuilder() 26 | .addHeader("Authorization", token) 27 | .addHeader("Content-type","application/json;charset=UTF-8") 28 | .build(); 29 | return chain.proceed(build); 30 | }); 31 | return builder; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/BaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.player.movie; 2 | 3 | import android.app.Application; 4 | 5 | import com.player.common.Constants; 6 | import com.player.movie.entity.UserEntity; 7 | import com.player.movie.utils.SharedPreferencesUtils; 8 | 9 | public class BaseApplication extends Application { 10 | 11 | private static BaseApplication mApp; 12 | 13 | public static BaseApplication getInstance(){ 14 | return mApp; 15 | } 16 | 17 | private String token; 18 | 19 | private UserEntity userEntity; 20 | 21 | @Override 22 | public void onCreate() { 23 | super.onCreate(); 24 | mApp = this; 25 | token = (String) SharedPreferencesUtils.getParam(this, Constants.TOKEN,""); 26 | } 27 | 28 | public void setToken(String token){ 29 | this.token = token; 30 | } 31 | 32 | public String getToken(){ 33 | return token; 34 | } 35 | 36 | public UserEntity getUserEntity() { 37 | return userEntity; 38 | } 39 | 40 | public void setUserEntity(UserEntity userEntity) { 41 | this.userEntity = userEntity; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/activity/LaunchActivity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | import android.view.View; 7 | 8 | import androidx.appcompat.app.AppCompatActivity; 9 | 10 | import com.google.gson.Gson; 11 | import com.player.R; 12 | import com.player.common.Constants; 13 | import com.player.http.RequestUtils; 14 | import com.player.http.ResultEntity; 15 | import com.player.movie.BaseApplication; 16 | import com.player.movie.entity.UserEntity; 17 | import com.player.movie.utils.SharedPreferencesUtils; 18 | 19 | import retrofit2.Call; 20 | import retrofit2.Callback; 21 | import retrofit2.Response; 22 | 23 | 24 | public class LaunchActivity extends AppCompatActivity{ 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_launch); 29 | init(); 30 | } 31 | 32 | /** 33 | * @author: wuwenqiang 34 | * @description: 初始化加载缓存token 35 | * @date: 2024-04-20 18:42 36 | */ 37 | void init(){ 38 | Handler handler = new Handler(); 39 | Runnable runnable = () -> { 40 | String token = (String) SharedPreferencesUtils.getParam(LaunchActivity.this, Constants.TOKEN,""); 41 | if(!"".equals(token) && token != null){ 42 | getUserData(); 43 | }else{ 44 | startActivity(new Intent(LaunchActivity.this,LoginActivity.class)); 45 | } 46 | }; 47 | handler.postDelayed(runnable, 1000); // 延时1000毫秒执行 48 | } 49 | 50 | /** 51 | * @author: wuwenqiang 52 | * @description: 获取用户信息 53 | * @date: 2021-12-04 15:59 54 | */ 55 | private void getUserData(){ 56 | Call userData = RequestUtils.getMovieInstance().getUserData(); 57 | userData.enqueue(new Callback() { 58 | @Override 59 | public void onResponse(Call call, Response response) { 60 | Gson gson = new Gson(); 61 | ResultEntity body = response.body(); 62 | BaseApplication instance = BaseApplication.getInstance(); 63 | Intent intent; 64 | if(body.getToken() != null){ 65 | instance.setToken(body.getToken()); 66 | instance.setUserEntity(gson.fromJson(gson.toJson(body.getData()), UserEntity.class)); 67 | SharedPreferencesUtils.setParam(LaunchActivity.this, Constants.TOKEN,response.body().getToken()); 68 | intent = new Intent(LaunchActivity.this,MainActivity.class); 69 | }else{ 70 | intent = new Intent(LaunchActivity.this,LoginActivity.class); 71 | } 72 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// 前面所有页面置空 73 | startActivity(intent); 74 | finish(); 75 | } 76 | 77 | @Override 78 | public void onFailure(Call call, Throwable t) { 79 | Intent intent = new Intent(LaunchActivity.this,LoginActivity.class); 80 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// 前面所有页面置空 81 | startActivity(intent); 82 | finish(); 83 | } 84 | }); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/activity/WebViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.activity; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.content.Intent; 6 | import android.graphics.Bitmap; 7 | import android.net.Uri; 8 | import android.os.Bundle; 9 | import android.provider.MediaStore; 10 | import android.webkit.WebSettings; 11 | import android.webkit.WebView; 12 | import android.webkit.WebViewClient; 13 | 14 | import com.player.R; 15 | import com.player.movie.myinterface.JavaScriptinterface; 16 | import com.player.movie.utils.CommonUtils; 17 | import com.player.movie.dialog.PlugCamera; 18 | 19 | import java.io.IOException; 20 | 21 | public class WebViewActivity extends AppCompatActivity { 22 | WebView webView; 23 | JavaScriptinterface javaScriptinterface; 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_web_view); 28 | initData(); 29 | } 30 | 31 | private void initData(){ 32 | webView = (WebView) findViewById(R.id.movie_webview); 33 | Intent intent = getIntent(); 34 | String url = intent.getStringExtra("url"); 35 | WebSettings webSettings = webView.getSettings(); 36 | webSettings.setJavaScriptEnabled(true); 37 | webView.clearCache(true); 38 | javaScriptinterface = new JavaScriptinterface(this, WebViewActivity.this); 39 | webView.addJavascriptInterface(javaScriptinterface,"plus"); 40 | deleteDatabase("webview.db"); 41 | deleteDatabase("webviewCache.db"); 42 | webView.loadUrl(url); 43 | webView.setWebViewClient(new WebViewClient(){ 44 | @Override 45 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 46 | view.loadUrl(url); 47 | return true; 48 | } 49 | }); 50 | } 51 | 52 | @Override 53 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 54 | super.onActivityResult(requestCode, resultCode, data); 55 | if (requestCode == PlugCamera.REQUEST_CODE_CAMERA) { 56 | String base64; 57 | if("相机".equals(javaScriptinterface.getCheck())){ 58 | Bundle bundle = data.getExtras(); // 从data中取出传递回来缩略图的信息,图片质量差,适合传递小图片 59 | Bitmap bitmap = (Bitmap) bundle.get("data"); // 将data中的信息流解析为Bitmap类型 60 | base64 = CommonUtils.bitmapToBase64(bitmap); 61 | }else { 62 | Uri uri = data.getData(); 63 | try { 64 | Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),uri); 65 | base64 = CommonUtils.bitmapToBase64(bitmap); 66 | }catch (IOException e){ 67 | base64 = ""; 68 | } 69 | } 70 | webView.evaluateJavascript("javascript:plus.chooseImagesCallback('"+base64+"')", value -> {}); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/adapter/CategoryRecyclerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.adapter; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.LinearLayout; 9 | import android.widget.TextView; 10 | 11 | import androidx.annotation.NonNull; 12 | import androidx.recyclerview.widget.RecyclerView; 13 | 14 | import com.alibaba.fastjson.JSON; 15 | import com.bumptech.glide.Glide; 16 | import com.makeramen.roundedimageview.RoundedImageView; 17 | import com.player.R; 18 | import com.player.common.Constants; 19 | import com.player.movie.activity.MovieDetailActivity; 20 | import com.player.movie.api.Api; 21 | import com.player.movie.entity.MovieEntity; 22 | 23 | import java.util.List; 24 | 25 | public class CategoryRecyclerViewAdapter extends RecyclerView.Adapter implements View.OnClickListener{ 26 | 27 | private ListmovieEntityList; 28 | private Context context; 29 | public CategoryRecyclerViewAdapter(List movieEntityList,Context context){ 30 | this.movieEntityList = movieEntityList; 31 | this.context = context; 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 37 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item, parent, false); 38 | return new ViewHolder(view); 39 | } 40 | 41 | @Override 42 | public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 43 | String path = Constants.HOST + movieEntityList.get(position).getLocalImg(); 44 | Glide.with(context).load(path).into(holder.imageView); 45 | holder.textView.setText(movieEntityList.get(position).getMovieName()); 46 | holder.itemView.setTag(movieEntityList.get(position)); 47 | if(position == movieEntityList.size() - 1){ 48 | LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 49 | layoutParams.setMargins(0,0,0,0);//4个参数按顺序分别是左上右下 50 | holder.itemView.setLayoutParams(layoutParams); 51 | } 52 | holder.itemView.setOnClickListener(this); 53 | } 54 | 55 | 56 | @Override 57 | public int getItemCount() { 58 | return movieEntityList.size(); 59 | } 60 | 61 | // 列表绑定点击事件 62 | @Override 63 | public void onClick(View v) { 64 | Intent intent = new Intent(context, MovieDetailActivity.class); 65 | String movieJSONString = JSON.toJSONString(v.getTag()); 66 | intent.putExtra("movieItem",movieJSONString); 67 | context.startActivity(intent); 68 | } 69 | 70 | 71 | class ViewHolder extends RecyclerView.ViewHolder{ 72 | public final RoundedImageView imageView; 73 | public final TextView textView; 74 | public ViewHolder(@NonNull View itemView) { 75 | super(itemView); 76 | imageView = itemView.findViewById(R.id.movie_img); 77 | textView = itemView.findViewById(R.id.movie_name); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/adapter/StarRecyclerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.adapter; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.LinearLayout; 9 | import android.widget.TextView; 10 | 11 | import androidx.annotation.NonNull; 12 | import androidx.recyclerview.widget.RecyclerView; 13 | 14 | import com.alibaba.fastjson.JSON; 15 | import com.bumptech.glide.Glide; 16 | import com.makeramen.roundedimageview.RoundedImageView; 17 | import com.player.common.Constants; 18 | import com.player.movie.BaseApplication; 19 | import com.player.R; 20 | import com.player.movie.activity.MovieDetailActivity; 21 | import com.player.movie.api.Api; 22 | import com.player.movie.entity.MovieEntity; 23 | import com.player.movie.entity.MovieStarEntity; 24 | 25 | import java.util.List; 26 | 27 | public class StarRecyclerViewAdapter extends RecyclerView.Adapter implements View.OnClickListener{ 28 | 29 | private ListmovieStarList; 30 | Context context; 31 | 32 | public StarRecyclerViewAdapter(List movieStarList,Context context){ 33 | this.context = context; 34 | this.movieStarList = movieStarList; 35 | } 36 | 37 | @NonNull 38 | @Override 39 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 40 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item, parent, false); 41 | return new ViewHolder(view); 42 | } 43 | 44 | @Override 45 | public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 46 | String path = Constants.HOST + movieStarList.get(position).getLocalImg(); 47 | // String path = movieStarList.get(position).getImg(); 48 | Glide.with(context).load(path).into(holder.imageView); 49 | holder.textView.setText(movieStarList.get(position).getStarName()); 50 | if(position == movieStarList.size() - 1){ 51 | LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 52 | layoutParams.setMargins(0,0,0,0);//4个参数按顺序分别是左上右下 53 | holder.itemView.setLayoutParams(layoutParams); 54 | } 55 | holder.itemView.setTag(movieStarList.get(position)); 56 | holder.itemView.setOnClickListener(this); 57 | } 58 | 59 | @Override 60 | public int getItemCount() { 61 | return movieStarList.size(); 62 | } 63 | 64 | @Override 65 | public void onClick(View v) { 66 | Intent intent = new Intent(context, MovieDetailActivity.class); 67 | String movieJSONString = JSON.toJSONString(v.getTag()); 68 | intent.putExtra("movieItem",movieJSONString); 69 | context.startActivity(intent); 70 | } 71 | 72 | 73 | class ViewHolder extends RecyclerView.ViewHolder{ 74 | public final RoundedImageView imageView; 75 | public final TextView textView; 76 | public ViewHolder(@NonNull View itemView) { 77 | super(itemView); 78 | imageView = itemView.findViewById(R.id.movie_img); 79 | textView = itemView.findViewById(R.id.movie_name); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/api/Api.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.api; 2 | 3 | public class Api { 4 | //查询所有大分类 5 | public static final String GETUSERDATA = "/service/user/getUserData"; 6 | public static final String GETCATEGORYLIST = "/service/movie/getCategoryList";// 获取分类影片 7 | public static final String GETTOPMOVIELIST = "/service/movie/getTopMovieList";// 根据分类前20条影片数据 8 | public static final String GETKEYWORD = "/service/movie/getKeyWord";//按照classify查询搜索栏的关键词 9 | public static final String GETALLCATEGORYBYCLASSIFY = "/service/movie/getAllCategoryByClassify";//按classify大类查询所有catory小类 10 | public static final String GETALLCATEGORYLISTBYPAGENAME = "/service/movie/getAllCategoryListByPageName"; //按页面获取要展示的category小类 11 | public static final String GETUSERMSG = "/service/movie-getway/getUserMsg"; //获取用户四个指标信息,使用天数,关注,观看记录,浏览记录 12 | public static final String GETSEARCHRESULT = "/service/movie/search"; //搜索 13 | public static final String LOGIN = "/service/user/login"; //登录 14 | public static final String GETSTAR = "/service/movie/getStar/{movieId}"; //获取演员 15 | public static final String GETMOVIEURL = "/service/movie/getMovieUrl"; //获取电影播放地址 16 | public static final String GETVIEWRECORD = "/service/movie-getway/getViewRecord"; //获取浏览记录 17 | public static final String SAVEVIEWRECORD = "/service/movie-getway/saveViewRecord"; //浏览历史 18 | public static final String GETPLAYRECORD = "/service/movie-getway/getPlayRecord"; //获取观看记录 19 | public static final String SAVEPLAYRECORD = "/service/movie-getway/savePlayRecord"; //播放记录 20 | public static final String GETFAVORITE = "/service/movie-getway/getFavorite"; //获取收藏电影 21 | public static final String SAVEFAVORITE = "/service/movie-getway/saveFavorite"; //添加收藏 22 | public static final String DELETEFAVORITE = "/service/movie-getway/deleteFavorite"; //删除收藏 23 | public static final String GETYOURLIKES = "/service/movie/getYourLikes";//猜你想看 24 | public static final String GETRECOMMEND = "/service/movie/getRecommend";//获取推荐 25 | public static final String ISFAVORITE = "/service/movie-getway/isFavorite";//查询是否已经收藏 26 | public static final String UPDATEUSER = "/service/user-getway/updateUser";//更新用户信息 27 | public static final String UPDATEPASSWORD = "/service/user-getway/updatePassword";//更新密码 28 | public static final String GETCOMMENTCOUNT = "/service/social/getCommentCount";//获取评论总数 29 | public static final String GETTOPCOMMENTLIST = "/service/social/getTopCommentList";//获取一级评论 30 | public static final String GETREPLYCOMMENTLIST = "/service/social/getReplyCommentList";//获取一级评论 31 | public static final String INSERTCOMMENTSERVICE = "/service/social-getway/insertComment";//新增评论 32 | public static final String REGISTER = "/service/user/register";//注册 33 | public static final String GETUSERBYID = "/service/user/getUserById";// 校验账号是否存在 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/dao/SearchWordDao.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.dao; 2 | 3 | import androidx.room.Dao; 4 | import androidx.room.Delete; 5 | import androidx.room.Insert; 6 | import androidx.room.Query; 7 | import androidx.room.Update; 8 | 9 | import com.player.movie.entity.SearchWordEntity; 10 | 11 | import java.util.List; 12 | 13 | @Dao 14 | public interface SearchWordDao { 15 | 16 | @Insert 17 | void insert(SearchWordEntity...searchWordEntity); 18 | 19 | @Delete 20 | void delete(SearchWordEntity...searchWordEntity); 21 | 22 | @Update 23 | int update(SearchWordEntity...searchWordEntity); 24 | 25 | @Query("SELECT * FROM search_word") 26 | List query(); 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/database/SearchWordDatabase.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.database; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.room.Database; 6 | import androidx.room.Room; 7 | import androidx.room.RoomDatabase; 8 | import androidx.room.TypeConverters; 9 | 10 | import com.player.movie.dao.SearchWordDao; 11 | import com.player.movie.entity.SearchWordEntity; 12 | import com.player.movie.utils.Converters; 13 | 14 | /** 15 | * @author: wuwenqiang 16 | * @description: 生成实体类和表结构 17 | * @date: 2022-08-10 21:02 18 | */ 19 | @Database(entities = {SearchWordEntity.class},version = 1,exportSchema = false) 20 | @TypeConverters({Converters.class}) 21 | public abstract class SearchWordDatabase extends RoomDatabase { 22 | // 获取该数据库中某张表的持久化对象 23 | public abstract SearchWordDao searchWordDao(); 24 | // 单例 25 | private static SearchWordDatabase database; 26 | public static synchronized SearchWordDatabase getInstance(Context context){ 27 | if (database == null){ 28 | database = Room.databaseBuilder(context.getApplicationContext(),SearchWordDatabase.class,"search.db").build(); 29 | } 30 | return database; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/dialog/BottomMenu.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.dialog; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.provider.MediaStore; 8 | 9 | import androidx.core.app.ActivityCompat; 10 | 11 | import com.player.movie.view.ButtomMenuDialog; 12 | 13 | public class BottomMenu { 14 | private ButtomMenuDialog dialog; 15 | private final String [] menu; 16 | private ClickLister clickLister; 17 | public void showBottomMenu(Context context) { 18 | ButtomMenuDialog.Builder builder = new ButtomMenuDialog.Builder(context); 19 | //添加条目,可多个 20 | for(String item:menu){ 21 | builder.addMenu(item, view -> { 22 | clickLister.onClick(item); 23 | dialog.cancel(); 24 | }); 25 | } 26 | //下面这些设置都可不写 27 | builder.setCanCancel(true);//点击阴影时是否取消dialog,true为取消 28 | builder.setShadow(true);//是否设置阴影背景,true为有阴影 29 | builder.setCancelText("取消");//设置最下面取消的文本内容 30 | //设置点击取消时的事件 31 | builder.setCancelListener(view -> { 32 | dialog.cancel(); 33 | }); 34 | dialog = builder.create(); 35 | dialog.show(); 36 | } 37 | 38 | public BottomMenu(String [] menu,ClickLister clickLister){ 39 | this.menu = menu; 40 | this.clickLister = clickLister; 41 | } 42 | 43 | public interface ClickLister{ 44 | void onClick(String item); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/dialog/CustomDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.dialog; 2 | import android.annotation.SuppressLint; 3 | import android.app.AlertDialog; 4 | import android.app.Dialog; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import androidx.annotation.NonNull; 12 | import androidx.fragment.app.DialogFragment; 13 | import com.player.R; 14 | 15 | public class CustomDialogFragment extends DialogFragment implements View.OnClickListener{ 16 | private final ClickSureListener clickSureListener; 17 | private int layoutId; 18 | private final String title; 19 | private View toInsertLayout; 20 | TextView sureBtnView; 21 | @NonNull 22 | @Override 23 | public Dialog onCreateDialog(Bundle savedInstanceState) { 24 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 25 | LayoutInflater inflater = getActivity().getLayoutInflater(); 26 | View view = inflater.inflate(R.layout.custom_dialog, null); 27 | builder.setView(view).setPositiveButton(null,null).setCancelable(true);; 28 | view.findViewById(R.id.dialog_sure).setOnClickListener(this); 29 | view.findViewById(R.id.dialog_cancle).setOnClickListener(this); 30 | sureBtnView = view.findViewById(R.id.dialog_sure); 31 | if(toInsertLayout == null){// 加载要插入的布局 32 | toInsertLayout = inflater.inflate(layoutId, null); 33 | } 34 | // 找到要插入的容器 35 | ViewGroup insertPoint = view.findViewById(R.id.insert_point); 36 | // 将要插入的布局添加到容器中 37 | insertPoint.addView(toInsertLayout); 38 | TextView titleView = view.findViewById(R.id.dialog_title); 39 | if(!"".equals(title) && title != null){ 40 | titleView.setText(title); 41 | } 42 | return builder.create(); 43 | } 44 | 45 | public CustomDialogFragment(int layoutId,String title,ClickSureListener clickSureListener){ 46 | this.layoutId = layoutId; 47 | this.title = title; 48 | this.clickSureListener = clickSureListener; 49 | } 50 | 51 | public CustomDialogFragment(View toInsertLayout,String title,ClickSureListener clickSureListener){ 52 | this.toInsertLayout = toInsertLayout; 53 | this.title = title; 54 | this.clickSureListener = clickSureListener; 55 | } 56 | 57 | @SuppressLint("NonConstantResourceId") 58 | @Override 59 | public void onClick(View v) { 60 | switch (v.getId()){ 61 | case R.id.dialog_sure: 62 | clickSureListener.onSure(); 63 | dismiss(); 64 | break; 65 | case R.id.dialog_cancle: 66 | dismiss(); 67 | } 68 | } 69 | 70 | public TextView getSureBtn() { 71 | return sureBtnView; 72 | } 73 | 74 | public interface ClickSureListener { 75 | void onSure(); 76 | } 77 | } 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/dialog/DatePickerFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.dialog; 2 | 3 | import android.app.DatePickerDialog; 4 | import android.app.Dialog; 5 | import android.os.Bundle; 6 | import androidx.fragment.app.DialogFragment; 7 | 8 | public class DatePickerFragment extends DialogFragment { 9 | private int year; 10 | private int month; 11 | private int day; 12 | private final DatePickerFragment.CheckListener checkListener; 13 | 14 | @Override 15 | public Dialog onCreateDialog(Bundle savedInstanceState) { 16 | 17 | return new DatePickerDialog(getActivity(), (view, year1, month1, day1) -> { 18 | // 处理日期选择事件 19 | // 例如:显示选择的日期 20 | String selectedDate = String.format("%d-%02d-%02d", year1, month1 + 1, day1); 21 | // Toast.makeText(getActivity(), selectedDate, Toast.LENGTH_SHORT).show(); 22 | checkListener.onCheck(selectedDate); 23 | }, year, month, day); 24 | } 25 | public DatePickerFragment(int year, int month, int day,CheckListener checkListener){ 26 | this.year = year; 27 | this.month = month; 28 | this.day = day; 29 | this.checkListener = checkListener; 30 | } 31 | 32 | public interface CheckListener{ 33 | void onCheck(String selectedDate); 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/dialog/PlugCamera.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.dialog; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.provider.MediaStore; 8 | import androidx.core.app.ActivityCompat; 9 | 10 | public class PlugCamera { 11 | String [] menu = {"相机","相册"}; 12 | Activity activity; 13 | Context context; 14 | private String checkItem; 15 | public static final int REQUEST_CODE_CAMERA = 2; 16 | 17 | 18 | public void showCamera() { 19 | new BottomMenu(menu,item->{ 20 | checkItem = item; 21 | if("相机".equals(item)){ 22 | ActivityCompat.requestPermissions(activity, 23 | new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, 24 | Manifest.permission.READ_EXTERNAL_STORAGE, 25 | Manifest.permission.CAMERA, 26 | Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS} 27 | , REQUEST_CODE_CAMERA); 28 | Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 29 | activity.startActivityForResult(intent, REQUEST_CODE_CAMERA); 30 | }else{ 31 | Intent intent = new Intent(Intent.ACTION_PICK, null); 32 | intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); 33 | activity.startActivityForResult(intent, REQUEST_CODE_CAMERA); 34 | } 35 | }).showBottomMenu(context); 36 | } 37 | 38 | public PlugCamera(Context context,Activity activity){ 39 | this.context = context; 40 | this.activity = activity; 41 | } 42 | 43 | public String getCheck(){ 44 | return checkItem; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/entity/CategoryEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.entity; 2 | 3 | public class CategoryEntity { 4 | private String category; 5 | private String classify; 6 | 7 | public String getCategory() { 8 | return category; 9 | } 10 | 11 | public void setCategory(String category) { 12 | this.category = category; 13 | } 14 | 15 | public String getClassify() { 16 | return classify; 17 | } 18 | 19 | public void setClassify(String classify) { 20 | this.classify = classify; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/entity/EditEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.entity; 2 | 3 | public class EditEntity { 4 | private String title; 5 | private String field; 6 | private String value; 7 | private Boolean require; 8 | 9 | public String getField() { 10 | return field; 11 | } 12 | 13 | public void setField(String field) { 14 | this.field = field; 15 | } 16 | 17 | public String getTitle() { 18 | return title; 19 | } 20 | 21 | public void setTitle(String title) { 22 | this.title = title; 23 | } 24 | 25 | public String getValue() { 26 | return value; 27 | } 28 | 29 | public void setValue(String value) { 30 | this.value = value; 31 | } 32 | 33 | public Boolean getRequire() { 34 | return require; 35 | } 36 | 37 | public void setRequire(Boolean require) { 38 | this.require = require; 39 | } 40 | 41 | public EditEntity(){} 42 | 43 | public EditEntity(String title, String field, String value, Boolean require) { 44 | this.title = title; 45 | this.field = field; 46 | this.value = value; 47 | this.require = require; 48 | } 49 | 50 | public void setField(String key,String value){ 51 | // = value; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/entity/MovieStarEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.entity; 2 | 3 | import java.util.Date; 4 | 5 | public class MovieStarEntity { 6 | private Long id;//主键 7 | private String starName;//演员名称 8 | private String img;//演员图片地址 9 | private String localImg;//演员本地本地图片 10 | private Date createTime;//创建时间 11 | private Date updateTime;//创建时间 12 | private String movieId;//电影的id 13 | private String role;//角色 14 | private String href;//演员的豆瓣链接地址 15 | private String works;//代表作 16 | 17 | public Long getId() { 18 | return id; 19 | } 20 | 21 | public void setId(Long id) { 22 | this.id = id; 23 | } 24 | 25 | public String getStarName() { 26 | return starName; 27 | } 28 | 29 | public void setStarName(String starName) { 30 | this.starName = starName; 31 | } 32 | 33 | public String getImg() { 34 | return img; 35 | } 36 | 37 | public void setImg(String img) { 38 | this.img = img; 39 | } 40 | 41 | public String getLocalImg() { 42 | return localImg; 43 | } 44 | 45 | public void setLocalImg(String localImg) { 46 | this.localImg = localImg; 47 | } 48 | 49 | public Date getCreateTime() { 50 | return createTime; 51 | } 52 | 53 | public void setCreateTime(Date createTime) { 54 | this.createTime = createTime; 55 | } 56 | 57 | public Date getUpdateTime() { 58 | return updateTime; 59 | } 60 | 61 | public void setUpdateTime(Date updateTime) { 62 | this.updateTime = updateTime; 63 | } 64 | 65 | public String getMovieId() { 66 | return movieId; 67 | } 68 | 69 | public void setMovieId(String movieId) { 70 | this.movieId = movieId; 71 | } 72 | 73 | public String getRole() { 74 | return role; 75 | } 76 | 77 | public void setRole(String role) { 78 | this.role = role; 79 | } 80 | 81 | public String getHref() { 82 | return href; 83 | } 84 | 85 | public void setHref(String href) { 86 | this.href = href; 87 | } 88 | 89 | public String getWorks() { 90 | return works; 91 | } 92 | 93 | public void setWorks(String works) { 94 | this.works = works; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/entity/MovieUrlEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.entity; 2 | 3 | public class MovieUrlEntity { 4 | private int id;//主键 5 | private String movieName;//电影名称 6 | private Long movieId;//对应的电影的id 7 | private String href;//源地址 8 | private String label;//集数 9 | private String createTime;//创建时间 10 | private String updateTime;//播放地址 11 | private String url;//播放地址 12 | private int playGroup;//播放分组,1, 2 13 | 14 | public int getId() { 15 | return id; 16 | } 17 | 18 | public void setId(int id) { 19 | this.id = id; 20 | } 21 | 22 | public String getMovieName() { 23 | return movieName; 24 | } 25 | 26 | public void setMovieName(String movieName) { 27 | this.movieName = movieName; 28 | } 29 | 30 | public Long getMovieId() { 31 | return movieId; 32 | } 33 | 34 | public void setMovieId(Long movieId) { 35 | this.movieId = movieId; 36 | } 37 | 38 | public String getHref() { 39 | return href; 40 | } 41 | 42 | public void setHref(String href) { 43 | this.href = href; 44 | } 45 | 46 | public String getLabel() { 47 | return label; 48 | } 49 | 50 | public void setLabel(String label) { 51 | this.label = label; 52 | } 53 | 54 | public String getCreateTime() { 55 | return createTime; 56 | } 57 | 58 | public void setCreateTime(String createTime) { 59 | this.createTime = createTime; 60 | } 61 | 62 | public String getUpdateTime() { 63 | return updateTime; 64 | } 65 | 66 | public void setUpdateTime(String updateTime) { 67 | this.updateTime = updateTime; 68 | } 69 | 70 | public String getUrl() { 71 | return url; 72 | } 73 | 74 | public void setUrl(String url) { 75 | this.url = url; 76 | } 77 | 78 | public int getPlayGroup() { 79 | return playGroup; 80 | } 81 | 82 | public void setPlayGroup(int playGroup) { 83 | this.playGroup = playGroup; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/entity/SearchWordEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.entity; 2 | 3 | import androidx.room.ColumnInfo; 4 | import androidx.room.Entity; 5 | import androidx.room.Ignore; 6 | import androidx.room.PrimaryKey; 7 | 8 | import java.util.Date; 9 | 10 | 11 | @Entity(tableName = "search_word") 12 | public class SearchWordEntity { 13 | // @Ignore 14 | @PrimaryKey(autoGenerate = true) 15 | private int id; 16 | 17 | // @Ignore 18 | @ColumnInfo(name = "movie_name") 19 | private String movieName; 20 | 21 | // @Ignore 22 | @ColumnInfo(name = "classify") 23 | private String classify; 24 | 25 | // @Ignore 26 | @ColumnInfo(name = "creat_time") 27 | private Date creatTime; 28 | 29 | public int getId() { 30 | return id; 31 | } 32 | 33 | public void setId(int id) { 34 | this.id = id; 35 | } 36 | 37 | public String getMovieName() { 38 | return movieName; 39 | } 40 | 41 | public void setMovieName(String movieName) { 42 | this.movieName = movieName; 43 | } 44 | 45 | public String getClassify() { 46 | return classify; 47 | } 48 | 49 | public void setClassify(String classify) { 50 | this.classify = classify; 51 | } 52 | 53 | public Date getCreatTime() { 54 | return creatTime; 55 | } 56 | 57 | public void setCreatTime(Date creatTime) { 58 | this.creatTime = creatTime; 59 | } 60 | 61 | @Ignore 62 | public SearchWordEntity(int id, String movieName, String classify, Date creatTime) { 63 | this.id = id; 64 | this.movieName = movieName; 65 | this.classify = classify; 66 | this.creatTime = creatTime; 67 | } 68 | 69 | public SearchWordEntity(){} 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/entity/UserEntity.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.entity; 2 | 3 | public class UserEntity { 4 | private String userId; 5 | private String createDate; 6 | private String updateDate; 7 | private String username; 8 | private String telephone; 9 | private String email; 10 | private String avater; 11 | private String birthday; 12 | private String sex; 13 | private String role; 14 | private String sign; 15 | private String password; 16 | private String region; 17 | 18 | public String getUserId() { 19 | return userId; 20 | } 21 | 22 | public void setUserId(String userId) { 23 | this.userId = userId; 24 | } 25 | 26 | public String getCreateDate() { 27 | return createDate; 28 | } 29 | 30 | public void setCreateDate(String createDate) { 31 | this.createDate = createDate; 32 | } 33 | 34 | public String getUpdateDate() { 35 | return updateDate; 36 | } 37 | 38 | public void setUpdateDate(String updateDate) { 39 | this.updateDate = updateDate; 40 | } 41 | 42 | public String getUsername() { 43 | return username; 44 | } 45 | 46 | public void setUsername(String username) { 47 | this.username = username; 48 | } 49 | 50 | public String getTelephone() { 51 | return telephone; 52 | } 53 | 54 | public void setTelephone(String telephone) { 55 | this.telephone = telephone; 56 | } 57 | 58 | public String getEmail() { 59 | return email; 60 | } 61 | 62 | public void setEmail(String email) { 63 | this.email = email; 64 | } 65 | 66 | public String getAvater() { 67 | return avater; 68 | } 69 | 70 | public void setAvater(String avater) { 71 | this.avater = avater; 72 | } 73 | 74 | public String getBirthday() { 75 | return birthday; 76 | } 77 | 78 | public void setBirthday(String birthday) { 79 | this.birthday = birthday; 80 | } 81 | 82 | public String getSex() { 83 | return sex; 84 | } 85 | 86 | public void setSex(String sex) { 87 | this.sex = sex; 88 | } 89 | 90 | public String getRole() { 91 | return role; 92 | } 93 | 94 | public void setRole(String role) { 95 | this.role = role; 96 | } 97 | 98 | public String getSign() { 99 | return sign; 100 | } 101 | 102 | public void setSign(String sign) { 103 | this.sign = sign; 104 | } 105 | 106 | public String getPassword() { 107 | return password; 108 | } 109 | 110 | public void setPassword(String password) { 111 | this.password = password; 112 | } 113 | 114 | public String getRegion() { 115 | return region; 116 | } 117 | 118 | public void setRegion(String region) { 119 | this.region = region; 120 | } 121 | 122 | @Override 123 | public String toString() { 124 | return "UserEntity{" + 125 | "userId='" + userId + '\'' + 126 | ", createDate='" + createDate + '\'' + 127 | ", updateDate='" + updateDate + '\'' + 128 | ", username='" + username + '\'' + 129 | ", telephone='" + telephone + '\'' + 130 | ", email='" + email + '\'' + 131 | ", avater='" + avater + '\'' + 132 | ", birthday='" + birthday + '\'' + 133 | ", sex='" + sex + '\'' + 134 | ", role='" + role + '\'' + 135 | ", sign='" + sign + '\'' + 136 | ", password='" + password + '\'' + 137 | ", region='" + region + '\'' + 138 | '}'; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/fragment/CategoryFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import androidx.annotation.Nullable; 10 | import androidx.fragment.app.Fragment; 11 | import androidx.recyclerview.widget.LinearLayoutManager; 12 | import androidx.recyclerview.widget.RecyclerView; 13 | 14 | 15 | import com.alibaba.fastjson.JSON; 16 | import com.player.R; 17 | import com.player.movie.adapter.CategoryRecyclerViewAdapter; 18 | import com.player.movie.entity.MovieEntity; 19 | import com.player.http.RequestUtils; 20 | import com.player.http.ResultEntity; 21 | import java.util.List; 22 | 23 | import retrofit2.Call; 24 | import retrofit2.Callback; 25 | import retrofit2.Response; 26 | 27 | public class CategoryFragment extends Fragment { 28 | private View view; 29 | @Nullable 30 | @Override 31 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 32 | view = inflater.inflate(R.layout.category_fragment,container,false); 33 | Bundle bundle = getArguments(); 34 | //这里就拿到了之前传递的参数 35 | String category = bundle.getString("category"); 36 | String classify = bundle.getString("classify"); 37 | TextView textView = view.findViewById(R.id.category_title).findViewById(R.id.module_title); 38 | textView.setText(category); 39 | getCategoryData(category,classify); 40 | return view; 41 | } 42 | 43 | public void getCategoryData(String category,String classify){ 44 | Call categoryListService = RequestUtils.getMovieInstance().getCategoryList(category,classify); 45 | categoryListService.enqueue(new Callback() { 46 | @Override 47 | public void onResponse(Call call, Response response) { 48 | List movieEntityList = JSON.parseArray(JSON.toJSONString(response.body().getData()),MovieEntity.class); 49 | CategoryRecyclerViewAdapter recyclerViewAdapter = new CategoryRecyclerViewAdapter(movieEntityList,getContext()); 50 | LinearLayoutManager layoutManager=new LinearLayoutManager(getContext()); //LinearLayoutManager中定制了可扩展的布局排列接口,子类按照接口中的规范来实现就可以定制出不同排雷方式的布局了 51 | layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); 52 | RecyclerView recyclerView = view.findViewById(R.id.movie_recycler_view); 53 | recyclerView.setLayoutManager(layoutManager); 54 | recyclerView.setAdapter(recyclerViewAdapter); 55 | } 56 | 57 | @Override 58 | public void onFailure(Call call, Throwable t) { 59 | System.out.println("错误"); 60 | } 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/fragment/LikeMovieFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import androidx.annotation.Nullable; 10 | import androidx.fragment.app.Fragment; 11 | import androidx.recyclerview.widget.LinearLayoutManager; 12 | import androidx.recyclerview.widget.RecyclerView; 13 | 14 | import com.alibaba.fastjson.JSON; 15 | import com.player.R; 16 | import com.player.movie.adapter.CategoryRecyclerViewAdapter; 17 | import com.player.movie.entity.MovieEntity; 18 | import com.player.http.RequestUtils; 19 | import com.player.http.ResultEntity; 20 | 21 | import java.util.List; 22 | 23 | import retrofit2.Call; 24 | import retrofit2.Callback; 25 | import retrofit2.Response; 26 | 27 | public class LikeMovieFragment extends Fragment { 28 | View view; 29 | MovieEntity movieEntity; 30 | 31 | @Nullable 32 | @Override 33 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 34 | if(view == null){ 35 | view = inflater.inflate(R.layout.fraction_like_movie,container,false); 36 | } 37 | getYourLikes(); 38 | setModuleTitle(); 39 | return view; 40 | } 41 | 42 | public LikeMovieFragment(MovieEntity movieEntity){ 43 | this.movieEntity = movieEntity; 44 | } 45 | 46 | /** 47 | * @author: wuwenqiang 48 | * @description: 设置每个模块的标题 49 | * @date: 2022-08-18 22:27 50 | */ 51 | private void setModuleTitle(){ 52 | TextView yourLikeText = view.findViewById(R.id.like_title).findViewById(R.id.module_title); 53 | yourLikeText.setText(R.string.your_like); 54 | } 55 | 56 | /** 57 | * @author: wuwenqiang 58 | * @description: 获取猜你想看 59 | * @date: 2021-12-11 12:11 60 | */ 61 | private void getYourLikes(){ 62 | String label = movieEntity.getLabel() == null ? movieEntity.getType() : movieEntity.getLabel(); 63 | Call yourLikesService; 64 | if(label == null){ 65 | String category = movieEntity.getCategory().equals("轮播") ? null : movieEntity.getCategory(); 66 | yourLikesService = RequestUtils.getMovieInstance().getTopMovieList(movieEntity.getClassify(),category); 67 | }else{ 68 | yourLikesService = RequestUtils.getMovieInstance().getYourLikes(label, movieEntity.getClassify()); 69 | } 70 | yourLikesService.enqueue(new Callback() { 71 | @Override 72 | public void onResponse(Call call, Response response) { 73 | List movieEntityList = JSON.parseArray(JSON.toJSONString(response.body().getData()), MovieEntity.class); 74 | CategoryRecyclerViewAdapter categoryRecyclerViewAdapter = new CategoryRecyclerViewAdapter(movieEntityList,getContext()); 75 | LinearLayoutManager layoutManager=new LinearLayoutManager(getContext()); //LinearLayoutManager中定制了可扩展的布局排列接口,子类按照接口中的规范来实现就可以定制出不同排雷方式的布局了 76 | layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); 77 | RecyclerView recyclerView = view.findViewById(R.id.like_recycler_view); 78 | recyclerView.setLayoutManager(layoutManager); 79 | recyclerView.setAdapter(categoryRecyclerViewAdapter); 80 | } 81 | 82 | @Override 83 | public void onFailure(Call call, Throwable t) { 84 | System.out.println("获取猜你想看失败"); 85 | } 86 | }); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/fragment/RecommendMovieFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import androidx.annotation.Nullable; 10 | import androidx.fragment.app.Fragment; 11 | import androidx.recyclerview.widget.LinearLayoutManager; 12 | import androidx.recyclerview.widget.RecyclerView; 13 | 14 | import com.alibaba.fastjson.JSON; 15 | import com.player.R; 16 | import com.player.movie.adapter.CategoryRecyclerViewAdapter; 17 | import com.player.movie.adapter.GridRecyclerViewAdapter; 18 | import com.player.movie.entity.MovieEntity; 19 | import com.player.http.RequestUtils; 20 | import com.player.http.ResultEntity; 21 | 22 | import java.util.List; 23 | 24 | import retrofit2.Call; 25 | import retrofit2.Callback; 26 | import retrofit2.Response; 27 | 28 | public class RecommendMovieFragment extends Fragment { 29 | View view; 30 | MovieEntity movieEntity; 31 | String orientation;// 方向。横向和纵向,纵向每行3个 32 | 33 | @Nullable 34 | @Override 35 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 36 | if(view == null){ 37 | view = inflater.inflate(R.layout.fraction_recommend_movie,container,false); 38 | } 39 | getRecommend(); 40 | setModuleTitle(); 41 | return view; 42 | } 43 | 44 | public RecommendMovieFragment(MovieEntity movieEntity,String orientation){ 45 | this.movieEntity = movieEntity; 46 | this.orientation = orientation; 47 | } 48 | 49 | /** 50 | * @author: wuwenqiang 51 | * @description: 设置模块的标题 52 | * @date: 2022-08-18 22:27 53 | */ 54 | private void setModuleTitle(){ 55 | TextView yourLikeText = view.findViewById(R.id.recommend_title).findViewById(R.id.module_title); 56 | yourLikeText.setText(R.string.recommend); 57 | } 58 | 59 | /** 60 | * @author: wuwenqiang 61 | * @description: 获取推荐列表 62 | * @date: 2021-12-11 12:11 63 | */ 64 | private void getRecommend(){ 65 | Call userData = RequestUtils.getMovieInstance().getRecommend(movieEntity.getClassify()); 66 | userData.enqueue(new Callback() { 67 | @Override 68 | public void onResponse(Call call, Response response) { 69 | List movieEntityList = JSON.parseArray(JSON.toJSONString(response.body().getData()), MovieEntity.class); 70 | LinearLayoutManager layoutManager=new LinearLayoutManager(getContext()); //LinearLayoutManager中定制了可扩展的布局排列接口,子类按照接口中的规范来实现就可以定制出不同排雷方式的布局了 71 | RecyclerView recyclerView = view.findViewById(R.id.recommend_recycler_view); 72 | // 横向排列 73 | if("horizontal".equals(orientation) || orientation == null){ 74 | layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); 75 | recyclerView.setLayoutManager(layoutManager); 76 | CategoryRecyclerViewAdapter categoryRecyclerViewAdapter = new CategoryRecyclerViewAdapter(movieEntityList, getContext()); 77 | recyclerView.setAdapter(categoryRecyclerViewAdapter); 78 | }else{// 纵向表格排列,每行3个 79 | layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 80 | recyclerView.setLayoutManager(layoutManager); 81 | GridRecyclerViewAdapter gridRecyclerViewAdapter = new GridRecyclerViewAdapter(movieEntityList, getContext(),recyclerView.getWidth()); 82 | recyclerView.setAdapter(gridRecyclerViewAdapter); 83 | } 84 | 85 | } 86 | 87 | @Override 88 | public void onFailure(Call call, Throwable t) { 89 | System.out.println("获取推荐列表失败"); 90 | } 91 | }); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/fragment/SearchFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.fragment; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | 12 | import androidx.annotation.Nullable; 13 | import androidx.fragment.app.Fragment; 14 | 15 | import com.alibaba.fastjson.JSON; 16 | import com.bumptech.glide.Glide; 17 | import com.makeramen.roundedimageview.RoundedImageView; 18 | import com.player.common.Constants; 19 | import com.player.movie.BaseApplication; 20 | import com.player.R; 21 | import com.player.movie.activity.SearchActivity; 22 | import com.player.movie.api.Api; 23 | import com.player.movie.entity.MovieEntity; 24 | import com.player.movie.entity.UserEntity; 25 | import com.player.http.RequestUtils; 26 | import com.player.http.ResultEntity; 27 | 28 | import retrofit2.Call; 29 | import retrofit2.Callback; 30 | import retrofit2.Response; 31 | 32 | public class SearchFragment extends Fragment { 33 | View view; 34 | LinearLayout avaterLayout; 35 | String classify; 36 | MovieEntity movieEntity; 37 | @Nullable 38 | @Override 39 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 40 | view = inflater.inflate(R.layout.fragment_search,container,false); 41 | initData(); 42 | getKeyWord(); 43 | addSearchClickListener(); 44 | return view; 45 | } 46 | 47 | public SearchFragment(String classify){ 48 | this.classify = classify; 49 | } 50 | 51 | public SearchFragment(){} 52 | 53 | private void initData(){ 54 | avaterLayout = view.findViewById(R.id.avater_layout); 55 | avaterLayout.setVisibility(View.VISIBLE); 56 | UserEntity userEntity = BaseApplication.getInstance().getUserEntity(); 57 | RoundedImageView avaterImage = view.findViewById(R.id.avater); 58 | if(userEntity.getAvater()!= null){ 59 | Glide.with(getContext()).load(Constants.HOST + userEntity.getAvater()).into(avaterImage); 60 | }else{ 61 | avaterImage.setImageResource(R.mipmap.default_avater); 62 | } 63 | } 64 | 65 | private void addSearchClickListener(){ 66 | LinearLayout searchLayout = view.findViewById(R.id.search_layout); 67 | searchLayout.setOnClickListener(listener->{ 68 | Context context = getContext(); 69 | Intent intent = new Intent(context, SearchActivity.class); 70 | intent.putExtra("movieItem",JSON.toJSONString(movieEntity)); 71 | context.startActivity(intent); 72 | }); 73 | } 74 | 75 | /** 76 | * @author: wuwenqiang 77 | * @description: 获取搜索栏关键词 78 | * @date: 2021-12-11 11:08 79 | */ 80 | public void getKeyWord(){ 81 | Call getKeyWordService = RequestUtils.getMovieInstance().getKeyWord(classify); 82 | getKeyWordService.enqueue(new Callback() { 83 | @Override 84 | public void onResponse(Call call, Response response) { 85 | movieEntity = JSON.parseObject(JSON.toJSONString(response.body().getData()), MovieEntity.class); 86 | TextView textView = avaterLayout.findViewById(R.id.search_key); 87 | textView.setText(movieEntity.getMovieName()); 88 | } 89 | 90 | @Override 91 | public void onFailure(Call call, Throwable t) { 92 | 93 | } 94 | }); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/myinterface/JavaScriptinterface.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.myinterface; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.webkit.JavascriptInterface; 6 | 7 | import com.alibaba.fastjson.JSON; 8 | import com.player.movie.BaseApplication; 9 | import com.player.movie.dialog.PlugCamera; 10 | 11 | public class JavaScriptinterface { 12 | private Context context; 13 | private Activity activity; 14 | private PlugCamera plugCamera; 15 | private String data; 16 | public JavaScriptinterface(Context context, Activity activity) { 17 | this.context= context; 18 | this.activity = activity; 19 | } 20 | 21 | /** 22 | * 与js交互时用到的方法,在js里直接调用的 23 | */ 24 | @JavascriptInterface 25 | public void chooseImages() { 26 | plugCamera = new PlugCamera(context,activity); 27 | plugCamera.showCamera(); 28 | } 29 | 30 | public String getCheck(){ 31 | return plugCamera.getCheck(); 32 | } 33 | 34 | /** 35 | * 获取token方法,与js交互时用到的方法,在js里直接调用的 36 | */ 37 | @JavascriptInterface 38 | public String getToken(){ 39 | return JSON.toJSONString(BaseApplication.getInstance().getToken()); 40 | } 41 | 42 | /** 43 | * 获取用户信息,与js交互时用到的方法,在js里直接调用的 44 | */ 45 | @JavascriptInterface 46 | public String getUserData(){ 47 | return JSON.toJSONString(BaseApplication.getInstance().getUserEntity()); 48 | } 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/myinterface/UrlClickListener.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.myinterface; 2 | 3 | import android.widget.TextView; 4 | 5 | public interface UrlClickListener { 6 | void onClickListener(TextView textView); 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/receiver/UpdateUserReciver.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.receiver; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import com.alibaba.fastjson.JSON; 8 | import com.player.movie.entity.UserEntity; 9 | 10 | public class UpdateUserReciver extends BroadcastReceiver { 11 | public static final String TAG = "UpdateUserBroadcastReceiver"; 12 | 13 | private static MessageListener mMessageListener; 14 | 15 | public UpdateUserReciver() { 16 | super(); 17 | } 18 | 19 | @Override 20 | public void onReceive(Context context, Intent intent) { 21 | UserEntity userEntity = JSON.parseObject(intent.getStringExtra("userData"), UserEntity.class); 22 | mMessageListener.OnReceived(userEntity); 23 | } 24 | 25 | // 回调接口 26 | public interface MessageListener { 27 | 28 | /** 29 | * @author: wuwenqiang 30 | * @description: 接收到自己的验证码时回调 31 | * @date: 2023-04-20 23:07 32 | */ 33 | void OnReceived(UserEntity userEntity); 34 | } 35 | 36 | /** 37 | * 设置验证码接收监听 38 | * 39 | * @param messageListener 自己验证码的接受监听,接收到自己验证码时回调 40 | */ 41 | public void setOnReceivedMessageListener(MessageListener messageListener) { 42 | mMessageListener = messageListener; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/service/RequestMusicService.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.service; 2 | 3 | import com.player.http.ResultEntity; 4 | import com.player.movie.api.Api; 5 | import com.player.movie.entity.MovieEntity; 6 | import com.player.movie.entity.UserEntity; 7 | 8 | import retrofit2.Call; 9 | import retrofit2.http.Body; 10 | import retrofit2.http.GET; 11 | import retrofit2.http.POST; 12 | import retrofit2.http.PUT; 13 | import retrofit2.http.Path; 14 | import retrofit2.http.Query; 15 | 16 | public interface RequestMusicService { 17 | @GET(Api.GETUSERDATA) 18 | Call getUserData(); 19 | 20 | @GET(Api.GETCATEGORYLIST) 21 | Call getCategoryList(@Query("category")String category,@Query("classify")String classify); 22 | 23 | @GET(Api.GETALLCATEGORYLISTBYPAGENAME) 24 | Call getAllCategoryListByPageName(@Query("pageName")String pageName); 25 | 26 | @GET(Api.GETKEYWORD) 27 | Call getKeyWord(@Query("classify")String classify); 28 | 29 | @GET(Api.GETUSERMSG) 30 | Call getUserMsg(); 31 | 32 | @GET(Api.GETPLAYRECORD) 33 | Call getPlayRecord(); 34 | 35 | @POST(Api.SAVEPLAYRECORD) 36 | Call savePlayRecord(@Body MovieEntity movieEntity); 37 | 38 | @GET(Api.GETVIEWRECORD) 39 | Call getViewRecord(); 40 | 41 | @POST(Api.SAVEVIEWRECORD) 42 | Call saveViewRecord(@Body MovieEntity movieEntity); 43 | 44 | @GET(Api.GETFAVORITE) 45 | Call getFavoriteList(); 46 | 47 | @GET(Api.GETSTAR) 48 | Call getStarList(@Path("movieId") String movieId); 49 | 50 | @GET(Api.GETYOURLIKES) 51 | Call getYourLikes(@Query("labels") String labels,@Query("classify") String classify); 52 | 53 | @GET(Api.GETRECOMMEND) 54 | Call getRecommend(@Query("classify") String classify); 55 | 56 | @GET(Api.GETTOPMOVIELIST) 57 | Call getTopMovieList(@Query("classify") String classify,@Query("category") String category); 58 | 59 | @GET(Api.GETMOVIEURL) 60 | Call getMovieUrl(@Query("movieId") Long movieId); 61 | 62 | // 搜索 63 | @GET(Api.GETSEARCHRESULT) 64 | Call search( 65 | @Query("classify") String classify, 66 | @Query("category") String category, 67 | @Query("label") String label, 68 | @Query("star") String star, 69 | @Query("director") String director, 70 | @Query("keyword") String keyword, 71 | @Query("pageSize") int pageSize, 72 | @Query("pageNum") int pageNum 73 | 74 | ); 75 | 76 | @PUT(Api.UPDATEUSER) 77 | Call updateUser(@Body UserEntity userEntity); 78 | 79 | @POST(Api.LOGIN) 80 | Call login(@Body UserEntity userEntity); 81 | 82 | @POST(Api.REGISTER) 83 | Call register(@Body UserEntity userEntity); 84 | 85 | @GET(Api.GETUSERBYID) 86 | Call getUserById(@Query("userId") String userId); 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/utils/ActivityCollectorUtil.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.utils; 2 | 3 | import android.app.Activity; 4 | 5 | import java.util.ArrayList; 6 | 7 | public class ActivityCollectorUtil { 8 | public static ArrayList mActivityList = new ArrayList(); 9 | 10 | /** 11 | * onCreate()时添加 12 | * @param activity 13 | */ 14 | public static void addActivity(Activity activity){ 15 | //判断集合中是否已经添加,添加过的则不再添加 16 | if (!mActivityList.contains(activity)){ 17 | mActivityList.add(activity); 18 | } 19 | } 20 | 21 | /** 22 | * onDestroy()时删除 23 | * @param activity 24 | */ 25 | public static void removeActivity(Activity activity){ 26 | mActivityList.remove(activity); 27 | } 28 | 29 | /** 30 | * 关闭所有Activity 31 | */ 32 | public static void finishAllActivity(){ 33 | for (Activity activity : mActivityList){ 34 | if (!activity.isFinishing()){ 35 | activity.finish(); 36 | } 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/utils/CMAppGlideModule.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.utils; 2 | 3 | import com.bumptech.glide.annotation.GlideModule; 4 | import com.bumptech.glide.module.AppGlideModule; 5 | @GlideModule 6 | public class CMAppGlideModule extends AppGlideModule { 7 | @Override 8 | public boolean isManifestParsingEnabled() { 9 | return false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/utils/CommonUtils.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.utils; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.util.Base64; 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.IOException; 9 | import java.util.regex.Pattern; 10 | 11 | public class CommonUtils { 12 | public static final int dip2px(Context context,int resId){ 13 | float scale = context.getResources().getDisplayMetrics().density; 14 | float dpValue = Float.parseFloat(Pattern.compile("[^0-9.]").matcher(context.getResources().getString(resId)).replaceAll("").trim()); 15 | return (int)(dpValue * scale + 0.5f); 16 | } 17 | 18 | public static final int dip2px(Context context,float dpValue){ 19 | float scale = context.getResources().getDisplayMetrics().density; 20 | return (int)(dpValue * scale + 0.5f); 21 | } 22 | 23 | /** 24 | * @author: wuwenqiang 25 | * @description: 跳转到编辑页面 26 | * @date: 2022-12-30 22:37 27 | */ 28 | public static final String bitmapToBase64(Bitmap bitmap) { 29 | String result = null; 30 | ByteArrayOutputStream baos = null; 31 | try { 32 | if (bitmap != null) { 33 | baos = new ByteArrayOutputStream(); 34 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 35 | 36 | baos.flush(); 37 | baos.close(); 38 | 39 | byte[] bitmapBytes = baos.toByteArray(); 40 | result = Base64.encodeToString(bitmapBytes, Base64.NO_WRAP); 41 | } 42 | } catch (IOException e) { 43 | e.printStackTrace(); 44 | } finally { 45 | try { 46 | if (baos != null) { 47 | baos.flush(); 48 | baos.close(); 49 | } 50 | } catch (IOException e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | return result; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/utils/Converters.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.utils; 2 | 3 | import androidx.room.TypeConverter; 4 | 5 | import java.util.Date; 6 | 7 | public class Converters { 8 | @TypeConverter 9 | public static Date fromTimestamp(Long value) { 10 | return value == null ? null : new Date(value); 11 | } 12 | @TypeConverter 13 | public static Long dateToTimestamp(Date date) { 14 | return date == null ? null : date.getTime(); 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/utils/MD5.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.utils; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | public class MD5 { 9 | /** 10 | * 获取字符串对应的MD5 11 | * @param str 12 | * @return 13 | */ 14 | public static String getStrMD5(String str) { 15 | String ret=""; 16 | if (!TextUtils.isEmpty(str)) { 17 | try { 18 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 19 | char[] charArray = str.toCharArray(); 20 | byte[] byteArray = new byte[charArray.length]; 21 | for (int i = 0; i < charArray.length; i++) { 22 | byteArray[i] = (byte) charArray[i]; 23 | } 24 | byte[] md5Bytes = md5.digest(byteArray); 25 | StringBuilder hexValue = new StringBuilder(); 26 | for (int i = 0; i < md5Bytes.length; i++) { 27 | int val = ((int) md5Bytes[i]) & 0xff; 28 | if (val < 16) { 29 | hexValue.append("0"); 30 | } 31 | hexValue.append(Integer.toHexString(val)); 32 | } 33 | ret= hexValue.toString().toUpperCase(); 34 | } catch (NoSuchAlgorithmException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | return ret; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/utils/SharedPreferencesUtils.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | /** 7 | * SharedPreferences的一个工具类,调用setParam就能保存String, Integer, Boolean, Float, Long类型的参数 8 | * 同样调用getParam就能获取到保存在手机里面的数据 9 | * @author xiaanming 10 | * 11 | */ 12 | public class SharedPreferencesUtils { 13 | /** 14 | * 保存在手机里面的文件名 15 | */ 16 | private static final String FILE_NAME = "share_date"; 17 | 18 | 19 | /** 20 | * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 21 | * @param key 22 | * @param object 23 | */ 24 | public static void setParam(Context context,String key, Object object){ 25 | String type = object.getClass().getSimpleName(); 26 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); 27 | SharedPreferences.Editor editor = sp.edit(); 28 | 29 | if("String".equals(type)){ 30 | editor.putString(key, (String)object); 31 | } 32 | else if("Integer".equals(type)){ 33 | editor.putInt(key, (Integer)object); 34 | } 35 | else if("Boolean".equals(type)){ 36 | editor.putBoolean(key, (Boolean)object); 37 | } 38 | else if("Float".equals(type)){ 39 | editor.putFloat(key, (Float)object); 40 | } 41 | else if("Long".equals(type)){ 42 | editor.putLong(key, (Long)object); 43 | } 44 | 45 | editor.commit(); 46 | } 47 | 48 | 49 | /** 50 | * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 51 | * @param key 52 | * @param defaultObject 53 | * @return 54 | */ 55 | public static Object getParam(Context context,String key, Object defaultObject){ 56 | String type = defaultObject.getClass().getSimpleName(); 57 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); 58 | 59 | if("String".equals(type)){ 60 | return sp.getString(key, (String)defaultObject); 61 | } 62 | else if("Integer".equals(type)){ 63 | return sp.getInt(key, (Integer)defaultObject); 64 | } 65 | else if("Boolean".equals(type)){ 66 | return sp.getBoolean(key, (Boolean)defaultObject); 67 | } 68 | else if("Float".equals(type)){ 69 | return sp.getFloat(key, (Float)defaultObject); 70 | } 71 | else if("Long".equals(type)){ 72 | return sp.getLong(key, (Long)defaultObject); 73 | } 74 | 75 | return null; 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/view/MyImageView.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.os.Handler; 7 | import android.os.Message; 8 | import android.util.AttributeSet; 9 | import android.widget.Toast; 10 | 11 | import androidx.appcompat.widget.AppCompatImageView; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.net.HttpURLConnection; 16 | import java.net.URL; 17 | 18 | public class MyImageView extends AppCompatImageView { 19 | public static final int GET_DATA_SUCCESS = 1; 20 | public static final int NETWORK_ERROR = 2; 21 | public static final int SERVER_ERROR = 3; 22 | 23 | //子线程不能操作UI,通过Handler设置图片 24 | private Handler handler = new Handler() { 25 | @Override 26 | public void handleMessage(Message msg) { 27 | switch (msg.what){ 28 | case GET_DATA_SUCCESS: 29 | Bitmap bitmap = (Bitmap) msg.obj; 30 | setImageBitmap(bitmap); 31 | break; 32 | case NETWORK_ERROR: 33 | Toast.makeText(getContext(),"加载图片失败", Toast.LENGTH_SHORT).show(); 34 | break; 35 | case SERVER_ERROR: 36 | Toast.makeText(getContext(),"服务器发生错误", Toast.LENGTH_SHORT).show(); 37 | break; 38 | } 39 | } 40 | }; 41 | 42 | public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) { 43 | super(context, attrs, defStyleAttr); 44 | } 45 | 46 | public MyImageView(Context context) { 47 | super(context); 48 | } 49 | 50 | public MyImageView(Context context, AttributeSet attrs) { 51 | super(context, attrs); 52 | } 53 | 54 | //设置网络图片 55 | public void setImageURL(final String path) { 56 | //开启一个线程用于联网 57 | new Thread() { 58 | @Override 59 | public void run() { 60 | try { 61 | //把传过来的路径转成URL 62 | URL url = new URL(path); 63 | //获取连接 64 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 65 | //使用GET方法访问网络 66 | connection.setRequestMethod("GET"); 67 | //超时时间为10秒 68 | connection.setConnectTimeout(10000); 69 | //获取返回码 70 | int code = connection.getResponseCode(); 71 | if (code == 200) { 72 | InputStream inputStream = connection.getInputStream(); 73 | //使用工厂把网络的输入流生产Bitmap 74 | Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 75 | //利用Message把图片发给Handler 76 | Message msg = Message.obtain(); 77 | msg.obj = bitmap; 78 | msg.what = GET_DATA_SUCCESS; 79 | handler.sendMessage(msg); 80 | inputStream.close(); 81 | }else { 82 | //服务启发生错误 83 | handler.sendEmptyMessage(SERVER_ERROR); 84 | } 85 | } catch (IOException e) { 86 | e.printStackTrace(); 87 | //网络连接错误 88 | handler.sendEmptyMessage(NETWORK_ERROR); 89 | } 90 | } 91 | }.start(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/view/NoScrollGridView.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.GridView; 6 | 7 | public class NoScrollGridView extends GridView { 8 | public NoScrollGridView(Context context) { 9 | super(context); 10 | } 11 | public NoScrollGridView(Context context, AttributeSet attrs) { 12 | super(context, attrs); 13 | } 14 | 15 | @Override 16 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 17 | int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); 18 | super.onMeasure(widthMeasureSpec, expandSpec); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/view/ReflectHelper.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.view; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.Hashtable; 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * @desc 通过反射来动态调用get 和 set 方法 9 | */ 10 | public class ReflectHelper { 11 | private Class cls; 12 | /** 13 | * 传过来的对象 14 | */ 15 | private Object obj; 16 | private Hashtable getMethods = null; 17 | private Hashtable setMethods = null; 18 | 19 | public ReflectHelper(Object o) { 20 | obj = o; 21 | initMethods(); 22 | } 23 | 24 | public void initMethods() { 25 | getMethods = new Hashtable(); 26 | setMethods = new Hashtable(); 27 | cls = obj.getClass(); 28 | Method[] methods = cls.getMethods(); 29 | // 定义正则表达式,从方法中过滤出getter / setter 函数. 30 | String gs = "get(\\w+)"; 31 | Pattern getM = Pattern.compile(gs); 32 | String ss = "set(\\w+)"; 33 | Pattern setM = Pattern.compile(ss); 34 | // 把方法中的"set" 或者 "get" 去掉,$1匹配第一个 35 | String rapl = "$1"; 36 | String param; 37 | for (int i = 0; i < methods.length; ++i) { 38 | Method m = methods[i]; 39 | String methodName = m.getName(); 40 | if (Pattern.matches(gs, methodName)) { 41 | param = getM.matcher(methodName).replaceAll(rapl).toLowerCase(); 42 | getMethods.put(param, m); 43 | } else if (Pattern.matches(ss, methodName)) { 44 | param = setM.matcher(methodName).replaceAll(rapl).toLowerCase(); 45 | setMethods.put(param, m); 46 | } else { 47 | } 48 | } 49 | } 50 | 51 | public boolean setMethodValue(String property, Object object) { 52 | Method m = setMethods.get(property.toLowerCase()); 53 | if (m != null) { 54 | try { 55 | // 调用目标类的setter函数 56 | m.invoke(obj, object); 57 | return true; 58 | } catch (Exception ex) { 59 | ex.printStackTrace(); 60 | return false; 61 | } 62 | } 63 | return false; 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/movie/view/WrapContentHeightViewPager.java: -------------------------------------------------------------------------------- 1 | package com.player.movie.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | 7 | import androidx.viewpager.widget.ViewPager; 8 | 9 | public class WrapContentHeightViewPager extends ViewPager { 10 | /** 11 | * Constructor 12 | * 13 | * @param context 14 | * the context 15 | */ 16 | public WrapContentHeightViewPager(Context context) { 17 | super(context); 18 | } 19 | /** 20 | * Constructor 21 | * 22 | * @param context 23 | * the context 24 | * @param attrs 25 | * the attribute set 26 | */ 27 | public WrapContentHeightViewPager(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | @Override 31 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 32 | 33 | int height = 0, childCount = getChildCount(); 34 | for (int i = 0; i < childCount; i++) { 35 | View child = getChildAt(i); 36 | child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 37 | int h = child.getMeasuredHeight(); 38 | if (h > height) 39 | height = h; 40 | } 41 | 42 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); 43 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/activity/MusicSearchActivity.java: -------------------------------------------------------------------------------- 1 | package com.player.music.activity; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.os.Bundle; 6 | 7 | import com.player.R; 8 | 9 | public class MusicSearchActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_music_search); 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/api/Api.java: -------------------------------------------------------------------------------- 1 | package com.player.music.api; 2 | 3 | public class Api { 4 | public static final String GETKEYWORDMUSIC = "/service/myMusic/getKeywordMusic";//获取搜索关键词 5 | public static final String GETMUSICCLASSIFY = "/service/myMusic/getMusicClassify";//获取分类歌曲 6 | public static final String GETMUSICLISTBYCLASSIFYID = "/service/myMusic/getMusicListByClassifyId";//获取推荐音乐列表 7 | public static final String GETSINGERLIST= "/service/myMusic/getSingerList";// 获取歌手列表 8 | public static final String GETCIRCLELISTBYTYPE= "/service/circle/getCircleListByType";// 获取歌手列表 9 | public static final String GETMUSICPLAYMENU= "/service/myMusic-getway/getMusicPlayMenu";// 获取我的歌单 10 | public static final String GETMYSINGER= "/service/myMusic-getway/getMySinger";// 获取我关注的歌手 11 | public static final String GETMUSICRECORD= "/service/myMusic-getway/getMusicRecord";// 获取播放记录 12 | public static final String INSERTMUSICRECORD= "/service/myMusic-getway/insertLog";// 记录播放日志 13 | public static final String INSERTMUSICFAVORITE= "/service/myMusic-getway/insertMusicFavorite";// 插入收藏 14 | public static final String DELETEMUSICFAVORITE= "/service/myMusic-getway/deleteMusicFavorite/";// 删除收藏 15 | public static final String QUERYMUSICFAVORITE= "/service/myMusic-getway/queryMusicFavorite";// 查询收藏 16 | public static final String SEARCHMUSIC= "/service/myMusic/searchMusic";// 音乐搜索 17 | public static final String GETSINGERCATEGORY="/service/myMusic/getSingerCategory";// 获取歌手分类 18 | public static final String SAVELIKE="/service/social-getway/saveLike";// 添加点赞 19 | public static final String DELETELIKE="/service/social-getway/deleteLike";// 删除点赞 20 | public static final String INSERTCOMMENT="/service/social-getway/insertComment";// 新增评论 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/fragment/MusicCircleFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.music.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | 11 | import com.player.R; 12 | 13 | public class MusicCircleFragment extends Fragment { 14 | boolean isInit = false; 15 | View view; 16 | 17 | @Nullable 18 | @Override 19 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 20 | if(view == null){ 21 | view = inflater.inflate(R.layout.fragment_music_circle,container,false); 22 | } 23 | return view; 24 | } 25 | 26 | /** 27 | * @author: wuwenqiang 28 | * @description: 初始化调用方法 29 | * @date: 2024-04-19 23:30 30 | */ 31 | @Override 32 | public void setUserVisibleHint(boolean isUserVisibleHint){ 33 | super.setUserVisibleHint(isUserVisibleHint); 34 | if(getUserVisibleHint() && !isInit){ 35 | isInit = true; 36 | 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/fragment/MusicHomeFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.music.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | import androidx.fragment.app.FragmentTransaction; 11 | import com.player.R; 12 | import com.player.movie.fragment.SearchFragment; 13 | 14 | public class MusicHomeFragment extends Fragment { 15 | private View view; 16 | private boolean isInit = false; 17 | FragmentTransaction transaction; 18 | @Nullable 19 | @Override 20 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 21 | if(!isInit){ 22 | view = inflater.inflate(R.layout.fragment_music_home,container,false); 23 | transaction = getFragmentManager().beginTransaction(); 24 | addSearchFraction(); 25 | isInit = true; 26 | } 27 | return view; 28 | } 29 | 30 | /** 31 | * @author: wuwenqiang 32 | * @description: 设置搜索和头像 33 | * @date: 2022-08-13 11:19 34 | */ 35 | private void addSearchFraction(){ 36 | getFragmentManager() 37 | .beginTransaction() 38 | .replace(R.id.music_search_layout,new MusicSearchFragment()) 39 | .commit(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/fragment/MusicRecommentFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.music.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import androidx.annotation.Nullable; 8 | import androidx.fragment.app.Fragment; 9 | import com.player.R; 10 | 11 | public class MusicRecommentFragment extends Fragment { 12 | boolean isInit = false; 13 | View view; 14 | 15 | @Nullable 16 | @Override 17 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 18 | if(view == null){ 19 | view = inflater.inflate(R.layout.fragment_music_recommend,container,false); 20 | } 21 | return view; 22 | } 23 | 24 | /** 25 | * @author: wuwenqiang 26 | * @description: 初始化调用方法 27 | * @date: 2024-04-19 23:27 28 | */ 29 | @Override 30 | public void setUserVisibleHint(boolean isUserVisibleHint){ 31 | super.setUserVisibleHint(isUserVisibleHint); 32 | if(getUserVisibleHint() && !isInit){ 33 | isInit = true; 34 | 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/fragment/MusicSearchFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.music.fragment; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | 12 | import androidx.annotation.Nullable; 13 | import androidx.fragment.app.Fragment; 14 | 15 | import com.alibaba.fastjson.JSON; 16 | import com.bumptech.glide.Glide; 17 | import com.makeramen.roundedimageview.RoundedImageView; 18 | import com.player.R; 19 | import com.player.common.Constants; 20 | import com.player.movie.BaseApplication; 21 | import com.player.movie.api.Api; 22 | import com.player.movie.entity.UserEntity; 23 | import com.player.http.RequestUtils; 24 | import com.player.http.ResultEntity; 25 | import com.player.music.activity.MusicSearchActivity; 26 | import com.player.music.entity.MusicEntity; 27 | 28 | import retrofit2.Call; 29 | import retrofit2.Callback; 30 | import retrofit2.Response; 31 | 32 | public class MusicSearchFragment extends Fragment { 33 | View view; 34 | LinearLayout avaterLayout; 35 | MusicEntity musicEntity; 36 | @Nullable 37 | @Override 38 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 39 | view = inflater.inflate(R.layout.fragment_music_search,container,false); 40 | initData(); 41 | getKeyWord(); 42 | addSearchClickListener(); 43 | return view; 44 | } 45 | 46 | private void initData(){ 47 | avaterLayout = view.findViewById(R.id.music_avater_layout); 48 | avaterLayout.setVisibility(View.VISIBLE); 49 | UserEntity userEntity = BaseApplication.getInstance().getUserEntity(); 50 | RoundedImageView avaterImage = view.findViewById(R.id.music_avater); 51 | if(userEntity.getAvater()!= null){ 52 | Glide.with(getContext()).load(Constants.HOST + userEntity.getAvater()).into(avaterImage); 53 | }else{ 54 | avaterImage.setImageResource(R.mipmap.default_avater); 55 | } 56 | } 57 | 58 | private void addSearchClickListener(){ 59 | LinearLayout searchLayout = view.findViewById(R.id.music_search_layout); 60 | searchLayout.setOnClickListener(listener->{ 61 | Context context = getContext(); 62 | Intent intent = new Intent(context, MusicSearchActivity.class); 63 | intent.putExtra("musicItem", JSON.toJSONString(musicEntity)); 64 | startActivity(intent); 65 | }); 66 | } 67 | 68 | /** 69 | * @author: wuwenqiang 70 | * @description: 获取搜索栏关键词 71 | * @date: 2024-04-25 23:20 72 | */ 73 | public void getKeyWord(){ 74 | Call getKeyWordService = RequestUtils.getMusicInstance().getKeywordMusic(); 75 | getKeyWordService.enqueue(new Callback() { 76 | @Override 77 | public void onResponse(Call call, Response response) { 78 | musicEntity = JSON.parseObject(JSON.toJSONString(response.body().getData()), MusicEntity.class); 79 | TextView textView = avaterLayout.findViewById(R.id.music_search_key); 80 | textView.setText(musicEntity.getSongName()); 81 | } 82 | 83 | @Override 84 | public void onFailure(Call call, Throwable t) { 85 | 86 | } 87 | }); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/fragment/MusicUserFragment.java: -------------------------------------------------------------------------------- 1 | package com.player.music.fragment; 2 | 3 | import android.content.Intent; 4 | import android.content.IntentFilter; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import androidx.annotation.Nullable; 10 | import androidx.fragment.app.Fragment; 11 | import com.player.R; 12 | 13 | 14 | public class MusicUserFragment extends Fragment { 15 | private View view; 16 | private boolean isUserVisibleHint = false; 17 | 18 | @Nullable 19 | @Override 20 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 21 | if(view == null){ 22 | view = inflater.inflate(R.layout.fragment_music_user,container,false); 23 | } 24 | if(isUserVisibleHint){// 从第三个tab页切换到第四个tab页,加载了view但可能没显示 25 | } 26 | return view; 27 | } 28 | 29 | /** 30 | * @author: wuwenqiang 31 | * @description: 初始化组件 32 | * @date: 2024-04-19 23:31 33 | */ 34 | @Override 35 | public void setUserVisibleHint(boolean isUserVisibleHint){ 36 | super.setUserVisibleHint(isUserVisibleHint); 37 | this.isUserVisibleHint = getUserVisibleHint(); 38 | if(this.isUserVisibleHint && view != null){// 从第一个tab直接切花到第四个tab页,显示了但可能没有加载view 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/player/music/service/RequestMusicService.java: -------------------------------------------------------------------------------- 1 | package com.player.music.service; 2 | import com.player.music.api.Api; 3 | import com.player.http.ResultEntity; 4 | import retrofit2.Call; 5 | import retrofit2.http.GET; 6 | import retrofit2.http.POST; 7 | import retrofit2.http.PUT; 8 | 9 | public interface RequestMusicService { 10 | @GET(Api.GETKEYWORDMUSIC) 11 | Call getKeywordMusic(); 12 | 13 | @GET(Api.GETMUSICCLASSIFY) 14 | Call getMusicClassify(); 15 | 16 | @GET(Api.GETMUSICLISTBYCLASSIFYID) 17 | Call getMusicListByClassifyId(); 18 | 19 | @GET(Api.GETSINGERLIST) 20 | Call getSingerList(); 21 | 22 | @GET(Api.GETCIRCLELISTBYTYPE) 23 | Call getCircleListByType(); 24 | 25 | @GET(Api.GETMUSICPLAYMENU) 26 | Call getMusicPlayMenu(); 27 | 28 | @POST(Api.GETMYSINGER) 29 | Call getMySinger(); 30 | 31 | @GET(Api.GETMUSICRECORD) 32 | Call getMusicRecord(); 33 | 34 | @POST(Api.INSERTMUSICRECORD) 35 | Call insertMusicRecord(); 36 | 37 | @GET(Api.INSERTMUSICFAVORITE) 38 | Call insertMusicFavorite(); 39 | 40 | @GET(Api.DELETEMUSICFAVORITE) 41 | Call deleteMusicFavorite(); 42 | 43 | @GET(Api.QUERYMUSICFAVORITE) 44 | Call queryMusicFavorite(); 45 | 46 | @GET(Api.SEARCHMUSIC) 47 | Call searchMusic(); 48 | 49 | @GET(Api.GETSINGERCATEGORY) 50 | Call getSingerCategory(); 51 | 52 | @GET(Api.SAVELIKE) 53 | Call saveLike(); 54 | 55 | // 搜索 56 | @GET(Api.DELETELIKE) 57 | Call deleteLike(); 58 | 59 | @PUT(Api.INSERTCOMMENT) 60 | Call insertComment(); 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_cancel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_cancel_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_disabled_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_sure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_sure_disabled.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_sure_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_sure_normal_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border_radius.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_radius_blue_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_radius_red_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/edit_input_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/movie_img_border_radius.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/right_border_stroke_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rounded_border_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rounded_corner_search_box.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_input_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_record_item_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sm_active_border_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sm_border_decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_left_active.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_left_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_middle_active.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_middle_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_right_active.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_right_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/title_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/top_border_stroke_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_launch.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | 21 | 27 | 33 | 39 | 40 | 41 | 48 | 54 | 63 | 64 | 65 |