├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── lite-orm-1.9.2.jar │ └── universal-image-loader-1.9.5.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── susion │ │ └── boring │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── susion │ │ │ └── boring │ │ │ ├── base │ │ │ ├── SAppApplication.java │ │ │ ├── adapter │ │ │ │ ├── BaseRVAdapter.java │ │ │ │ ├── QuickPageAdapter.java │ │ │ │ └── ViewHolder.java │ │ │ ├── entity │ │ │ │ ├── FavoriteMark.java │ │ │ │ ├── ModelTranslateContract.java │ │ │ │ └── TitleMark.java │ │ │ ├── service │ │ │ │ ├── BaseService.java │ │ │ │ └── BaseServiceContract.java │ │ │ ├── ui │ │ │ │ ├── AppInfoActivity.java │ │ │ │ ├── AuthorActivity.java │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── BaseFragment.java │ │ │ │ ├── CollectActivity.java │ │ │ │ ├── ItemHandler.java │ │ │ │ ├── ItemHandlerFactory.java │ │ │ │ ├── ListFragment.java │ │ │ │ ├── OnLastItemVisibleListener.java │ │ │ │ ├── SettingActivity.java │ │ │ │ ├── SimpleItemHandler.java │ │ │ │ ├── SplashActivity.java │ │ │ │ └── mainui │ │ │ │ │ ├── IMainUIPresenter.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── drawer │ │ │ │ │ ├── DividerMark.java │ │ │ │ │ ├── DrawerData.java │ │ │ │ │ ├── DrawerHeaderItemHandler.java │ │ │ │ │ ├── DrawerItemHandler.java │ │ │ │ │ └── MainDrawerAdapter.java │ │ │ └── view │ │ │ │ ├── IView.java │ │ │ │ ├── LoadMoreRecycleView.java │ │ │ │ ├── LoadMoreView.java │ │ │ │ ├── NestScrollView.java │ │ │ │ ├── SToolBar.java │ │ │ │ ├── SearchBar.java │ │ │ │ ├── ViewPageFragment.java │ │ │ │ └── swipebacklayout │ │ │ │ ├── SwipeBackActivity.java │ │ │ │ ├── SwipeBackActivityBase.java │ │ │ │ ├── SwipeBackActivityHelper.java │ │ │ │ ├── SwipeBackLayout.java │ │ │ │ ├── Utils.java │ │ │ │ └── ViewDragHelper.java │ │ │ ├── db │ │ │ ├── DbManager.java │ │ │ └── operate │ │ │ │ ├── DataBaseOperateContract.java │ │ │ │ ├── DbBaseOperate.java │ │ │ │ └── MusicDbOperator.java │ │ │ ├── event │ │ │ ├── AddMusicToQueueEvent.java │ │ │ ├── AddToNextPlayEvent.java │ │ │ ├── CategoryPictureLoadErrorEvent.java │ │ │ ├── ChangeSongEvent.java │ │ │ ├── EssayDeleteFromLikeEvent.java │ │ │ ├── JokeDeleteFormLikeEvent.java │ │ │ ├── PictureCategorySelectedEvent.java │ │ │ ├── PictureDeleteFormLikeEvent.java │ │ │ ├── PlayListDeleteFromLikeEvent.java │ │ │ ├── SongDeleteFromLikeEvent.java │ │ │ └── SongDeleteFromPlayQueueEvent.java │ │ │ ├── http │ │ │ ├── APIHelper.java │ │ │ ├── BaseURL.java │ │ │ ├── CommonObserver.java │ │ │ └── service │ │ │ │ ├── JokeService.java │ │ │ │ ├── MusicServices.java │ │ │ │ ├── PictureService.java │ │ │ │ └── ZhiHuService.java │ │ │ ├── music │ │ │ ├── MusicPageFragment.java │ │ │ ├── adapter │ │ │ │ └── MusicPageAdapter.java │ │ │ ├── itemhandler │ │ │ │ ├── DialogMusicIH.java │ │ │ │ ├── LocalMusicIH.java │ │ │ │ ├── MusicPageConstantIH.java │ │ │ │ ├── MusicPagePlayListIH.java │ │ │ │ ├── MusicPageTitleIH.java │ │ │ │ ├── PLayListIH.java │ │ │ │ ├── SearchMusicResultIH.java │ │ │ │ └── SimpleMusicIH.java │ │ │ ├── mvp │ │ │ │ ├── contract │ │ │ │ │ ├── FileDownContract.java │ │ │ │ │ ├── LocalMusicContract.java │ │ │ │ │ ├── MediaPlayerContract.java │ │ │ │ │ └── MusicServiceContract.java │ │ │ │ ├── model │ │ │ │ │ ├── Album.java │ │ │ │ │ ├── DownTask.java │ │ │ │ │ ├── GetPlayListResult.java │ │ │ │ │ ├── Lyric.java │ │ │ │ │ ├── LyricResult.java │ │ │ │ │ ├── MusicPageConstantItem.java │ │ │ │ │ ├── MusicSearchResult.java │ │ │ │ │ ├── PlayList.java │ │ │ │ │ ├── PlayListDetail.java │ │ │ │ │ ├── PlayListSong.java │ │ │ │ │ ├── PlayQueueSong.java │ │ │ │ │ ├── SimpleSong.java │ │ │ │ │ ├── SimpleTitle.java │ │ │ │ │ ├── Singer.java │ │ │ │ │ └── Song.java │ │ │ │ ├── presenter │ │ │ │ │ ├── ClientReceiverPresenter.java │ │ │ │ │ ├── FileDownloadPresenter.java │ │ │ │ │ ├── LocalMusicPresenter.java │ │ │ │ │ ├── MediaPlayPresenter.java │ │ │ │ │ ├── MusicModelTranslatePresenter.java │ │ │ │ │ ├── MusicPlayQueueControlPresenter.java │ │ │ │ │ ├── PlayMusicPresenter.java │ │ │ │ │ └── ServiceReceiverPresenter.java │ │ │ │ └── view │ │ │ │ │ ├── LocalMusicActivity.java │ │ │ │ │ ├── MyLikeActivity.java │ │ │ │ │ ├── PlayListActivity.java │ │ │ │ │ ├── PlayMusicActivity.java │ │ │ │ │ └── SearchMusicActivity.java │ │ │ ├── service │ │ │ │ ├── MusicPlayerService.java │ │ │ │ ├── MusicServiceInstruction.java │ │ │ │ └── action │ │ │ │ │ ├── ClientPlayControlCommand.java │ │ │ │ │ ├── ClientPlayModeCommand.java │ │ │ │ │ └── ClientPlayQueueControlCommand.java │ │ │ └── view │ │ │ │ ├── LyricView.java │ │ │ │ ├── MediaPlayerThumb.java │ │ │ │ ├── MediaSeekBar.java │ │ │ │ ├── MusicControlPanel.java │ │ │ │ ├── MusicPlayControlView.java │ │ │ │ ├── MusicPlayQueueWindow.java │ │ │ │ └── PlayOperatorView.java │ │ │ ├── read │ │ │ ├── ReadPageFragment.java │ │ │ ├── adapter │ │ │ │ └── ZhiHuDailyAdapter.java │ │ │ ├── itemhandler │ │ │ │ ├── DailyNewsDateIH.java │ │ │ │ ├── DailyNewsIH.java │ │ │ │ ├── JokeIH.java │ │ │ │ ├── PictureCategoryIH.java │ │ │ │ ├── PictureColumnIH.java │ │ │ │ ├── SimplePictureIH.java │ │ │ │ └── TopNewsIH.java │ │ │ ├── mvp │ │ │ │ ├── contract │ │ │ │ │ ├── ZhiHuDailyContract.java │ │ │ │ │ └── ZhiHuEssayContract.java │ │ │ │ ├── entity │ │ │ │ │ ├── DailyNews.java │ │ │ │ │ ├── DailyNewsDate.java │ │ │ │ │ ├── Joke.java │ │ │ │ │ ├── JokeList.java │ │ │ │ │ ├── NewsDetail.java │ │ │ │ │ ├── PictureCategoryResult.java │ │ │ │ │ ├── SimplePicture.java │ │ │ │ │ ├── SimplePictureList.java │ │ │ │ │ └── ZhiHuEssay.java │ │ │ │ ├── presenter │ │ │ │ │ ├── ZhiHuDailyNewsPresenter.java │ │ │ │ │ ├── ZhiHuEssayPresenter.java │ │ │ │ │ └── ZhiHuEssayQueuePresenter.java │ │ │ │ └── view │ │ │ │ │ ├── JokeFragment.java │ │ │ │ │ ├── NestChildViewPager.java │ │ │ │ │ ├── PictureFragment.java │ │ │ │ │ ├── PictureViewActivity.java │ │ │ │ │ ├── ZhiHuEssayActivity.java │ │ │ │ │ └── ZhiHuFragment.java │ │ │ └── view │ │ │ │ ├── BannerView.java │ │ │ │ ├── DrawScaleImageView.java │ │ │ │ ├── FixedPopupWindow.java │ │ │ │ └── PictureCategoryWindow.java │ │ │ └── utils │ │ │ ├── AlbumUtils.java │ │ │ ├── BroadcastUtils.java │ │ │ ├── FileUtils.java │ │ │ ├── ImagePipelineConfigFactory.java │ │ │ ├── Md5Utils.java │ │ │ ├── PictureLoadHelper.java │ │ │ ├── RVUtils.java │ │ │ ├── SPUtils.java │ │ │ ├── StatusBarView.java │ │ │ ├── StringUtils.java │ │ │ ├── SystemOperationUtils.java │ │ │ ├── TimeUtils.java │ │ │ ├── ToastUtils.java │ │ │ ├── TransitionHelper.java │ │ │ └── UIUtils.java │ └── res │ │ ├── anim │ │ ├── anim_dialog_enter_formbottom.xml │ │ ├── anim_dialog_exit_formbottom.xml │ │ ├── anim_window_right_entry.xml │ │ └── anim_window_right_exit.xml │ │ ├── drawable │ │ ├── bg_dialog.xml │ │ ├── bg_ripple.xml │ │ ├── bg_ripple_accent_color.xml │ │ ├── bg_ripple_toolbar.xml │ │ ├── bg_search_bar_bt.xml │ │ ├── bg_search_bar_tv.xml │ │ ├── bg_shape_corner_rectangle.xml │ │ ├── bg_shape_rect_black.xml │ │ ├── bg_transparent_ripple.xml │ │ ├── bg_view_load_more.xml │ │ ├── gradient_circle.xml │ │ ├── ic_menu_camera.xml │ │ ├── play_music_thumb.xml │ │ ├── shadow_bottom.png │ │ ├── shadow_left.png │ │ ├── shadow_right.png │ │ └── shape_search_bar_cursor.xml │ │ ├── layout │ │ ├── activity_app_info.xml │ │ ├── activity_author.xml │ │ ├── activity_base_swipeback.xml │ │ ├── activity_collect.xml │ │ ├── activity_local_music.xml │ │ ├── activity_main.xml │ │ ├── activity_music_down_load_list.xml │ │ ├── activity_my_music_collect.xml │ │ ├── activity_picture_view.xml │ │ ├── activity_play_list.xml │ │ ├── activity_play_music.xml │ │ ├── activity_search_music.xml │ │ ├── activity_setting.xml │ │ ├── activity_splash.xml │ │ ├── activity_zhi_hu_daily_news.xml │ │ ├── activity_zhi_hu_essay.xml │ │ ├── dialog_play_control.xml │ │ ├── fragment_interseting_page_layout.xml │ │ ├── fragment_joke_layout.xml │ │ ├── fragment_list.xml │ │ ├── fragment_music_page_layout.xml │ │ ├── fragment_picture_layout.xml │ │ ├── fragment_player_page_layout.xml │ │ ├── fragment_zhi_hu_layout.xml │ │ ├── include_refresh_list.xml │ │ ├── item_daily_news.xml │ │ ├── item_daily_news_date.xml │ │ ├── item_dialog_header.xml │ │ ├── item_dialog_music_item.xml │ │ ├── item_drawer_header.xml │ │ ├── item_drawer_item.xml │ │ ├── item_interesting_page.xml │ │ ├── item_joke.xml │ │ ├── item_like_play_list.xml │ │ ├── item_load_more.xml │ │ ├── item_local_music.xml │ │ ├── item_lyric.xml │ │ ├── item_music_down.xml │ │ ├── item_music_page_constant.xml │ │ ├── item_music_play_list.xml │ │ ├── item_picture_category.xml │ │ ├── item_simple_picture.xml │ │ ├── item_simple_title.xml │ │ ├── item_top_news.xml │ │ ├── layout_left_menu.xml │ │ ├── layout_main.xml │ │ ├── view_banner.xml │ │ ├── view_music_control_panel.xml │ │ ├── view_music_play_control.xml │ │ ├── view_picture_category.xml │ │ ├── view_play_operator.xml │ │ ├── view_search_bar.xml │ │ ├── view_tool_bar.xml │ │ └── view_water_wave_rotate_iv.xml │ │ ├── menu │ │ └── activity_main_drawer.xml │ │ ├── mipmap-xxhdpi │ │ ├── bg_drawer_header.png │ │ ├── bg_search_music.png │ │ ├── bg_splash.png │ │ ├── ic_add_to_next_play.png │ │ ├── ic_back.png │ │ ├── ic_black_back.png │ │ ├── ic_dialog_music_item_delete.png │ │ ├── ic_dialog_music_item_volume.png │ │ ├── ic_drawer_app_info.png │ │ ├── ic_drawer_author.png │ │ ├── ic_drawer_collect.png │ │ ├── ic_drawer_setting.png │ │ ├── ic_empty.png │ │ ├── ic_flaot_bt_pic_menu.png │ │ ├── ic_local_music.png │ │ ├── ic_logo.png │ │ ├── ic_love.png │ │ ├── ic_menu.png │ │ ├── ic_music_loading.png │ │ ├── ic_music_pannel_next.png │ │ ├── ic_music_pannel_paly.png │ │ ├── ic_music_pannel_stop.png │ │ ├── ic_music_placeholder.png │ │ ├── ic_music_player_next.png │ │ ├── ic_music_player_play.png │ │ ├── ic_music_player_pre.png │ │ ├── ic_music_player_recycle.png │ │ ├── ic_music_player_stop.png │ │ ├── ic_my_icon.png │ │ ├── ic_my_music_collect.png │ │ ├── ic_paly_list.png │ │ ├── ic_picture_download.png │ │ ├── ic_play_operator_circle.png │ │ ├── ic_play_operator_circle_enable.png │ │ ├── ic_play_operator_down.png │ │ ├── ic_play_operator_list.png │ │ ├── ic_play_operator_music_list.png │ │ ├── ic_play_operator_next_play.png │ │ ├── ic_play_operator_random.png │ │ ├── ic_play_operator_random_enable.png │ │ ├── ic_recommend_play_list.png │ │ ├── ic_right_more.png │ │ ├── ic_scan_local_music.png │ │ ├── ic_scan_music.png │ │ ├── ic_search.png │ │ ├── ic_search_local_music.png │ │ ├── ic_un_love.png │ │ ├── ic_zhihu_essay_next.png │ │ ├── ic_zhihu_essay_pre.png │ │ ├── placeholder_load_failed.png │ │ ├── placeholder_loading.png │ │ └── placeholder_long_loading.png │ │ ├── transition │ │ └── slide_from_bottom.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── susion │ └── boring │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties ├── screenshot ├── changepage.jpg ├── drawerpage.jpg ├── essaydetail.jpg ├── imagepage.jpg ├── joke.jpg ├── mainpage1.jpg ├── mainpage2.jpg ├── musicdetail.jpg ├── playlist.jpg └── readingpage.jpg ├── settings.gradle └── susion.jks /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | /infer-out 9 | /freeline 10 | freeline.py 11 | freeline_project_description.json 12 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 随 心 2 | >刚开始写这个项目的时候是为了自己的毕业设计。 3 | >后来慢慢的就想借这个项目来巩固自己的Android编程技能,也可以更好的站在全局来考虑项目的开发,而不只是需求的迭代开发。 4 | 5 | ## APP细节 6 | 7 | ### API 8 | - APP的API 9 | - 音乐部分,是在网络上收集的网易云音乐的API。用了挺散的, 比如 : https://github.com/javaSwing/MusicAPI 10 | - 知乎日报, https://github.com/izzyleung/ZhihuDailyPurify/wiki/%E7%9F%A5%E4%B9%8E%E6%97%A5%E6%8A%A5-API-%E5%88%86%E6%9E%90 11 | - 段子、图片, API市场 12 | - 对于第三方开源库的使用 13 | - 基础库: RxJava, Retrofit, fresco, eventbus 14 | - 侧滑退出 15 | - 项目编码 16 | - 对于复杂的逻辑, 采用的MVP编写。 17 | - 由于本人是处女座,代码阅读起来应该还是比较容易的。 18 | - github 19 | - https://github.com/SusionSuc/Boring 20 | - 当然还是希望可以给一个star的... 谢谢 21 | 22 | ### 模块设计架构 23 | - 音乐播放模块的大体架构 24 | - MusicServie负责维护音乐播放 25 | - 管理 MediaPlayer 26 | - 管理 播放队列 27 | - Client 与 MusicService的通讯 28 | - MusicService 会开启一个广播接收者,根据相应的广播Action,处理相应的事件 29 | - 抽取音乐播放Action类, 即发送特定的Action来控制音乐播放 30 | - Client 通过广播接收者,来更新音乐播放相关UI : 进度、播放状态等 31 | - Client 通过Action类,向Service的广播接收者发送特定的Action,来实现音乐的控制。 32 | - 阅读模块的大体架构 33 | - 知乎阅读 34 | - StickHeader的实现, 35 | - 对于知乎文章的展示, 利用RxJava请求文章内容,文章的CSS样式, 然后拼接 Html内容,进行展示 36 | - 段子 37 | - 普通的RecyclerView列表 38 | - 图片 39 | - 通过分类window来切换图片请求的URI 40 | - 图片的查看,简单的实现缩放退出 41 | - 整个APP的收藏模块 42 | - 利用第三方关系型数据库, 泛型, 实现了简单的对象存储 43 | - 最简单的收藏就是: 收藏:把对象存入数据库, 删除收藏: 把对象从数据库中删除 44 | 45 | - APP 中RecylerView的使用 46 | - 通过对Adapter和ViewHolder的抽取 47 | - 整个具体UI的展现, 可以说是面向 ItemHandler 的编程。 48 | 49 | - 接下来事情不是很多,对整个APP还会慢慢优化。 50 | 51 | 52 | ## APP截图 53 | 54 | 图片名称 55 | 图片名称 56 | 图片名称 57 | 图片名称 58 | 图片名称 59 | 图片名称 60 | 图片名称 61 | 图片名称 62 | 图片名称 63 | 图片名称 64 | 65 | 66 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.susion.boring" 9 | minSdkVersion 21 10 | targetSdkVersion 24 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | signingConfigs { 15 | //keystore info 16 | release { 17 | storeFile file("${SIGN_STORE_FILE}") 18 | storePassword SIGN_STORE_PASSWORD 19 | keyAlias SIGN_KEY_ALIAS 20 | keyPassword SIGN_KEY_PASSWORD 21 | } 22 | } 23 | 24 | buildTypes { 25 | 26 | debug { 27 | signingConfig signingConfigs.release 28 | buildConfigField "boolean", "ISDEBUG", "true" 29 | debuggable true 30 | minifyEnabled false 31 | shrinkResources false 32 | } 33 | 34 | release { 35 | signingConfig signingConfigs.release 36 | minifyEnabled false 37 | zipAlignEnabled true 38 | debuggable false 39 | shrinkResources true 40 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 41 | } 42 | } 43 | } 44 | 45 | 46 | dependencies { 47 | compile fileTree(include: ['*.jar'], dir: 'libs') 48 | testCompile 'junit:junit:4.12' 49 | compile 'com.android.support:appcompat-v7:24.2.1' 50 | compile 'com.facebook.fresco:fresco:1.0.0' 51 | compile 'com.android.support:recyclerview-v7:24.2.1' 52 | compile 'com.android.support:design:24.2.1' 53 | compile 'io.reactivex:rxandroid:1.2.1' 54 | compile 'io.reactivex:rxjava:1.1.6' 55 | compile 'com.squareup.retrofit2:retrofit:2.0.2' 56 | compile 'com.squareup.retrofit2:converter-gson:2.0.2' 57 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2' 58 | compile 'org.greenrobot:eventbus:3.0.0' 59 | } 60 | -------------------------------------------------------------------------------- /app/libs/lite-orm-1.9.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SusionSuc/android-learn-music/2dcaed6649ce2df7abe07e226e1a05f5155abce1/app/libs/lite-orm-1.9.2.jar -------------------------------------------------------------------------------- /app/libs/universal-image-loader-1.9.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SusionSuc/android-learn-music/2dcaed6649ce2df7abe07e226e1a05f5155abce1/app/libs/universal-image-loader-1.9.5.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/susion/Documents/xiaohongshu_sdk_mac/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/susion/boring/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/SAppApplication.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.Application; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.util.Log; 8 | 9 | import com.facebook.drawee.backends.pipeline.Fresco; 10 | import com.susion.boring.base.service.BaseService; 11 | import com.susion.boring.utils.FileUtils; 12 | import com.susion.boring.utils.ImagePipelineConfigFactory; 13 | 14 | /** 15 | * Created by susion on 17/1/17. 16 | */ 17 | public class SAppApplication extends Application { 18 | 19 | private static Context sContext; 20 | 21 | @Override 22 | public void onCreate() { 23 | super.onCreate(); 24 | Fresco.initialize(this, ImagePipelineConfigFactory.getImagePipelineConfig(this)); 25 | FileUtils.initAppDir(); 26 | 27 | Intent intent = new Intent(this, BaseService.class); 28 | startService(intent); 29 | } 30 | 31 | @Override 32 | protected void attachBaseContext(Context base) { 33 | super.attachBaseContext(base); 34 | sContext = base; 35 | } 36 | 37 | public static Context getAppContext() { 38 | return sContext; 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/adapter/QuickPageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.adapter; 2 | 3 | import android.support.v4.view.PagerAdapter; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by susion on 17/3/9. 11 | */ 12 | public class QuickPageAdapter extends PagerAdapter { 13 | 14 | private List mList; 15 | 16 | public QuickPageAdapter(List mList) { 17 | this.mList = mList; 18 | } 19 | 20 | @Override 21 | public int getCount() { 22 | return mList.size(); 23 | } 24 | 25 | @Override 26 | public boolean isViewFromObject(View view, Object object) { 27 | return object == view; 28 | } 29 | 30 | @Override 31 | public Object instantiateItem(ViewGroup container, int position) { 32 | container.addView(mList.get(position)); 33 | return mList.get(position); 34 | } 35 | 36 | @Override 37 | public void destroyItem(ViewGroup container, int position, Object object) { 38 | container.removeView(mList.get(position)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/adapter/ViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.adapter; 2 | 3 | import android.content.Context; 4 | import android.util.SparseArray; 5 | import android.view.View; 6 | import android.widget.Button; 7 | import android.widget.ImageView; 8 | import android.widget.TextSwitcher; 9 | import android.widget.TextView; 10 | 11 | import com.susion.boring.R; 12 | import com.susion.boring.base.ui.ItemHandler; 13 | 14 | 15 | public class ViewHolder { 16 | 17 | private SparseArray viewHolder; 18 | private View view; 19 | public int position; 20 | 21 | public ItemHandler itemHandler; 22 | 23 | 24 | public static ViewHolder newInstant(View view) { 25 | ViewHolder viewHolder = (ViewHolder) view.getTag(R.id.item_tag_id); 26 | if (viewHolder == null) { 27 | viewHolder = new ViewHolder(view); 28 | view.setTag(R.id.item_tag_id, viewHolder); 29 | } 30 | 31 | return viewHolder; 32 | } 33 | 34 | private ViewHolder(View view) { 35 | this.view = view; 36 | viewHolder = new SparseArray<>(); 37 | } 38 | 39 | public T get(int id) { 40 | View childView = viewHolder.get(id); 41 | if (childView == null) { 42 | childView = view.findViewById(id); 43 | viewHolder.put(id, childView); 44 | } 45 | return (T) childView; 46 | } 47 | 48 | public View getConvertView() { 49 | return view; 50 | } 51 | 52 | public TextView getTextView(int id) { 53 | 54 | return get(id); 55 | } 56 | 57 | public TextSwitcher getTextSwitcher(int id) { 58 | return get(id); 59 | } 60 | 61 | public Button getButton(int id) { 62 | return get(id); 63 | } 64 | 65 | public ImageView getImageView(int id) { 66 | return get(id); 67 | } 68 | 69 | public void setTextView(int id, String charSequence) { 70 | 71 | getTextView(id).setText(charSequence); 72 | } 73 | 74 | public void setTextView(int id, int stringId) { 75 | 76 | getTextView(id).setText(stringId); 77 | } 78 | 79 | public Context getContext() { 80 | return getConvertView().getContext(); 81 | } 82 | 83 | 84 | public void setOnClickListener(int vid, View.OnClickListener onClick) { 85 | this.get(vid).setOnClickListener(onClick); 86 | this.get(vid).setTag(this); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/entity/FavoriteMark.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.entity; 2 | 3 | /** 4 | * Created by susion on 17/3/28. 5 | */ 6 | public class FavoriteMark { 7 | public boolean favorite; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/entity/ModelTranslateContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.entity; 2 | 3 | import com.susion.boring.music.mvp.model.SimpleSong; 4 | import com.susion.boring.music.mvp.model.PlayList; 5 | import com.susion.boring.music.mvp.model.PlayListDetail; 6 | import com.susion.boring.music.mvp.model.Song; 7 | 8 | import java.util.List; 9 | 10 | import rx.Observable; 11 | 12 | /** 13 | * Created by susion on 17/3/3. 14 | */ 15 | public interface ModelTranslateContract { 16 | 17 | interface MusicModeTranslate { 18 | Observable> getSongFromPlayList(PlayList playList); 19 | 20 | List translateTracksToSimpleSong(List tracks); 21 | 22 | List translateTracksToSong(List tracks); 23 | 24 | Observable checkIfHasPlayUrl(Song song); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/entity/TitleMark.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.entity; 2 | 3 | /** 4 | * Created by susion on 17/3/10. 5 | */ 6 | public class TitleMark { 7 | private String headerTitle; 8 | private boolean showTitle; 9 | 10 | public String getHeaderTitle() { 11 | return headerTitle; 12 | } 13 | 14 | public void setHeaderTitle(String headerTitle) { 15 | this.headerTitle = headerTitle; 16 | } 17 | 18 | public boolean isShowTitle() { 19 | return showTitle; 20 | } 21 | 22 | public void setShowTitle(boolean showTitle) { 23 | this.showTitle = showTitle; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/service/BaseService.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.service; 2 | 3 | import android.app.Service; 4 | import android.content.Intent; 5 | import android.os.IBinder; 6 | import android.support.annotation.Nullable; 7 | 8 | import com.susion.boring.music.service.MusicPlayerService; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by susion on 17/3/14. 15 | * 管理各个Service, 原想多次采用service-client模式做一些业务逻辑, 于是就抽取了出来。 16 | */ 17 | public class BaseService extends Service { 18 | 19 | List childServices; 20 | public static final String SERVICE_ACTION = "BASE_SERVICE"; 21 | 22 | @Override 23 | public void onCreate() { 24 | super.onCreate(); 25 | childServices = new ArrayList<>(); 26 | childServices.add(new MusicPlayerService(this)); 27 | 28 | for (BaseServiceContract service : childServices) { 29 | service.initService(); 30 | } 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public IBinder onBind(Intent intent) { 36 | return null; 37 | } 38 | 39 | @Override 40 | public void onTaskRemoved(Intent rootIntent) { 41 | for (BaseServiceContract service : childServices) { 42 | service.onTaskMoved(); 43 | } 44 | super.onTaskRemoved(rootIntent); 45 | } 46 | 47 | @Override 48 | public void onDestroy() { 49 | for (BaseServiceContract service : childServices) { 50 | service.onDestroy(); 51 | } 52 | super.onDestroy(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/service/BaseServiceContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.service; 2 | 3 | /** 4 | * Created by susion on 17/3/14. 5 | */ 6 | public interface BaseServiceContract { 7 | 8 | void initService(); 9 | 10 | void onTaskMoved(); 11 | 12 | void onDestroy(); 13 | 14 | interface ReceiverPresenter { 15 | void releaseResource(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/AuthorActivity.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | 8 | import com.susion.boring.R; 9 | 10 | public class AuthorActivity extends AppCompatActivity { 11 | 12 | public static void start(Context context) { 13 | Intent intent = new Intent(); 14 | intent.setClass(context, AuthorActivity.class); 15 | context.startActivity(intent); 16 | } 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_author); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/ItemHandler.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui; 2 | 3 | import android.support.annotation.LayoutRes; 4 | import android.view.ViewGroup; 5 | 6 | import com.susion.boring.base.adapter.ViewHolder; 7 | 8 | /** 9 | * Created by susion on 17/1/18. 10 | */ 11 | public interface ItemHandler { 12 | 13 | void onCreateItemHandler(ViewHolder vh, ViewGroup parent); 14 | 15 | @LayoutRes 16 | int getLayoutResId(); 17 | 18 | void onBindView(Object adapter, ViewHolder vh, T data, int position); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/ItemHandlerFactory.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui; 2 | 3 | /** 4 | * Created by susion on 17/1/18. 5 | */ 6 | public interface ItemHandlerFactory { 7 | ItemHandler newInstant(int viewType); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/OnLastItemVisibleListener.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui; 2 | 3 | /** 4 | * Created by susion on 17/2/10. 5 | */ 6 | public interface OnLastItemVisibleListener { 7 | void onLastItemVisible(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | 8 | import com.susion.boring.R; 9 | 10 | public class SettingActivity extends AppCompatActivity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_setting); 16 | } 17 | 18 | public static void start(Context context) { 19 | Intent intent = new Intent(); 20 | intent.setClass(context, SettingActivity.class); 21 | context.startActivity(intent); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/SimpleItemHandler.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.susion.boring.base.adapter.ViewHolder; 8 | 9 | /** 10 | * Created by susion on 17/1/18. 11 | */ 12 | public abstract class SimpleItemHandler implements ItemHandler, View.OnClickListener { 13 | 14 | protected Context mContext; 15 | 16 | protected T mData; 17 | protected int mPosition; 18 | protected Object mAdapter; 19 | @Override 20 | 21 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 22 | if (mContext == null) { 23 | mContext = vh.getContext(); 24 | } 25 | vh.getConvertView().setOnClickListener(this); 26 | } 27 | 28 | /** 29 | * 这里不建议有产生对象的操作(比如设置监听),把对象的生成放在 {@link #onCreateItemHandler(ViewHolder)} 方法里面吧. 30 | * @param vh 31 | * @param data 32 | * @param position 33 | */ 34 | @Override 35 | final public void onBindView(Object adapter, ViewHolder vh, T data, int position) { 36 | mData=data; 37 | mPosition=position; 38 | mAdapter = adapter; 39 | onBindDataView(vh, data, position); 40 | } 41 | 42 | public abstract void onBindDataView(ViewHolder vh, T data, int position); 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/mainui/IMainUIPresenter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui.mainui; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | 6 | /** 7 | * Created by susion on 17/1/19. 8 | */ 9 | public interface IMainUIPresenter { 10 | 11 | int getFragmentCount(); 12 | 13 | Fragment getPageFragmentByPos(int pos); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/mainui/drawer/DividerMark.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui.mainui.drawer; 2 | 3 | /** 4 | * Created by susion on 17/2/21. 5 | */ 6 | public class DividerMark { 7 | public boolean needDivider; 8 | 9 | public DividerMark(boolean needDivider) { 10 | this.needDivider = needDivider; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/mainui/drawer/DrawerHeaderItemHandler.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui.mainui.drawer; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | 6 | import com.susion.boring.R; 7 | import com.susion.boring.base.ui.SimpleItemHandler; 8 | import com.susion.boring.base.adapter.ViewHolder; 9 | 10 | /** 11 | * Created by susion on 17/1/18. 12 | */ 13 | public class DrawerHeaderItemHandler extends SimpleItemHandler { 14 | 15 | @Override 16 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 17 | super.onCreateItemHandler(vh, parent); 18 | } 19 | 20 | @Override 21 | public void onBindDataView(ViewHolder vh, DrawerData.DrawerHeader data, int position) { 22 | vh.getTextView(R.id.drawer_header_username).setText(data.username); 23 | } 24 | 25 | @Override 26 | public int getLayoutResId() { 27 | return R.layout.item_drawer_header; 28 | } 29 | 30 | 31 | @Override 32 | public void onClick(View view) { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/mainui/drawer/DrawerItemHandler.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui.mainui.drawer; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | 6 | import com.susion.boring.R; 7 | import com.susion.boring.base.ui.SimpleItemHandler; 8 | import com.susion.boring.base.adapter.ViewHolder; 9 | 10 | /** 11 | * Created by susion on 17/1/19. 12 | */ 13 | public class DrawerItemHandler extends SimpleItemHandler { 14 | 15 | @Override 16 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 17 | super.onCreateItemHandler(vh, parent); 18 | } 19 | 20 | @Override 21 | 22 | public void onBindDataView(ViewHolder vh, DrawerData.DrawerItem data, int position) { 23 | vh.getTextView(R.id.drawer_item_title).setText(data.type); 24 | if (data.imageRes != -1) { 25 | vh.getImageView(R.id.drawer_item_image).setImageResource(data.imageRes); 26 | } 27 | } 28 | 29 | @Override 30 | public int getLayoutResId() { 31 | return R.layout.item_drawer_item; 32 | } 33 | 34 | @Override 35 | public void onClick(View view) { 36 | DrawerData.onItemClick(mContext, mData.type); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/ui/mainui/drawer/MainDrawerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.ui.mainui.drawer; 2 | 3 | import android.app.Activity; 4 | 5 | import com.susion.boring.base.adapter.BaseRVAdapter; 6 | import com.susion.boring.base.ui.ItemHandler; 7 | import com.susion.boring.base.ui.ItemHandlerFactory; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by susion on 17/1/18. 13 | */ 14 | public class MainDrawerAdapter extends BaseRVAdapter { 15 | 16 | private final int ITEM_HANDLER_HEADER = 1; 17 | private final int ITEM_HANDLER_ITEM = 2; 18 | 19 | public MainDrawerAdapter(Activity context, List data) { 20 | super(context, data); 21 | } 22 | 23 | @Override 24 | protected void initHandlers() { 25 | registerItemHandler(ITEM_HANDLER_HEADER, new ItemHandlerFactory() { 26 | @Override 27 | public ItemHandler newInstant(int viewType) { 28 | return new DrawerHeaderItemHandler(); 29 | } 30 | }); 31 | 32 | registerItemHandler(ITEM_HANDLER_ITEM, new ItemHandlerFactory() { 33 | @Override 34 | public ItemHandler newInstant(int viewType) { 35 | return new DrawerItemHandler(); 36 | } 37 | }); 38 | 39 | } 40 | 41 | @Override 42 | protected int getViewType(int position) { 43 | Object o = mData.get(position); 44 | 45 | if (o instanceof DrawerData.DrawerHeader) { 46 | return ITEM_HANDLER_HEADER; 47 | } 48 | 49 | if (o instanceof DrawerData.DrawerItem) { 50 | return ITEM_HANDLER_ITEM; 51 | } 52 | 53 | return -1; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/view/IView.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.view; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * Created by susion on 17/2/26. 7 | */ 8 | public interface IView { 9 | Context getViewContext(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/view/ViewPageFragment.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.view; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import com.susion.boring.R; 9 | import com.susion.boring.base.ui.BaseFragment; 10 | import com.susion.boring.utils.UIUtils; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created by susion on 17/3/15. 16 | */ 17 | public abstract class ViewPageFragment extends BaseFragment { 18 | public abstract String getTitle(); 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/view/swipebacklayout/SwipeBackActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.susion.boring.base.view.swipebacklayout; 3 | 4 | import android.os.Build; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | 9 | 10 | public class SwipeBackActivity extends AppCompatActivity implements SwipeBackActivityBase { 11 | private SwipeBackActivityHelper mHelper; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | mHelper = new SwipeBackActivityHelper(this); 17 | mHelper.onActivityCreate(); 18 | if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { 19 | setSwipeBackEnable(false); 20 | } 21 | } 22 | 23 | @Override 24 | protected void onPostCreate(Bundle savedInstanceState) { 25 | super.onPostCreate(savedInstanceState); 26 | mHelper.onPostCreate(); 27 | } 28 | 29 | @Override 30 | public View findViewById(int id) { 31 | View v = super.findViewById(id); 32 | if (v == null && mHelper != null) 33 | return mHelper.findViewById(id); 34 | return v; 35 | } 36 | 37 | @Override 38 | public SwipeBackLayout getSwipeBackLayout() { 39 | return mHelper.getSwipeBackLayout(); 40 | } 41 | 42 | @Override 43 | public void setSwipeBackEnable(boolean enable) { 44 | getSwipeBackLayout().setEnableGesture(enable); 45 | } 46 | 47 | @Override 48 | public void scrollToFinishActivity() { 49 | Utils.convertActivityToTranslucent(this); 50 | getSwipeBackLayout().scrollToFinishActivity(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/view/swipebacklayout/SwipeBackActivityBase.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.view.swipebacklayout; 2 | 3 | /** 4 | * @author Yrom 5 | */ 6 | public interface SwipeBackActivityBase { 7 | /** 8 | * @return the SwipeBackLayout associated with this activity. 9 | */ 10 | public abstract SwipeBackLayout getSwipeBackLayout(); 11 | 12 | public abstract void setSwipeBackEnable(boolean enable); 13 | 14 | /** 15 | * Scroll out contentView and finish the activity 16 | */ 17 | public abstract void scrollToFinishActivity(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/base/view/swipebacklayout/SwipeBackActivityHelper.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.base.view.swipebacklayout; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | 9 | import com.susion.boring.R; 10 | 11 | 12 | /** 13 | * @author Yrom 14 | */ 15 | public class SwipeBackActivityHelper { 16 | private Activity mActivity; 17 | 18 | private SwipeBackLayout mSwipeBackLayout; 19 | 20 | public SwipeBackActivityHelper(Activity activity) { 21 | mActivity = activity; 22 | } 23 | 24 | @SuppressWarnings("deprecation") 25 | public void onActivityCreate() { 26 | mActivity.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 27 | mActivity.getWindow().getDecorView().setBackgroundDrawable(null); 28 | mSwipeBackLayout = (SwipeBackLayout) LayoutInflater.from(mActivity).inflate( 29 | R.layout.activity_base_swipeback, null); 30 | mSwipeBackLayout.addSwipeListener(new SwipeBackLayout.SwipeListener() { 31 | @Override 32 | public void onScrollStateChange(int state, float scrollPercent) { 33 | } 34 | 35 | @Override 36 | public void onEdgeTouch(int edgeFlag) { 37 | Utils.convertActivityToTranslucent(mActivity); 38 | } 39 | 40 | @Override 41 | public void onScrollOverThreshold() { 42 | 43 | } 44 | }); 45 | } 46 | 47 | public void onPostCreate() { 48 | mSwipeBackLayout.attachToActivity(mActivity); 49 | } 50 | 51 | public View findViewById(int id) { 52 | if (mSwipeBackLayout != null) { 53 | return mSwipeBackLayout.findViewById(id); 54 | } 55 | return null; 56 | } 57 | 58 | public SwipeBackLayout getSwipeBackLayout() { 59 | return mSwipeBackLayout; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/db/DbManager.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.db; 2 | 3 | import com.litesuits.orm.BuildConfig; 4 | import com.litesuits.orm.LiteOrm; 5 | import com.susion.boring.base.SAppApplication; 6 | 7 | /** 8 | * Created by susion on 17/2/20. 9 | */ 10 | public class DbManager { 11 | 12 | private static volatile LiteOrm sLiteOrm; 13 | private static final String DB_NAME = "boring.db"; 14 | 15 | private DbManager() { 16 | } 17 | 18 | public static LiteOrm getLiteOrm() { 19 | if (sLiteOrm == null) { 20 | synchronized (DbManager.class) { 21 | if (sLiteOrm == null) { 22 | sLiteOrm = LiteOrm.newCascadeInstance(SAppApplication.getAppContext(), DB_NAME); 23 | sLiteOrm.setDebugged(BuildConfig.DEBUG); 24 | } 25 | } 26 | } 27 | return sLiteOrm; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/db/operate/DataBaseOperateContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.db.operate; 2 | 3 | import com.susion.boring.music.mvp.model.SimpleSong; 4 | 5 | import java.util.List; 6 | 7 | import rx.Observable; 8 | 9 | /** 10 | * Created by susion on 17/2/20. 11 | */ 12 | public interface DataBaseOperateContract { 13 | 14 | interface BaseOperate { 15 | Observable> add(final List ts); 16 | 17 | Observable add(T t); 18 | 19 | Observable delete(T t); 20 | 21 | Observable clearALLData(); 22 | 23 | Observable query(String id); 24 | 25 | Observable getTotalCount(); 26 | 27 | Observable> getAll(); 28 | 29 | Observable update(T t); 30 | 31 | Observable> getLikeData(); 32 | } 33 | 34 | interface MusicOperator extends BaseOperate { 35 | Observable> getLikeMusic(); 36 | 37 | Observable getLikeMusicCount(); 38 | 39 | Observable> getLocalMusic(); 40 | 41 | Observable getLocalMusicCount(); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/AddMusicToQueueEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.music.mvp.model.Song; 4 | 5 | /** 6 | * Created by susion on 17/4/1. 7 | */ 8 | public class AddMusicToQueueEvent { 9 | public Song song; 10 | public AddMusicToQueueEvent(Song song) { 11 | this.song = song; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/AddToNextPlayEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.music.mvp.model.SimpleSong; 4 | import com.susion.boring.music.mvp.model.Song; 5 | 6 | /** 7 | * Created by susion on 17/4/3. 8 | */ 9 | public class AddToNextPlayEvent { 10 | 11 | public Song song; 12 | 13 | public AddToNextPlayEvent(SimpleSong data) { 14 | song = data.translateToSong(); 15 | } 16 | 17 | public AddToNextPlayEvent(Song data) { 18 | song = data; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/CategoryPictureLoadErrorEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | /** 4 | * Created by susion on 17/3/27. 5 | */ 6 | public class CategoryPictureLoadErrorEvent { 7 | String id; 8 | 9 | public CategoryPictureLoadErrorEvent(String id) { 10 | this.id = id; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/ChangeSongEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.music.mvp.model.Song; 4 | 5 | /** 6 | * Created by susion on 17/3/6. 7 | */ 8 | public class ChangeSongEvent { 9 | 10 | public Song song; 11 | 12 | public ChangeSongEvent(Song mData) { 13 | song = mData; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/EssayDeleteFromLikeEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.read.mvp.entity.NewsDetail; 4 | 5 | /** 6 | * Created by susion on 17/3/31. 7 | */ 8 | public class EssayDeleteFromLikeEvent { 9 | public NewsDetail newsDetail; 10 | public EssayDeleteFromLikeEvent(NewsDetail detail) { 11 | newsDetail = detail; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/JokeDeleteFormLikeEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.read.mvp.entity.Joke; 4 | 5 | /** 6 | * Created by susion on 17/3/29. 7 | */ 8 | public class JokeDeleteFormLikeEvent { 9 | public Joke joke; 10 | 11 | public JokeDeleteFormLikeEvent(Joke data) { 12 | joke = data; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/PictureCategorySelectedEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | /** 4 | * Created by susion on 17/3/27. 5 | */ 6 | public class PictureCategorySelectedEvent { 7 | public String id; 8 | 9 | public PictureCategorySelectedEvent(String id) { 10 | this.id = id; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/PictureDeleteFormLikeEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.read.mvp.entity.SimplePicture; 4 | 5 | /** 6 | * Created by susion on 17/3/29. 7 | */ 8 | public class PictureDeleteFormLikeEvent { 9 | public SimplePicture picture; 10 | 11 | public PictureDeleteFormLikeEvent(SimplePicture data) { 12 | picture = data; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/PlayListDeleteFromLikeEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.music.mvp.model.PlayList; 4 | 5 | /** 6 | * Created by susion on 17/4/4. 7 | */ 8 | public class PlayListDeleteFromLikeEvent { 9 | public PlayList playList; 10 | public PlayListDeleteFromLikeEvent(PlayList mPlayList) { 11 | playList = mPlayList; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/SongDeleteFromLikeEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.music.mvp.model.SimpleSong; 4 | 5 | /** 6 | * Created by susion on 17/4/4. 7 | */ 8 | public class SongDeleteFromLikeEvent { 9 | public SimpleSong song; 10 | 11 | public SongDeleteFromLikeEvent(SimpleSong song) { 12 | this.song = song; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/event/SongDeleteFromPlayQueueEvent.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.event; 2 | 3 | import com.susion.boring.music.mvp.model.Song; 4 | 5 | /** 6 | * Created by susion on 17/3/6. 7 | */ 8 | public class SongDeleteFromPlayQueueEvent { 9 | public SongDeleteFromPlayQueueEvent(Song song) { 10 | this.song = song; 11 | } 12 | 13 | public Song song; 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/http/BaseURL.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.http; 2 | 3 | /** 4 | * Created by susion on 17/1/20. 5 | */ 6 | public interface BaseURL { 7 | //music 8 | String MUSIC_SEARCH = "https://api.imjad.cn/cloudmusic"; 9 | String MUSIC_SEARCH_LYRIC = "http://music.163.com"; 10 | String CLOUD_MUSIC_API_MUSICINGO = "http://musicapi.duapp.com/api.php"; 11 | String MUSIC_PLAY_LIST = "http://musicapi.duapp.com/api.php"; 12 | String MUSIC_PLAY_LIST_DETAIL = "https://api.imjad.cn/cloudmusic"; 13 | 14 | //zhi hu 15 | String ZHI_HU_DAILY_LATEST_NEWS = "http://news-at.zhihu.com/api/4/news/latest"; 16 | String ZHI_HU_DAILY_FIX_DATE_NEWS = "http://news-at.zhihu.com/api/4/news/before"; 17 | String ZHI_HU_ESSAY_CONTENT = "http://news-at.zhihu.com/api/4/news"; 18 | 19 | //picture 20 | String PICTURE_GET_CLASS = "http://route.showapi.com/852-1?showapi_sign=7a0e1eaf10af43c0a30ba74319a6d3fd&showapi_appid=33839"; 21 | String PICTURE_GET_TYPE = "http://route.showapi.com/852-2?showapi_sign=7a0e1eaf10af43c0a30ba74319a6d3fd&showapi_appid=33839"; 22 | 23 | //app info 24 | String BORING_GIT = "https://github.com/SusionSuc/Boring"; 25 | String WEIBO = "http://weibo.com/3914031613/profile"; 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/http/CommonObserver.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.http; 2 | 3 | import com.susion.boring.utils.ToastUtils; 4 | 5 | import java.net.ConnectException; 6 | import java.net.SocketTimeoutException; 7 | 8 | import retrofit2.adapter.rxjava.HttpException; 9 | import rx.Observer; 10 | import rx.functions.Action1; 11 | 12 | 13 | public abstract class CommonObserver implements Observer { 14 | 15 | @Override 16 | public void onCompleted() { 17 | } 18 | 19 | @Override 20 | public void onError(Throwable e) { 21 | new CommonErrorAction().call(e); 22 | } 23 | 24 | public class CommonErrorAction implements Action1 { 25 | @Override 26 | public void call(Throwable throwable) { 27 | if (throwable == null) { 28 | return; 29 | } 30 | 31 | String msg; 32 | if (throwable instanceof ConnectException) { 33 | msg = "网络有点不通畅哎"; 34 | } else if (throwable instanceof SocketTimeoutException) { 35 | msg = "网络有点不通畅哎"; 36 | } else if (throwable instanceof HttpException) { 37 | HttpException exception = (HttpException) throwable; 38 | if (exception.code() >= 300 && exception.code() < 400) { 39 | msg = "网路迷路了哎"; 40 | } else if (exception.code() >= 400 && exception.code() < 500) { 41 | msg = "访问的资源好像不见了"; 42 | } else if (exception.code() >= 500 && exception.code() < 600) { 43 | msg = "服务器好像挂掉了哎"; 44 | } else { 45 | msg = "出现了未知错误哎"; 46 | } 47 | } else { 48 | msg = "出现了未知错误哎"; 49 | } 50 | ToastUtils.showShort(msg); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/http/service/JokeService.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.http.service; 2 | 3 | import com.susion.boring.read.mvp.entity.JokeList; 4 | 5 | import retrofit2.http.GET; 6 | import retrofit2.http.Query; 7 | import rx.Observable; 8 | 9 | /** 10 | * Created by susion on 17/3/16. 11 | */ 12 | public interface JokeService { 13 | @GET("http://v.juhe.cn/joke/randJoke.php?key=9ce3fed0e5ac5442ec6dc52f7e2d770a&sort=asc") 14 | Observable getJokes(@Query("page") int page, @Query("pagesize") int pageSize, @Query("time") String timestamp); 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/http/service/MusicServices.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.http.service; 2 | 3 | 4 | import com.susion.boring.http.BaseURL; 5 | import com.susion.boring.music.mvp.model.GetPlayListResult; 6 | import com.susion.boring.music.mvp.model.LyricResult; 7 | import com.susion.boring.music.mvp.model.MusicSearchResult; 8 | import com.susion.boring.music.mvp.model.PlayListDetail; 9 | import com.susion.boring.music.mvp.model.PlayListSong; 10 | 11 | import retrofit2.http.GET; 12 | import retrofit2.http.Query; 13 | import rx.Observable; 14 | 15 | /** 16 | * Created by susion on 17/1/20. 17 | */ 18 | public interface MusicServices { 19 | 20 | @GET(BaseURL.MUSIC_SEARCH) 21 | Observable searchMusic(@Query("s") String musicName, @Query("limit") int limit, 22 | @Query("type") String type, @Query("offset") int page); 23 | 24 | @GET(BaseURL.MUSIC_SEARCH_LYRIC + "/api/song/lyric?os=pc&kv=-1&tv=-1&lv=-1") 25 | Observable getMusicLyric(@Query("id") String songId); 26 | 27 | @GET(BaseURL.MUSIC_PLAY_LIST + "?type=topPlayList&cat=全部") 28 | Observable getPlayList(@Query("offset") int offset, @Query("limit") int limit); 29 | 30 | @GET(BaseURL.MUSIC_PLAY_LIST_DETAIL + "?type=playlist") 31 | Observable getPlayListDetail(@Query("id") int id); 32 | 33 | @GET(BaseURL.CLOUD_MUSIC_API_MUSICINGO + "?type=url") 34 | Observable getSongDetail(@Query("id") int id); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/http/service/PictureService.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.http.service; 2 | 3 | import com.susion.boring.http.BaseURL; 4 | import com.susion.boring.read.mvp.entity.PictureCategoryResult; 5 | import com.susion.boring.read.mvp.entity.SimplePictureList; 6 | 7 | import okhttp3.ResponseBody; 8 | import retrofit2.http.GET; 9 | import retrofit2.http.Query; 10 | import retrofit2.http.Url; 11 | import rx.Observable; 12 | 13 | /** 14 | * Created by susion on 17/3/17. 15 | */ 16 | public interface PictureService { 17 | 18 | @GET(BaseURL.PICTURE_GET_TYPE) 19 | Observable getPicturesByType(@Query("type") String type, @Query("page") String page); 20 | 21 | @GET(BaseURL.PICTURE_GET_CLASS) 22 | Observable getPictureCategory(); 23 | 24 | @GET 25 | Observable getImage(@Url String url); 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/http/service/ZhiHuService.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.http.service; 2 | 3 | import com.susion.boring.http.BaseURL; 4 | import com.susion.boring.read.mvp.entity.DailyNews; 5 | import com.susion.boring.read.mvp.entity.NewsDetail; 6 | 7 | import okhttp3.ResponseBody; 8 | import retrofit2.http.GET; 9 | import retrofit2.http.Path; 10 | import retrofit2.http.Url; 11 | import rx.Observable; 12 | 13 | /** 14 | * Created by susion on 17/3/9. 15 | */ 16 | public interface ZhiHuService { 17 | 18 | @GET(BaseURL.ZHI_HU_DAILY_LATEST_NEWS) 19 | Observable getLatestNews(); 20 | 21 | @GET(BaseURL.ZHI_HU_DAILY_FIX_DATE_NEWS + "/{date}") 22 | Observable getFixDateNews(@Path("date") String oid); 23 | 24 | 25 | @GET(BaseURL.ZHI_HU_ESSAY_CONTENT + "/{id}") 26 | Observable getEssayContent(@Path("id") String id); 27 | 28 | @GET 29 | Observable getEssayCSS(@Url String url); 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/adapter/MusicPageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.adapter; 2 | 3 | import android.app.Activity; 4 | 5 | import com.susion.boring.base.adapter.BaseRVAdapter; 6 | import com.susion.boring.base.ui.ItemHandler; 7 | import com.susion.boring.base.ui.ItemHandlerFactory; 8 | import com.susion.boring.music.itemhandler.MusicPageConstantIH; 9 | import com.susion.boring.music.itemhandler.MusicPagePlayListIH; 10 | import com.susion.boring.music.itemhandler.MusicPageTitleIH; 11 | import com.susion.boring.music.mvp.model.MusicPageConstantItem; 12 | import com.susion.boring.music.mvp.model.PlayList; 13 | import com.susion.boring.music.mvp.model.SimpleTitle; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * Created by susion on 17/1/21. 19 | */ 20 | public class MusicPageAdapter extends BaseRVAdapter { 21 | 22 | private static final int MUSIC_PAGE_CONSTANT_ITEM = 1; 23 | private static final int MUSIC_PAGE_TITLE_ITEM = 2; 24 | private static final int MUSIC_PAGE_PLAY_LIST_ITEM = 3; 25 | 26 | 27 | public MusicPageAdapter(Activity activity, List data) { 28 | super(activity, data); 29 | } 30 | 31 | @Override 32 | protected void initHandlers() { 33 | registerItemHandler(MUSIC_PAGE_CONSTANT_ITEM, new ItemHandlerFactory() { 34 | @Override 35 | public ItemHandler newInstant(int viewType) { 36 | return new MusicPageConstantIH(); 37 | } 38 | }); 39 | 40 | registerItemHandler(MUSIC_PAGE_TITLE_ITEM, new ItemHandlerFactory() { 41 | @Override 42 | public ItemHandler newInstant(int viewType) { 43 | return new MusicPageTitleIH(); 44 | } 45 | }); 46 | 47 | registerItemHandler(MUSIC_PAGE_PLAY_LIST_ITEM, new ItemHandlerFactory() { 48 | @Override 49 | public ItemHandler newInstant(int viewType) { 50 | return new MusicPagePlayListIH(); 51 | } 52 | }); 53 | 54 | } 55 | 56 | @Override 57 | protected int getViewType(int position) { 58 | 59 | Object o = mData.get(position); 60 | 61 | if (o instanceof MusicPageConstantItem) { 62 | return MUSIC_PAGE_CONSTANT_ITEM; 63 | } 64 | 65 | if (o instanceof SimpleTitle) { 66 | return MUSIC_PAGE_TITLE_ITEM; 67 | } 68 | 69 | if (o instanceof PlayList) { 70 | return MUSIC_PAGE_PLAY_LIST_ITEM; 71 | } 72 | 73 | return 0; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/itemhandler/LocalMusicIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.itemhandler; 2 | 3 | import android.text.TextUtils; 4 | import android.view.View; 5 | 6 | import com.susion.boring.base.adapter.ViewHolder; 7 | import com.susion.boring.event.AddMusicToQueueEvent; 8 | import com.susion.boring.event.AddToNextPlayEvent; 9 | import com.susion.boring.music.mvp.model.SimpleSong; 10 | import com.susion.boring.music.mvp.view.PlayMusicActivity; 11 | import com.susion.boring.utils.AlbumUtils; 12 | import com.susion.boring.utils.TimeUtils; 13 | import com.susion.boring.utils.ToastUtils; 14 | import com.susion.boring.utils.UIUtils; 15 | 16 | import org.greenrobot.eventbus.EventBus; 17 | 18 | /** 19 | * Created by susion on 17/3/6. 20 | */ 21 | public class LocalMusicIH extends SimpleMusicIH { 22 | 23 | 24 | public LocalMusicIH(boolean showNextPlay) { 25 | super(showNextPlay); 26 | } 27 | 28 | @Override 29 | protected void onAddToNextPlayClick() { 30 | ToastUtils.showShort("已经添加下一首播放"); 31 | EventBus.getDefault().post(new AddToNextPlayEvent(mData)); 32 | } 33 | 34 | @Override 35 | protected void onItemClick() { 36 | if (!mData.isFromPlayList() && mData.isHasDown()) { 37 | PlayMusicActivity.start(mContext, mData.translateToSong(), false); 38 | } else { 39 | PlayMusicActivity.start(mContext, mData.translateToSong(), true); 40 | } 41 | 42 | EventBus.getDefault().post(new AddMusicToQueueEvent(mData.translateToSong())); 43 | } 44 | 45 | @Override 46 | protected void bindData(ViewHolder vh, SimpleSong data, int position) { 47 | mTvTile.setText(data.getDisplayName() + ""); 48 | String desc = data.getArtist(); 49 | 50 | if (!TextUtils.isEmpty(data.getAlbum())) { 51 | desc += "-" + data.getAlbum(); 52 | } 53 | 54 | mTvSecondTile.setText(desc); 55 | 56 | if (data.isHasDown()) { 57 | AlbumUtils.setAlbum(mSdvAlbum, data.getPath()); 58 | String duration = TimeUtils.formatDuration(data.getDuration()); 59 | mTvDuration.setText(duration.equals("00:00") ? "" : duration); 60 | } else { 61 | UIUtils.loadSmallPicture(mSdvAlbum, data.getPicPath()); 62 | mTvDuration.setVisibility(View.GONE); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/itemhandler/MusicPagePlayListIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.itemhandler; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | 6 | import com.facebook.drawee.view.SimpleDraweeView; 7 | import com.susion.boring.R; 8 | import com.susion.boring.base.ui.SimpleItemHandler; 9 | import com.susion.boring.base.adapter.ViewHolder; 10 | import com.susion.boring.music.mvp.view.PlayListActivity; 11 | import com.susion.boring.music.mvp.model.PlayList; 12 | import com.susion.boring.utils.UIUtils; 13 | 14 | /** 15 | * Created by susion on 17/2/23. 16 | */ 17 | public class MusicPagePlayListIH extends SimpleItemHandler { 18 | 19 | 20 | private SimpleDraweeView mSDVCover; 21 | 22 | @Override 23 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 24 | super.onCreateItemHandler(vh, parent); 25 | mSDVCover = vh.get(R.id.item_play_list_iv_cover); 26 | } 27 | 28 | @Override 29 | public void onBindDataView(ViewHolder vh, PlayList data, int position) { 30 | mSDVCover.setImageURI(data.getCoverImgUrl()); 31 | vh.getTextView(R.id.item_play_list_tv_name).setText(data.getName()); 32 | vh.getTextView(R.id.item_play_list_tv_play_count).setText(UIUtils.translatePlayCount(data.getPlayCount())); 33 | } 34 | 35 | @Override 36 | public int getLayoutResId() { 37 | return R.layout.item_music_play_list; 38 | } 39 | 40 | @Override 41 | public void onClick(View v) { 42 | PlayListActivity.start(mContext, mData); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/itemhandler/MusicPageTitleIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.itemhandler; 2 | 3 | import android.support.v7.widget.StaggeredGridLayoutManager; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.susion.boring.R; 8 | import com.susion.boring.base.ui.SimpleItemHandler; 9 | import com.susion.boring.base.adapter.ViewHolder; 10 | import com.susion.boring.music.mvp.model.SimpleTitle; 11 | 12 | /** 13 | * Created by susion on 17/2/23. 14 | */ 15 | public class MusicPageTitleIH extends SimpleItemHandler{ 16 | 17 | 18 | @Override 19 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 20 | super.onCreateItemHandler(vh, parent); 21 | ViewGroup.LayoutParams layoutParams = vh.getConvertView().getLayoutParams(); 22 | if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) { 23 | ((StaggeredGridLayoutManager.LayoutParams) layoutParams).setFullSpan(true); 24 | } 25 | } 26 | 27 | @Override 28 | public void onBindDataView(ViewHolder vh, SimpleTitle data, int position) { 29 | 30 | } 31 | 32 | @Override 33 | public int getLayoutResId() { 34 | return R.layout.item_simple_title; 35 | } 36 | 37 | @Override 38 | public void onClick(View v) { 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/itemhandler/PLayListIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.itemhandler; 2 | 3 | import android.view.View; 4 | 5 | import com.susion.boring.R; 6 | import com.susion.boring.base.ui.SimpleItemHandler; 7 | import com.susion.boring.base.adapter.ViewHolder; 8 | import com.susion.boring.music.mvp.model.PlayList; 9 | 10 | /** 11 | * Created by susion on 17/3/6. 12 | */ 13 | public class PLayListIH extends SimpleItemHandler { 14 | @Override 15 | public void onBindDataView(ViewHolder vh, PlayList data, int position) { 16 | 17 | } 18 | 19 | @Override 20 | public int getLayoutResId() { 21 | return R.layout.item_like_play_list; 22 | } 23 | 24 | @Override 25 | public void onClick(View v) { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/itemhandler/SearchMusicResultIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.itemhandler; 2 | 3 | import android.text.TextUtils; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.susion.boring.base.adapter.ViewHolder; 8 | import com.susion.boring.event.AddToNextPlayEvent; 9 | import com.susion.boring.music.mvp.view.PlayMusicActivity; 10 | import com.susion.boring.music.mvp.model.Song; 11 | import com.susion.boring.utils.ToastUtils; 12 | import com.susion.boring.utils.UIUtils; 13 | 14 | import org.greenrobot.eventbus.EventBus; 15 | 16 | /** 17 | * Created by susion on 17/1/20. 18 | */ 19 | public class SearchMusicResultIH extends SimpleMusicIH { 20 | 21 | public SearchMusicResultIH(boolean showNextPlay) { 22 | super(showNextPlay); 23 | } 24 | 25 | @Override 26 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 27 | super.onCreateItemHandler(vh, parent); 28 | mTvDuration.setVisibility(View.INVISIBLE); 29 | } 30 | 31 | @Override 32 | protected void onAddToNextPlayClick() { 33 | ToastUtils.showShort("已经添加下一首播放"); 34 | EventBus.getDefault().post(new AddToNextPlayEvent(mData)); 35 | } 36 | 37 | @Override 38 | protected void onItemClick() { 39 | PlayMusicActivity.start(mContext, mData, false); 40 | } 41 | 42 | @Override 43 | protected void bindData(ViewHolder vh, Song data, int position) { 44 | mTvTile.setText(data.name); 45 | if (!data.artists.isEmpty()) { 46 | mTvSecondTile.setText(data.artists.get(0).name + "-" + data.album.name); 47 | } 48 | UIUtils.loadSmallPicture(mSdvAlbum, data.album.picUrl); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/itemhandler/SimpleMusicIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.itemhandler; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.facebook.drawee.view.SimpleDraweeView; 9 | import com.susion.boring.R; 10 | import com.susion.boring.base.ui.SimpleItemHandler; 11 | import com.susion.boring.base.adapter.ViewHolder; 12 | 13 | 14 | /** 15 | * Created by susion on 17/2/15. 16 | */ 17 | public abstract class SimpleMusicIH extends SimpleItemHandler { 18 | 19 | protected SimpleDraweeView mSdvAlbum; 20 | protected TextView mTvTile; 21 | protected TextView mTvSecondTile; 22 | protected TextView mTvDuration; 23 | protected ImageView mIvNextPlay; 24 | 25 | private boolean mShowNextPlay; 26 | 27 | public SimpleMusicIH(boolean showNextPlay) { 28 | this.mShowNextPlay = showNextPlay; 29 | } 30 | 31 | @Override 32 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 33 | super.onCreateItemHandler(vh, parent); 34 | mSdvAlbum = vh.get(R.id.item_local_music_iv_album_pic); 35 | mTvSecondTile = vh.getTextView(R.id.item_local_music_tv_artist_album); 36 | mTvTile = vh.getTextView(R.id.item_local_music_tv_music_name); 37 | mTvDuration = vh.getTextView(R.id.item_local_music_tv_duration); 38 | mIvNextPlay = vh.getImageView(R.id.item_local_music_iv_add_to_next_play); 39 | 40 | if (!mShowNextPlay) { 41 | mIvNextPlay.setVisibility(View.INVISIBLE); 42 | } else { 43 | mIvNextPlay.setOnClickListener(this); 44 | } 45 | } 46 | 47 | @Override 48 | public void onBindDataView(ViewHolder vh, final T data, int position) { 49 | bindData(vh, data, position); 50 | } 51 | 52 | @Override 53 | public int getLayoutResId() { 54 | return R.layout.item_local_music; 55 | } 56 | 57 | @Override 58 | public void onClick(View view) { 59 | if (view.getId() == R.id.item_local_music_iv_add_to_next_play) { 60 | onAddToNextPlayClick(); 61 | return; 62 | } 63 | 64 | onItemClick(); 65 | } 66 | 67 | protected abstract void onAddToNextPlayClick(); 68 | 69 | protected abstract void onItemClick(); 70 | 71 | protected abstract void bindData(ViewHolder vh, final T data, int position); 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/contract/FileDownContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.contract; 2 | 3 | import com.susion.boring.base.view.IView; 4 | import com.susion.boring.music.mvp.model.DownTask; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by susion on 17/2/20. 10 | * 11 | * because copyright , no use 12 | */ 13 | public interface FileDownContract { 14 | 15 | interface View extends IView { 16 | void errorDownTask(DownTask view); 17 | 18 | void updateDownTaskProgress(DownTask view); 19 | 20 | void successDownTask(DownTask mCurrentTask); 21 | } 22 | 23 | interface Presenter { 24 | 25 | boolean addDownTask(DownTask url); 26 | 27 | boolean removeDownTask(DownTask url); 28 | 29 | List getTaskList(); 30 | 31 | DownTask getCurrentDownTask(); 32 | 33 | boolean stopDown(DownTask task); 34 | 35 | boolean isDowning(DownTask task); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/contract/LocalMusicContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.contract; 2 | 3 | import android.app.LoaderManager; 4 | import com.susion.boring.base.view.IView; 5 | import com.susion.boring.music.mvp.model.SimpleSong; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created with Android Studio. 11 | * User: ryan.hoo.j@gmail.com 12 | * Date: 9/13/16 13 | * Time: 8:32 PM 14 | * Desc: LocalMusicContract 15 | */ 16 | /* package */ public interface LocalMusicContract { 17 | 18 | interface View extends IView { 19 | LoaderManager getMyLoaderManager(); 20 | 21 | void showScanResult(List songs); 22 | 23 | void showScanErrorUI(); 24 | 25 | void hideScanLocalMusicUI(); 26 | 27 | void startScanLocalMusic(); 28 | } 29 | 30 | interface Presenter{ 31 | void loadLocalMusic(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/contract/MusicServiceContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.contract; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.susion.boring.music.mvp.model.PlayList; 7 | import com.susion.boring.music.mvp.model.Song; 8 | 9 | import java.util.List; 10 | 11 | import rx.Observable; 12 | 13 | /** 14 | * Created by susion on 17/2/24. 15 | */ 16 | public interface MusicServiceContract { 17 | 18 | interface Service { 19 | void loadMusicInfo(Song song, boolean autoPlay); 20 | 21 | void playMusic(); 22 | 23 | void pausePlay(); 24 | 25 | void seekTo(Intent intent); 26 | 27 | void saveLastPlayMusic(); 28 | 29 | void informCurrentPlayMusic(); 30 | 31 | void informCurrentIfPlayProgress(); 32 | 33 | void updateSong(Song song); 34 | 35 | Context getContext(); 36 | 37 | void notifyCurrentPlayMusic(boolean isPlaying); 38 | 39 | void clear(); 40 | 41 | void playNextMusic(); 42 | 43 | void PlayPreMusic(); 44 | 45 | void changeMusic(Song song); 46 | 47 | void startCircleMode(); 48 | 49 | void startRandomMode(); 50 | 51 | void songToNextPlay(Song serializableExtra); 52 | 53 | void notifyCurrentMode(); 54 | 55 | void circlePlayPlayList(PlayList playList); 56 | 57 | void getPlayQueue(); 58 | 59 | void randomPlayPlayList(PlayList playList); 60 | 61 | void removeSongFromQueue(Song serializableExtra); 62 | 63 | void startQueueMode(); 64 | 65 | void addMusicToQueue(Song song); 66 | } 67 | 68 | 69 | interface PlayQueueControlPresenter { 70 | int QUEUE_MODE = 0; 71 | int RANDOM_MODE = 1; 72 | int CIRCLE_MODE = 2; 73 | int PLAY_LIST_CIRCLE_MODE = 3; 74 | 75 | boolean addToPlayQueue(Song song); 76 | 77 | boolean randomPlayQueueMusic(); 78 | 79 | boolean addToNextPlay(Song song); 80 | 81 | Song getNextPlayMusic(); 82 | 83 | Song getPrePlayMusic(); 84 | 85 | void clearPlayQueue(); 86 | 87 | void setPlayMode(int mode); 88 | 89 | int getPlayMode(); 90 | 91 | Observable reLoadPlayQueue(PlayList playList); 92 | 93 | List getPlayQueue(); 94 | 95 | boolean removeSong(Song song); 96 | 97 | void markCurrentPlayMusic(Song song); 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/Album.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by susion on 17/1/20. 7 | */ 8 | public class Album implements Serializable { 9 | public String id; 10 | public String name; 11 | public Singer artist; 12 | public String picUrl; 13 | 14 | public Album(String name) { 15 | this.name = name; 16 | } 17 | 18 | public Album(String name, String picUrl) { 19 | this.name = name; 20 | this.picUrl = picUrl; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/DownTask.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by susion on 17/2/17. 7 | */ 8 | public class DownTask { 9 | public static final int DOWN_ERROR = 1; 10 | public static final int DOWN_SUCCESS = 2; 11 | public String uri; 12 | public Map params; 13 | public String taskName; 14 | 15 | public long currentDownSize; 16 | public long totalSize; 17 | public float currentProgress; 18 | public long networkSpeed; 19 | public int downStatus; 20 | 21 | public DownTask(String uri) { 22 | this.uri = uri; 23 | } 24 | 25 | public void setDownInfo(long currentSize, long totalSize, float progress, long networkSpeed){ 26 | this.currentDownSize = currentSize; 27 | this.totalSize = totalSize; 28 | this.networkSpeed = networkSpeed; 29 | this.currentProgress = progress; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/GetPlayListResult.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by susion on 17/2/23. 7 | */ 8 | public class GetPlayListResult { 9 | private List playlists; 10 | private String code; 11 | private boolean more; 12 | private int total; 13 | 14 | public List getPlaylists() { 15 | return playlists; 16 | } 17 | 18 | public void setPlaylists(List playlists) { 19 | this.playlists = playlists; 20 | } 21 | 22 | public String getCode() { 23 | return code; 24 | } 25 | 26 | public void setCode(String code) { 27 | this.code = code; 28 | } 29 | 30 | public boolean isMore() { 31 | return more; 32 | } 33 | 34 | public void setMore(boolean more) { 35 | this.more = more; 36 | } 37 | 38 | public int getTotal() { 39 | return total; 40 | } 41 | 42 | public void setTotal(int total) { 43 | this.total = total; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/Lyric.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | /** 4 | * Created by susion on 17/2/8. 5 | */ 6 | public class Lyric { 7 | public static int NO_MEASURE = -1; 8 | 9 | public String version; 10 | public String time; 11 | public String lyric; 12 | public int pos; 13 | public int height = NO_MEASURE; 14 | 15 | public Lyric(String time, String lyric, int pos) { 16 | this.time = time; 17 | this.lyric = lyric; 18 | this.pos = pos; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/LyricResult.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | /** 4 | * Created by susion on 17/2/8. 5 | */ 6 | public class LyricResult { 7 | 8 | public String sgc; 9 | public String sfy; 10 | public String qfy; 11 | public Lyric lrc; 12 | public Lyric klyric; 13 | public Lyric tlyric; 14 | public String code; 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/MusicPageConstantItem.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | /** 4 | * Created by susion on 17/1/21. 5 | */ 6 | public class MusicPageConstantItem { 7 | public int iconId; 8 | public String item; 9 | public String appendDesc; 10 | public int type; 11 | 12 | public MusicPageConstantItem(int iconId, String item, int type) { 13 | this.iconId = iconId; 14 | this.item = item; 15 | this.type = type; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/MusicSearchResult.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by susion on 17/1/20. 7 | */ 8 | public class MusicSearchResult{ 9 | 10 | public int code; 11 | public SearchResult result; 12 | 13 | public class SearchResult{ 14 | public int songCount; 15 | public List songs; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/PlayList.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import com.litesuits.orm.db.annotation.PrimaryKey; 4 | import com.litesuits.orm.db.annotation.Table; 5 | import com.litesuits.orm.db.enums.AssignType; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Created by susion on 17/2/23. 11 | */ 12 | @Table("play_list") 13 | public class PlayList implements Serializable { 14 | @PrimaryKey(AssignType.BY_MYSELF) 15 | public String id; 16 | 17 | private String name; 18 | private String coverImgUrl; 19 | private int trackCount; 20 | private int playCount; 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public String getId() { 31 | return id; 32 | } 33 | 34 | public void setId(String id) { 35 | this.id = id; 36 | } 37 | 38 | public String getCoverImgUrl() { 39 | return coverImgUrl; 40 | } 41 | 42 | public void setCoverImgUrl(String coverImgUrl) { 43 | this.coverImgUrl = coverImgUrl; 44 | } 45 | 46 | public int getPlayCount() { 47 | return playCount; 48 | } 49 | 50 | public void setPlayCount(int playCount) { 51 | this.playCount = playCount; 52 | } 53 | 54 | public int getTrackCount() { 55 | return trackCount; 56 | } 57 | 58 | public void setTrackCount(int trackCount) { 59 | this.trackCount = trackCount; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/PlayQueueSong.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | /** 4 | * Created by susion on 17/3/2. 5 | */ 6 | public interface PlayQueueSong { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/SimpleTitle.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | /** 4 | * Created by susion on 17/2/23. 5 | */ 6 | public class SimpleTitle { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/Singer.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by susion on 17/1/20. 7 | */ 8 | public class Singer implements Serializable{ 9 | public String id; 10 | public String name; 11 | public String picUrl; 12 | 13 | public Singer(String name) { 14 | this.name = name; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/model/Song.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.model; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.google.gson.annotations.SerializedName; 6 | import com.susion.boring.base.entity.FavoriteMark; 7 | 8 | import java.io.Serializable; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by susion on 17/1/20. 13 | * model for request accept wang yi music API 14 | */ 15 | public class Song extends FavoriteMark implements Serializable, PlayQueueSong { 16 | public String id; 17 | public String name; 18 | 19 | @SerializedName("ar") 20 | public List artists; 21 | @SerializedName("al") 22 | public Album album; 23 | public String audio; 24 | 25 | public String mp3Url; 26 | public boolean hasDown; 27 | public boolean fromPlayList; 28 | public boolean isPlaying; 29 | 30 | public SimpleSong translateToSimpleSong() { 31 | SimpleSong simpleSong = new SimpleSong(); 32 | 33 | if (!TextUtils.isEmpty(audio)) { 34 | simpleSong.setPath(audio); 35 | } else { 36 | simpleSong.setPath(mp3Url); 37 | } 38 | 39 | simpleSong.setDisplayName(name); 40 | simpleSong.setId(id); 41 | simpleSong.setArtist(artists.get(0).name); 42 | simpleSong.setFavorite(favorite); 43 | simpleSong.setHasDown(hasDown); 44 | simpleSong.setPicPath(album.picUrl); 45 | return simpleSong; 46 | } 47 | 48 | 49 | public String getArtist() { 50 | String artist = ""; 51 | if (artists != null && !artists.isEmpty()) { 52 | for (int i = 0; i < artists.size(); i++) { 53 | if (i == 0) { 54 | artist = artists.get(i).name; 55 | } else { 56 | artist += "、" + artists.get(i).name; 57 | } 58 | } 59 | } 60 | return artist; 61 | } 62 | 63 | @Override 64 | public boolean equals(Object o) { 65 | if (this == o) return true; 66 | if (o == null || getClass() != o.getClass()) return false; 67 | 68 | Song song = (Song) o; 69 | 70 | return id.equals(song.id); 71 | 72 | } 73 | 74 | @Override 75 | public int hashCode() { 76 | return id.hashCode(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/mvp/presenter/PlayMusicPresenter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.mvp.presenter; 2 | 3 | import android.content.Context; 4 | 5 | import com.susion.boring.music.mvp.model.Song; 6 | import com.susion.boring.music.mvp.contract.MediaPlayerContract; 7 | import com.susion.boring.utils.SPUtils; 8 | 9 | /** 10 | * Created by susion on 17/2/8. 11 | *

12 | * extension 13 | */ 14 | public class PlayMusicPresenter extends MediaPlayPresenter implements MediaPlayerContract.PlayMusicControlPresenter { 15 | 16 | public PlayMusicPresenter(MediaPlayerContract.MediaPlayerRefreshView mView, Context mContext) { 17 | super(mView, mContext); 18 | } 19 | 20 | @Override 21 | public void saveLastPlayMusic(Song song, Context c) { 22 | if (song != null && song.hasDown) { 23 | SPUtils.writeStringConfig(SPUtils.KEY_LAST_PLAY_MUSIC, song.id); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/service/action/ClientPlayControlCommand.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.service.action; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.v4.content.LocalBroadcastManager; 6 | 7 | import com.susion.boring.music.mvp.model.Song; 8 | import com.susion.boring.music.mvp.contract.MediaPlayerContract; 9 | import com.susion.boring.music.service.MusicServiceInstruction; 10 | 11 | /** 12 | * Created by susion on 17/3/2. 13 | */ 14 | public class ClientPlayControlCommand implements MediaPlayerContract.ClientPlayControlCommand { 15 | 16 | private Context mContext; 17 | 18 | public ClientPlayControlCommand(Context mContext) { 19 | this.mContext = mContext; 20 | } 21 | 22 | @Override 23 | public void changeToNextMusic() { 24 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PLAY_NEXT); 25 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 26 | } 27 | 28 | @Override 29 | public void changeToPreMusic() { 30 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PLAY_PRE); 31 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 32 | } 33 | 34 | @Override 35 | public void getCurrentPlayMusic() { 36 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_CURRENT_PLAY_MUSIC); 37 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 38 | } 39 | 40 | @Override 41 | public void pausePlay() { 42 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PAUSE_MUSIC); 43 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 44 | } 45 | 46 | @Override 47 | public void play() { 48 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PLAY_MUSIC); 49 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 50 | } 51 | 52 | @Override 53 | public void seekProgressTo(int currentProgress) { 54 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_SEEK_TO); 55 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_SEEK_TO_POS, currentProgress); 56 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/service/action/ClientPlayModeCommand.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.service.action; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.v4.content.LocalBroadcastManager; 6 | 7 | import com.susion.boring.music.mvp.model.PlayList; 8 | import com.susion.boring.music.mvp.contract.MediaPlayerContract; 9 | import com.susion.boring.music.mvp.model.Song; 10 | import com.susion.boring.music.service.MusicServiceInstruction; 11 | 12 | /** 13 | * Created by susion on 17/3/2. 14 | */ 15 | public class ClientPlayModeCommand implements MediaPlayerContract.ClientPlayModeCommand { 16 | 17 | private Context mContext; 18 | 19 | public ClientPlayModeCommand(Context mContext) { 20 | this.mContext = mContext; 21 | } 22 | 23 | @Override 24 | public void startCirclePlayMode() { 25 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PLAY_MODE_CIRCLE); 26 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 27 | } 28 | 29 | @Override 30 | public void startRandomPlayMode() { 31 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PLAY_MODE_RANDOM); 32 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 33 | } 34 | 35 | @Override 36 | public void circlePlayPlayList(PlayList mData) { 37 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_CIRCLE_PLAY_PLAY_LIST); 38 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_PLAY_LIST, mData); 39 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 40 | } 41 | 42 | @Override 43 | public void randomPlayPlayList(PlayList mPlayList) { 44 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_RANDOM_PLAY_PLAY_LIST); 45 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_PLAY_LIST, mPlayList); 46 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 47 | } 48 | 49 | @Override 50 | public void startQueuePlayMode() { 51 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_PLAY_MODE_QUEUE); 52 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 53 | } 54 | 55 | @Override 56 | public void queryCurrentPlayMode() { 57 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_SONG_QUERY_CUR_MODE); 58 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/service/action/ClientPlayQueueControlCommand.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.service.action; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.v4.content.LocalBroadcastManager; 6 | 7 | import com.susion.boring.music.mvp.model.Song; 8 | import com.susion.boring.music.mvp.contract.MediaPlayerContract; 9 | import com.susion.boring.music.service.MusicServiceInstruction; 10 | 11 | /** 12 | * Created by susion on 17/3/3. 13 | */ 14 | public class ClientPlayQueueControlCommand implements MediaPlayerContract.ClientPlayQueueControlCommand{ 15 | private Context mContext; 16 | 17 | public ClientPlayQueueControlCommand(Context c) { 18 | mContext = c; 19 | } 20 | 21 | @Override 22 | public void getPlayQueue() { 23 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_GET_PLAY_QUEUE); 24 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 25 | } 26 | 27 | @Override 28 | public void removeSongFromQueue(Song song) { 29 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_REMOVE_SONG_FROM_QUEUE); 30 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_REMOVE_SONG, song); 31 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 32 | } 33 | 34 | @Override 35 | public void changeMusic(Song song) { 36 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_CHANGE_MUSIC); 37 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_CHANGE_MUSIC, song); 38 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 39 | 40 | } 41 | 42 | @Override 43 | public void addMusicToQueue(Song song) { 44 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_ADD_MUSIC_TO_QUEUE); 45 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_QUEUE_ADD_SONG, song); 46 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 47 | } 48 | 49 | @Override 50 | public void addMusicToNextPlay(Song song) { 51 | Intent intent = new Intent(MusicServiceInstruction.SERVER_RECEIVER_SONG_TO_NEXT_PLAY); 52 | intent.putExtra(MusicServiceInstruction.SERVER_PARAM_SONG_TO_NEXT_PLAY, song); 53 | LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/music/view/MediaPlayerThumb.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.music.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Canvas; 6 | import android.graphics.Paint; 7 | import android.graphics.RectF; 8 | import android.graphics.drawable.BitmapDrawable; 9 | import android.graphics.drawable.Drawable; 10 | 11 | import com.susion.boring.R; 12 | 13 | /** 14 | * Created by susion on 16/11/9. 15 | */ 16 | public class MediaPlayerThumb { 17 | 18 | private static final double CIRCLE1_PADDING_PERCENT = 0.8; 19 | private static final double CIRCLE2_PADDING_PERCENT = 0.5; 20 | int width; 21 | int height; 22 | 23 | private Bitmap bitmap; 24 | private Drawable drawable; 25 | 26 | 27 | public MediaPlayerThumb(int height, int width, Context mContext) { 28 | this.height = height; 29 | this.width = width; 30 | 31 | int circle1Padding = (int) (width * CIRCLE1_PADDING_PERCENT); 32 | int circle2Padding = (int) (width * CIRCLE2_PADDING_PERCENT); 33 | 34 | bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 35 | Canvas canvas = new Canvas(bitmap); 36 | 37 | Paint paint = new Paint(); 38 | RectF ovalRect1 = new RectF(0, 0, width, height); 39 | paint.setColor(mContext.getResources().getColor(R.color.transparent)); 40 | paint.setStyle(Paint.Style.FILL); 41 | 42 | RectF ovalRect2 = new RectF(circle1Padding, circle1Padding, width - circle1Padding, height - circle1Padding); 43 | paint.setColor(mContext.getResources().getColor(R.color.thumb_out)); 44 | paint.setStyle(Paint.Style.FILL); 45 | canvas.drawOval(ovalRect2, paint); 46 | 47 | RectF ovalRect3 = new RectF(circle2Padding, circle2Padding, width - circle2Padding, height - circle2Padding); 48 | paint.setColor(mContext.getResources().getColor(R.color.white)); 49 | paint.setStyle(Paint.Style.FILL); 50 | canvas.drawOval(ovalRect3, paint); 51 | canvas.save(); 52 | drawable = new BitmapDrawable(mContext.getResources(), bitmap); 53 | } 54 | 55 | public Bitmap getBitmap() { 56 | return bitmap; 57 | } 58 | 59 | public Drawable getDrawable() { 60 | return drawable; 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/adapter/ZhiHuDailyAdapter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.adapter; 2 | 3 | import android.app.Activity; 4 | 5 | import com.susion.boring.base.adapter.BaseRVAdapter; 6 | import com.susion.boring.base.ui.ItemHandler; 7 | import com.susion.boring.base.ui.ItemHandlerFactory; 8 | import com.susion.boring.read.itemhandler.DailyNewsDateIH; 9 | import com.susion.boring.read.itemhandler.DailyNewsIH; 10 | import com.susion.boring.read.itemhandler.TopNewsIH; 11 | import com.susion.boring.read.mvp.entity.DailyNewsDate; 12 | import com.susion.boring.read.mvp.entity.NewsDetail; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by susion on 17/3/9. 18 | */ 19 | public class ZhiHuDailyAdapter extends BaseRVAdapter { 20 | 21 | private static final int TYPE_NEWS = 1; 22 | private static final int TYPE_DATE = 2; 23 | private static final int TYPE_TOP_NEWS = 3; 24 | 25 | public ZhiHuDailyAdapter(Activity activity, List data) { 26 | super(activity, data); 27 | } 28 | 29 | @Override 30 | protected void initHandlers() { 31 | registerItemHandler(TYPE_TOP_NEWS, new ItemHandlerFactory() { 32 | @Override 33 | public ItemHandler newInstant(int viewType) { 34 | return new TopNewsIH(); 35 | } 36 | }); 37 | 38 | registerItemHandler(TYPE_NEWS, new ItemHandlerFactory() { 39 | @Override 40 | public ItemHandler newInstant(int viewType) { 41 | return new DailyNewsIH(); 42 | } 43 | }); 44 | 45 | registerItemHandler(TYPE_DATE, new ItemHandlerFactory() { 46 | @Override 47 | public ItemHandler newInstant(int viewType) { 48 | return new DailyNewsDateIH(); 49 | } 50 | }); 51 | } 52 | 53 | @Override 54 | protected int getViewType(int position) { 55 | 56 | Object item = getItem(position); 57 | 58 | if (item instanceof List) { 59 | return TYPE_TOP_NEWS; 60 | } 61 | 62 | if (item instanceof NewsDetail) { 63 | return TYPE_NEWS; 64 | } 65 | 66 | if (item instanceof DailyNewsDate) { 67 | return TYPE_DATE; 68 | } 69 | 70 | return 0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/itemhandler/DailyNewsDateIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.itemhandler; 2 | 3 | import android.view.View; 4 | 5 | import com.susion.boring.R; 6 | import com.susion.boring.base.ui.SimpleItemHandler; 7 | import com.susion.boring.base.adapter.ViewHolder; 8 | import com.susion.boring.read.mvp.entity.DailyNewsDate; 9 | 10 | /** 11 | * Created by susion on 17/3/9. 12 | */ 13 | public class DailyNewsDateIH extends SimpleItemHandler{ 14 | 15 | @Override 16 | public void onBindDataView(ViewHolder vh, DailyNewsDate data, int position) { 17 | vh.getTextView(R.id.item_daily_news_date_tv_date).setText(data.date+""); 18 | } 19 | 20 | @Override 21 | public int getLayoutResId() { 22 | return R.layout.item_daily_news_date; 23 | } 24 | 25 | @Override 26 | public void onClick(View v) { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/itemhandler/DailyNewsIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.itemhandler; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | 6 | import com.facebook.drawee.view.SimpleDraweeView; 7 | import com.susion.boring.R; 8 | import com.susion.boring.base.ui.SimpleItemHandler; 9 | import com.susion.boring.base.adapter.ViewHolder; 10 | import com.susion.boring.read.mvp.entity.NewsDetail; 11 | import com.susion.boring.read.mvp.view.ZhiHuEssayActivity; 12 | 13 | /** 14 | * Created by susion on 17/3/9. 15 | */ 16 | public class DailyNewsIH extends SimpleItemHandler { 17 | 18 | @Override 19 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 20 | super.onCreateItemHandler(vh, parent); 21 | } 22 | 23 | @Override 24 | public void onBindDataView(ViewHolder vh, NewsDetail data, int position) { 25 | vh.getTextView(R.id.item_daily_new_tv_title).setText(data.getTitle()); 26 | SimpleDraweeView mIvImg = vh.get(R.id.item_daily_new_iv_img); 27 | if (data.getImages() != null && !data.getImages().isEmpty()) { 28 | mIvImg.setImageURI(data.getImages().get(0)); 29 | } else if (data.getImage() != null) { 30 | mIvImg.setImageURI(data.getImage()); 31 | } 32 | } 33 | 34 | @Override 35 | public int getLayoutResId() { 36 | return R.layout.item_daily_news; 37 | } 38 | 39 | @Override 40 | public void onClick(View v) { 41 | ZhiHuEssayActivity.start(mContext, mData.getId(), mData.date); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/itemhandler/PictureCategoryIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.itemhandler; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | import android.widget.TextView; 6 | 7 | import com.susion.boring.R; 8 | import com.susion.boring.base.adapter.ViewHolder; 9 | import com.susion.boring.base.ui.SimpleItemHandler; 10 | import com.susion.boring.read.mvp.entity.PictureCategoryResult; 11 | import com.susion.boring.utils.UIUtils; 12 | 13 | /** 14 | * Created by susion on 17/3/27. 15 | */ 16 | public class PictureCategoryIH extends SimpleItemHandler { 17 | 18 | private TextView mTvTitle; 19 | 20 | @Override 21 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 22 | super.onCreateItemHandler(vh, parent); 23 | mTvTitle = vh.getTextView(R.id.item_picture_category_tv_name); 24 | 25 | ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mTvTitle.getLayoutParams(); 26 | layoutParams.leftMargin = UIUtils.dp2Px(10); 27 | } 28 | 29 | @Override 30 | public void onBindDataView(ViewHolder vh, PictureCategoryResult.CategoryList.PictureCategory data, int position) { 31 | mTvTitle.setText(data.getName()); 32 | mTvTitle.setTextColor(UIUtils.getColor(mContext, R.color.colorPrimary)); 33 | } 34 | 35 | @Override 36 | public int getLayoutResId() { 37 | return R.layout.item_picture_category; 38 | } 39 | 40 | @Override 41 | public void onClick(View v) { 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/itemhandler/PictureColumnIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.itemhandler; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | import android.widget.TextView; 6 | 7 | import com.susion.boring.R; 8 | import com.susion.boring.base.adapter.ViewHolder; 9 | import com.susion.boring.base.ui.SimpleItemHandler; 10 | import com.susion.boring.event.PictureCategorySelectedEvent; 11 | import com.susion.boring.read.mvp.entity.PictureCategoryResult; 12 | import com.susion.boring.utils.UIUtils; 13 | 14 | import org.greenrobot.eventbus.EventBus; 15 | 16 | /** 17 | * Created by susion on 17/3/26. 18 | */ 19 | public class PictureColumnIH extends SimpleItemHandler { 20 | 21 | private TextView mTvTitle; 22 | 23 | @Override 24 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 25 | super.onCreateItemHandler(vh, parent); 26 | mTvTitle = vh.getTextView(R.id.item_picture_category_tv_name); 27 | ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mTvTitle.getLayoutParams(); 28 | layoutParams.leftMargin = UIUtils.dp2Px(25); 29 | } 30 | 31 | @Override 32 | public void onBindDataView(ViewHolder vh, PictureCategoryResult.CategoryList.PictureCategory.Column data, int position) { 33 | mTvTitle.setText(data.getName()); 34 | mTvTitle.setTextColor(UIUtils.getColor(mContext, R.color.colorAccent)); 35 | } 36 | 37 | @Override 38 | public int getLayoutResId() { 39 | return R.layout.item_picture_category; 40 | } 41 | 42 | @Override 43 | public void onClick(View v) { 44 | EventBus.getDefault().post(new PictureCategorySelectedEvent(mData.getId())); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/itemhandler/TopNewsIH.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.itemhandler; 2 | 3 | import android.support.v4.view.ViewPager; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import com.susion.boring.R; 8 | import com.susion.boring.base.adapter.QuickPageAdapter; 9 | import com.susion.boring.base.adapter.ViewHolder; 10 | import com.susion.boring.base.ui.SimpleItemHandler; 11 | import com.susion.boring.read.mvp.entity.DailyNews; 12 | import com.susion.boring.read.view.BannerView; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by susion on 17/3/15. 19 | */ 20 | public class TopNewsIH extends SimpleItemHandler> { 21 | 22 | private ViewPager mViewPager; 23 | 24 | @Override 25 | public void onCreateItemHandler(ViewHolder vh, ViewGroup parent) { 26 | super.onCreateItemHandler(vh, parent); 27 | mViewPager = vh.get(R.id.view_pager); 28 | } 29 | 30 | @Override 31 | public void onBindDataView(ViewHolder vh, List data, int position) { 32 | List mBannerViews = new ArrayList<>(); 33 | for (DailyNews.TopStoriesBean bean : data) { 34 | BannerView view = new BannerView(mContext, bean); 35 | view.setTitle(bean.getTitle()); 36 | view.setImgUrl(bean.getImage()); 37 | mBannerViews.add(view); 38 | } 39 | mViewPager.setAdapter(new QuickPageAdapter<>(mBannerViews)); 40 | mViewPager.setOffscreenPageLimit(3); 41 | } 42 | 43 | @Override 44 | public int getLayoutResId() { 45 | return R.layout.item_top_news; 46 | } 47 | 48 | @Override 49 | public void onClick(View v) { 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/contract/ZhiHuDailyContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.contract; 2 | 3 | import com.susion.boring.base.view.IView; 4 | import com.susion.boring.read.mvp.entity.DailyNews; 5 | import com.susion.boring.read.mvp.entity.NewsDetail; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by susion on 17/3/9. 12 | */ 13 | public interface ZhiHuDailyContract { 14 | 15 | int LATEST_NEWS = 0; 16 | int AFTER_DAY_NEWS = 1; 17 | 18 | interface View extends IView { 19 | void addNewsData(List news); 20 | 21 | void setDataForViewPage(List banners); 22 | } 23 | 24 | 25 | interface Presenter { 26 | void loadData(int page); 27 | 28 | void setCurrentDate(Date date); 29 | } 30 | 31 | interface DailyNewsStickHeader { 32 | String getTitle(int position); 33 | 34 | int getHeaderColor(int position); 35 | 36 | boolean isShowTitle(int position); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/contract/ZhiHuEssayContract.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.contract; 2 | 3 | import com.susion.boring.base.view.IView; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by susion on 17/3/14. 9 | */ 10 | public interface ZhiHuEssayContract { 11 | 12 | interface View extends IView { 13 | void showEssayContent(String contentHtml); 14 | 15 | void setHeaderImage(String url); 16 | 17 | void refreshLikeStatus(boolean status); 18 | } 19 | 20 | interface Presenter { 21 | void loadEssay(String essayId); 22 | 23 | void loadPreEssay(); 24 | 25 | void loadNextEssay(); 26 | 27 | void likeEssay(); 28 | } 29 | 30 | interface EssayQueue { 31 | String getPreEssayId(); 32 | 33 | String getNextEssayId(); 34 | 35 | void loadEssayQueue(List ids); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/entity/DailyNews.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.entity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by susion on 17/3/9. 7 | */ 8 | public class DailyNews { 9 | 10 | private String date; 11 | private List stories; 12 | private List top_stories; 13 | 14 | public String getDate() { 15 | return date; 16 | } 17 | 18 | public void setDate(String date) { 19 | this.date = date; 20 | } 21 | 22 | public List getStories() { 23 | return stories; 24 | } 25 | 26 | public void setStories(List stories) { 27 | this.stories = stories; 28 | } 29 | 30 | public List getTop_stories() { 31 | return top_stories; 32 | } 33 | 34 | public void setTop_stories(List top_stories) { 35 | this.top_stories = top_stories; 36 | } 37 | 38 | public static class TopStoriesBean { 39 | private String image; 40 | private int type; 41 | private String id; 42 | private String ga_prefix; 43 | private String title; 44 | 45 | public String getImage() { 46 | return image; 47 | } 48 | 49 | public void setImage(String image) { 50 | this.image = image; 51 | } 52 | 53 | public int getType() { 54 | return type; 55 | } 56 | 57 | public void setType(int type) { 58 | this.type = type; 59 | } 60 | 61 | public String getId() { 62 | return id; 63 | } 64 | 65 | public void setId(String id) { 66 | this.id = id; 67 | } 68 | 69 | public String getGa_prefix() { 70 | return ga_prefix; 71 | } 72 | 73 | public void setGa_prefix(String ga_prefix) { 74 | this.ga_prefix = ga_prefix; 75 | } 76 | 77 | public String getTitle() { 78 | return title; 79 | } 80 | 81 | public void setTitle(String title) { 82 | this.title = title; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/entity/DailyNewsDate.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.entity; 2 | 3 | /** 4 | * Created by susion on 17/3/9. 5 | */ 6 | public class DailyNewsDate { 7 | public String date; 8 | 9 | public DailyNewsDate(String date) { 10 | this.date = date; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/entity/Joke.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.entity; 2 | 3 | import com.litesuits.orm.db.annotation.PrimaryKey; 4 | import com.litesuits.orm.db.annotation.Table; 5 | import com.litesuits.orm.db.enums.AssignType; 6 | 7 | /** 8 | * Created by susion on 17/3/16. 9 | */ 10 | @Table("joke") 11 | public class Joke { 12 | 13 | @PrimaryKey(AssignType.BY_MYSELF) 14 | private String hashId; 15 | 16 | private String content; 17 | private String unixtime; 18 | 19 | public String getContent() { 20 | return content; 21 | } 22 | 23 | public void setContent(String content) { 24 | this.content = content; 25 | } 26 | 27 | public String getHashId() { 28 | return hashId; 29 | } 30 | 31 | public void setHashId(String hashId) { 32 | this.hashId = hashId; 33 | } 34 | 35 | public String getUnixtime() { 36 | return unixtime; 37 | } 38 | 39 | public void setUnixtime(String unixtime) { 40 | this.unixtime = unixtime; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/entity/JokeList.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.entity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by susion on 17/3/16. 7 | */ 8 | public class JokeList { 9 | 10 | private String reason; 11 | private int error_code; 12 | private List result; 13 | 14 | public String getReason() { 15 | return reason; 16 | } 17 | 18 | public void setReason(String reason) { 19 | this.reason = reason; 20 | } 21 | 22 | public int getError_code() { 23 | return error_code; 24 | } 25 | 26 | public void setError_code(int error_code) { 27 | this.error_code = error_code; 28 | } 29 | 30 | public List getResult() { 31 | return result; 32 | } 33 | 34 | public void setResult(List result) { 35 | this.result = result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/entity/SimplePicture.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.entity; 2 | 3 | import com.litesuits.orm.db.annotation.PrimaryKey; 4 | import com.litesuits.orm.db.annotation.Table; 5 | import com.litesuits.orm.db.enums.AssignType; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Created by susion on 17/3/17. 11 | */ 12 | @Table("picture") 13 | public class SimplePicture implements Serializable { 14 | 15 | @PrimaryKey(AssignType.BY_MYSELF) 16 | public String id; 17 | 18 | private String big; 19 | private String small; 20 | private String middle; 21 | 22 | public String getBig() { 23 | return big; 24 | } 25 | 26 | public void setBig(String big) { 27 | this.big = big; 28 | } 29 | 30 | public String getSmall() { 31 | return small; 32 | } 33 | 34 | public void setSmall(String small) { 35 | this.small = small; 36 | } 37 | 38 | public String getMiddle() { 39 | return middle; 40 | } 41 | 42 | public void setMiddle(String middle) { 43 | this.middle = middle; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/entity/ZhiHuEssay.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.entity; 2 | 3 | import com.susion.boring.base.entity.FavoriteMark; 4 | 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by susion on 17/3/28. 10 | */ 11 | public class ZhiHuEssay extends FavoriteMark { 12 | public String id; 13 | public int type; 14 | public String ga_prefix; 15 | public String title; 16 | public List images; 17 | public Date date; 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/presenter/ZhiHuEssayQueuePresenter.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.presenter; 2 | 3 | import com.susion.boring.read.mvp.contract.ZhiHuEssayContract; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by susion on 17/3/14. 9 | */ 10 | public class ZhiHuEssayQueuePresenter implements ZhiHuEssayContract.EssayQueue { 11 | 12 | private int mCurrentIndex; 13 | private List mEssayIds; 14 | 15 | 16 | public String getPreEssayId() { 17 | if (mEssayIds == null || mEssayIds.isEmpty()) { 18 | return null; 19 | } 20 | 21 | mCurrentIndex--; 22 | if (mCurrentIndex >= 0 && mCurrentIndex < mEssayIds.size()) { 23 | return mEssayIds.get(mCurrentIndex); 24 | } 25 | return null; 26 | } 27 | 28 | public String getNextEssayId() { 29 | if (mEssayIds == null || mEssayIds.isEmpty()) { 30 | return null; 31 | } 32 | mCurrentIndex++; 33 | if (mCurrentIndex < mEssayIds.size() && mCurrentIndex >= 0) { 34 | return mEssayIds.get(mCurrentIndex); 35 | } 36 | 37 | return null; 38 | } 39 | 40 | public String getCurrentEssayId() { 41 | return mEssayIds.get(mCurrentIndex); 42 | } 43 | 44 | public void loadEssayQueue(List ids) { 45 | mEssayIds = ids; 46 | mCurrentIndex = 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/mvp/view/NestChildViewPager.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.mvp.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.PointF; 5 | import android.support.v4.view.ViewPager; 6 | import android.util.AttributeSet; 7 | 8 | /** 9 | * Created by susion on 17/3/15. 10 | */ 11 | public class NestChildViewPager extends ViewPager { 12 | 13 | PointF mDownPoint; 14 | PointF mCurPoint; 15 | 16 | public NestChildViewPager(Context context) { 17 | super(context); 18 | } 19 | 20 | public NestChildViewPager(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | init(); 23 | } 24 | 25 | private void init() { 26 | mDownPoint = new PointF(); 27 | mCurPoint = new PointF(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/view/BannerView.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.view; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.LinearLayout; 6 | import android.widget.TextView; 7 | 8 | import com.facebook.drawee.view.SimpleDraweeView; 9 | import com.susion.boring.R; 10 | import com.susion.boring.read.mvp.entity.DailyNews; 11 | import com.susion.boring.read.mvp.view.ZhiHuEssayActivity; 12 | 13 | import java.util.Date; 14 | 15 | /** 16 | * Created by susion on 17/3/9. 17 | */ 18 | public class BannerView extends LinearLayout { 19 | 20 | private SimpleDraweeView mSdvImag; 21 | private TextView mTvTitle; 22 | private DailyNews.TopStoriesBean topNews; 23 | 24 | public BannerView(Context context) { 25 | super(context); 26 | initView(); 27 | } 28 | 29 | public BannerView(Context context, DailyNews.TopStoriesBean news) { 30 | super(context); 31 | topNews = news; 32 | initView(); 33 | } 34 | 35 | private void initView() { 36 | View.inflate(getContext(), R.layout.view_banner, this); 37 | mSdvImag = (SimpleDraweeView) findViewById(R.id.view_banner_iv_img); 38 | mTvTitle = (TextView) findViewById(R.id.view_banner_tv_title); 39 | 40 | setOnClickListener(new OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | ZhiHuEssayActivity.start(getContext(), topNews.getId(), new Date()); 44 | } 45 | }); 46 | } 47 | 48 | public void setTitle(String title) { 49 | mTvTitle.setText(title + ""); 50 | } 51 | 52 | public void setImgUrl(String url) { 53 | mSdvImag.setImageURI(url); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/read/view/FixedPopupWindow.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.read.view; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.util.AttributeSet; 7 | import android.view.Gravity; 8 | import android.view.View; 9 | import android.widget.PopupWindow; 10 | 11 | import com.susion.boring.base.SAppApplication; 12 | 13 | 14 | /** 15 | * Created by susion on 11/7/16. 16 | */ 17 | public class FixedPopupWindow extends PopupWindow { 18 | public FixedPopupWindow(Context context) { 19 | super(context); 20 | } 21 | 22 | public FixedPopupWindow(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | public FixedPopupWindow(Context context, AttributeSet attrs, int defStyle) { 27 | super(context, attrs, defStyle); 28 | } 29 | 30 | public FixedPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 31 | super(context, attrs, defStyleAttr, defStyleRes); 32 | } 33 | 34 | public FixedPopupWindow(View contentView) { 35 | super(contentView); 36 | } 37 | 38 | public FixedPopupWindow() { 39 | super(); 40 | } 41 | 42 | public FixedPopupWindow(int width, int height) { 43 | super(width, height); 44 | } 45 | 46 | public FixedPopupWindow(View contentView, int width, int height, boolean focusable) { 47 | super(contentView, width, height, focusable); 48 | } 49 | 50 | public FixedPopupWindow(View contentView, int width, int height) { 51 | super(contentView, width, height); 52 | } 53 | 54 | 55 | @Override 56 | public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 57 | if (isShowing() || getContentView() == null) { 58 | return; 59 | } 60 | 61 | if (Build.VERSION.SDK_INT >= 24) { 62 | int[] a = new int[2]; 63 | anchor.getLocationInWindow(a); 64 | 65 | Context context = SAppApplication.getAppContext(); 66 | if (context instanceof Activity) { 67 | showAtLocation(((Activity) context).getWindow().getDecorView(), Gravity.NO_GRAVITY, xoff, yoff + a[1] + anchor.getHeight()); 68 | } else { 69 | super.showAsDropDown(anchor, xoff, yoff, gravity); 70 | } 71 | } else { 72 | super.showAsDropDown(anchor, xoff, yoff, gravity); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/BroadcastUtils.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.v4.content.LocalBroadcastManager; 6 | 7 | 8 | /** 9 | * Created by susion on 17/2/13. 10 | */ 11 | public class BroadcastUtils { 12 | public static void sendIntentAction(Context context, String action) { 13 | Intent intent = new Intent(action); 14 | LocalBroadcastManager.getInstance(context).sendBroadcast(intent); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/Md5Utils.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | 7 | /** 8 | * Created by susion on 17/2/21. 9 | */ 10 | public class Md5Utils { 11 | 12 | public static String md5(String str) { 13 | MessageDigest messageDigest = null; 14 | 15 | try { 16 | messageDigest = MessageDigest.getInstance("MD5"); 17 | 18 | messageDigest.reset(); 19 | 20 | messageDigest.update(str.getBytes("UTF-8")); 21 | } catch (NoSuchAlgorithmException e) { 22 | System.out.println("NoSuchAlgorithmException caught!"); 23 | System.exit(-1); 24 | } catch (UnsupportedEncodingException e) { 25 | e.printStackTrace(); 26 | } 27 | 28 | byte[] byteArray = messageDigest.digest(); 29 | 30 | StringBuffer md5StrBuff = new StringBuffer(); 31 | 32 | for (int i = 0; i < byteArray.length; i++) { 33 | if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) 34 | md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i])); 35 | else 36 | md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); 37 | } 38 | //16位加密,从第9位到25位 39 | return md5StrBuff.toString().toUpperCase(); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/PictureLoadHelper.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | /** 9 | * Created by susion on 17/3/27. 10 | */ 11 | public class PictureLoadHelper { 12 | 13 | private static final int MAX_ERROR_TIME = 50; 14 | private static Map mCategoryLoadErrorGraphic = new HashMap<>(); 15 | 16 | public static Set mDiscardCategory = new HashSet<>(); 17 | 18 | public static void addLoadErrorTimeForType(String mTypeId) { 19 | if (mCategoryLoadErrorGraphic.containsKey(mTypeId)) { 20 | int errorTime = mCategoryLoadErrorGraphic.get(mTypeId); 21 | if (errorTime > MAX_ERROR_TIME) { 22 | mDiscardCategory.add(mTypeId); 23 | } 24 | 25 | mCategoryLoadErrorGraphic.put(mTypeId, errorTime + 1); 26 | return; 27 | } 28 | mCategoryLoadErrorGraphic.put(mTypeId, 0); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/SPUtils.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import com.google.gson.Gson; 7 | import com.susion.boring.base.SAppApplication; 8 | 9 | /** 10 | * Created by susion on 17/2/13. 11 | */ 12 | public class SPUtils { 13 | 14 | private static final String APP_CONFIG = "susion_config"; 15 | private static Context mContext; 16 | 17 | public static final String KEY_SHORTCUT = "shortcut"; 18 | public static final String KEY_LAST_PLAY_MUSIC = "last_play_music"; 19 | 20 | private SPUtils() { 21 | } 22 | 23 | private static SharedPreferences getMSharedPreferences() { 24 | if (mContext == null) { 25 | mContext = SAppApplication.getAppContext(); 26 | } 27 | return mContext.getSharedPreferences(APP_CONFIG, mContext.MODE_PRIVATE); 28 | } 29 | 30 | public static void writeStringConfig(String key, String value) { 31 | SharedPreferences.Editor edit = getMSharedPreferences().edit(); 32 | edit.putString(key, value); 33 | edit.commit(); 34 | } 35 | 36 | public static String getStringFromConfig(String key) { 37 | return getMSharedPreferences().getString(key, ""); 38 | } 39 | 40 | public static boolean getBooleanFromConfig(String key) { 41 | return getMSharedPreferences().getBoolean(key, false); 42 | } 43 | 44 | public static void setBooleanConfig(String key, boolean flag) { 45 | SharedPreferences.Editor edit = getMSharedPreferences().edit(); 46 | edit.putBoolean(key, flag); 47 | edit.commit(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/StatusBarView.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | 7 | /** 8 | * Created by Jaeger on 16/6/8. 9 | * 10 | * Email: chjie.jaeger@gmail.com 11 | * GitHub: https://github.com/laobie 12 | */ 13 | public class StatusBarView extends View { 14 | public StatusBarView(Context context, AttributeSet attrs) { 15 | super(context, attrs); 16 | } 17 | public StatusBarView(Context context) { 18 | super(context); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | /** 4 | * Created by susion on 17/3/14. 5 | */ 6 | public class StringUtils { 7 | 8 | public static String getCssLinkString() { 9 | StringBuilder builder = new StringBuilder(); 10 | builder.append(""); 13 | return builder.toString(); 14 | } 15 | 16 | public static String getHTMLHead(String... links) { 17 | StringBuilder builder = new StringBuilder(); 18 | builder.append(""); 19 | for (String link : links) { 20 | builder.append(link); 21 | } 22 | builder.append(""); 23 | builder.append(""); 24 | return builder.toString(); 25 | } 26 | 27 | public static String getCSSStyle(String tempCssString) { 28 | StringBuilder builder = new StringBuilder(); 29 | builder.append(" "); 32 | return builder.toString(); 33 | } 34 | 35 | public static String getHtmlString(String head, String body) { 36 | StringBuilder builder = new StringBuilder(); 37 | builder.append(""); 38 | builder.append(head); 39 | builder.append(""); 40 | builder.append(body); 41 | builder.append(""); 42 | builder.append(""); 43 | return builder.toString(); 44 | } 45 | 46 | public static String adjustEsssayHtmlStyle(String htmlString) { 47 | return htmlString.replace("class=\"img-place-holder\"", ""); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/susion/boring/utils/ToastUtils.java: -------------------------------------------------------------------------------- 1 | package com.susion.boring.utils; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.susion.boring.base.SAppApplication; 6 | 7 | 8 | /** 9 | * Toast Util 10 | * Created by sam on 14-9-13. 11 | */ 12 | public class ToastUtils { 13 | 14 | private ToastUtils() { 15 | } 16 | 17 | public static void showShort(int resId) { 18 | Toast.makeText(SAppApplication.getAppContext(), resId, Toast.LENGTH_SHORT).show(); 19 | } 20 | 21 | public static void showShort(String message) { 22 | Toast.makeText(SAppApplication.getAppContext(), message, Toast.LENGTH_SHORT).show(); 23 | } 24 | 25 | public static void showLong(int resId) { 26 | Toast.makeText(SAppApplication.getAppContext(), resId, Toast.LENGTH_LONG).show(); 27 | } 28 | 29 | public static void showLong(String message) { 30 | Toast.makeText(SAppApplication.getAppContext(), message, Toast.LENGTH_LONG).show(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_dialog_enter_formbottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_dialog_exit_formbottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_window_right_entry.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_window_right_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_ripple_accent_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_ripple_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_search_bar_bt.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_search_bar_tv.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_shape_corner_rectangle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_shape_rect_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_transparent_ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_view_load_more.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 10 | 11 | 14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/play_music_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 11 | 12 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shadow_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SusionSuc/android-learn-music/2dcaed6649ce2df7abe07e226e1a05f5155abce1/app/src/main/res/drawable/shadow_bottom.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/shadow_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SusionSuc/android-learn-music/2dcaed6649ce2df7abe07e226e1a05f5155abce1/app/src/main/res/drawable/shadow_left.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/shadow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SusionSuc/android-learn-music/2dcaed6649ce2df7abe07e226e1a05f5155abce1/app/src/main/res/drawable/shadow_right.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_search_bar_cursor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_author.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_base_swipeback.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_collect.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 16 | 17 | 25 | 26 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | 19 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_music_down_load_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_my_music_collect.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 23 | 24 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_picture_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 16 | 22 | 23 | 33 | 34 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_search_music.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 16 | 17 | 22 | 23 | 27 | 28 | 34 | 35 | 36 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_zhi_hu_daily_news.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 15 | 16 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | 40 | 41 | 42 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_play_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 20 | 21 | 22 | 26 | 27 | 31 | 32 | 33 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_interseting_page_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_joke_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_music_page_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 17 | 18 | 23 | 24 | 25 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_picture_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_player_page_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_zhi_hu_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_refresh_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_daily_news.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 17 | 18 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_daily_news_date.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_dialog_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 15 | 16 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_dialog_music_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 29 | 30 | 40 | 41 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_drawer_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 29 | 30 | 31 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_drawer_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 16 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_interesting_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 17 | 20 | 21 | 31 | 32 | 33 | 44 | 45 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_joke.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 18 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_like_play_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_load_more.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_lyric.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_music_down.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 18 | 25 | 26 | 27 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_music_page_constant.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 22 | 23 | 24 | 32 | 33 | 34 | 43 | 44 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_music_play_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 18 | 25 | 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_picture_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_simple_picture.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_simple_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 15 | 16 | 21 | 22 | 28 | 29 | 30 | 39 | 40 | 41 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_top_news.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_left_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_music_play_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 19 | 20 | 21 | 26 | 27 | 34 | 35 | 42 | 43 | 44 | 45 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_picture_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_play_operator.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 17 | 18 | 27 | 28 | 37 | 38 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_search_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 29 | 30 |