├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── encodings.xml ├── markdown-navigator.xml ├── markdown-navigator │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── viewpagertext │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── Satisfy-Regular.ttf │ ├── java │ │ └── com │ │ │ └── viewpagertext │ │ │ ├── Lrc │ │ │ ├── DefaultLrcBuilder.java │ │ │ ├── ILrcBuilder.java │ │ │ ├── ILrcView.java │ │ │ ├── ILrcViewListener.java │ │ │ └── LrcRow.java │ │ │ ├── activitys │ │ │ ├── LocalActivity.java │ │ │ ├── LoginActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── PlayActivity.java │ │ │ ├── ProjectHomeActivity.java │ │ │ └── WelcomeActivity.java │ │ │ ├── adapters │ │ │ ├── BannerViewHolder.java │ │ │ ├── HomeFragmentStatePagerAdapter.java │ │ │ ├── ListRecAdapter.java │ │ │ ├── LocalAdapter.java │ │ │ ├── LocalSongRecAdapter.java │ │ │ ├── MusicGridAdapter.java │ │ │ ├── PlayFragmentPagerAdapter.java │ │ │ └── VideoAdapter.java │ │ │ ├── app │ │ │ └── ScrollShapeUIApplication.java │ │ │ ├── constructor │ │ │ ├── fragments │ │ │ ├── FindFragment.java │ │ │ ├── FriendFragment.java │ │ │ ├── ListFragment.java │ │ │ ├── LocalPlayFragment.java │ │ │ ├── LoginFragment.java │ │ │ ├── MyFragment.java │ │ │ ├── RegisterFragment.java │ │ │ ├── SongFragment.java │ │ │ └── localSongFragment.java │ │ │ ├── help │ │ │ └── MediaPlayerHelp.java │ │ │ ├── json │ │ │ ├── HotSongs.java │ │ │ ├── HotVideo.java │ │ │ └── ListFragmentSongMusics.java │ │ │ ├── utils │ │ │ ├── CommonUtils.java │ │ │ ├── CustomChangeBounds.java │ │ │ ├── HttpUtil.java │ │ │ ├── LoadSongUtils.java │ │ │ ├── PermissionUtils.java │ │ │ ├── StatusBarUtil.java │ │ │ ├── StatusBarView.java │ │ │ ├── TimeUtil.java │ │ │ ├── TypefacesUtil.java │ │ │ └── UserUtils.java │ │ │ └── views │ │ │ ├── GridSpaceitemDecoration.java │ │ │ ├── Lead.java │ │ │ ├── LeadTextView.java │ │ │ ├── LrcView.java │ │ │ ├── MarqueeTextView.java │ │ │ ├── MyNestedScrollView.java │ │ │ ├── MyRoundedImageView.java │ │ │ └── MyYViewpager.java │ └── res │ │ ├── anim │ │ ├── anim_animo_alph_close.xml │ │ ├── anim_animo_alph_open.xml │ │ ├── in_from_left.xml │ │ ├── main_bottom_pic_rotate.xml │ │ ├── out_to_right.xml │ │ └── rotate_player_loading.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── bg_login.xml │ │ ├── bg_login_button.xml │ │ ├── bg_login_edit.xml │ │ ├── btn_h.xml │ │ ├── btn_n.xml │ │ ├── btn_nav_close_n.xml │ │ ├── btn_nav_close_select.xml │ │ ├── btn_select.xml │ │ ├── ic_launcher_background.xml │ │ ├── layer_player_playing_progress.xml │ │ ├── my_icon_h.xml │ │ ├── my_icon_n.xml │ │ ├── my_icon_select.xml │ │ ├── selector_player_playing_thumb.xml │ │ └── stroke_radius.xml │ │ ├── layout │ │ ├── activity_local.xml │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_movie_detail.xml │ │ ├── activity_play.xml │ │ ├── activity_project_home.xml │ │ ├── activity_welcome.xml │ │ ├── banner_item.xml │ │ ├── find_grid_music.xml │ │ ├── fragment_find.xml │ │ ├── fragment_friend.xml │ │ ├── fragment_localplay.xml │ │ ├── fragment_localsong.xml │ │ ├── fragment_login.xml │ │ ├── fragment_my.xml │ │ ├── fragment_register.xml │ │ ├── fragment_song.xml │ │ ├── friend_video_item.xml │ │ ├── header_slide_shape.xml │ │ ├── item_layout.xml │ │ ├── layout_bottom.xml │ │ ├── layout_toolbar.xml │ │ ├── list_dialog.xml │ │ ├── load_item.xml │ │ ├── local_dialog.xml │ │ ├── nav_buttom.xml │ │ └── nav_header.xml │ │ ├── menu │ │ ├── nav_menu.xml │ │ └── toolbar.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── play_num.png │ │ ├── mipmap-xhdpi │ │ ├── a.png │ │ ├── b.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── localpause.png │ │ ├── localplay.png │ │ ├── navigation_back_white.png │ │ └── test.jpg │ │ ├── mipmap-xxhdpi │ │ ├── b_last.png │ │ ├── b_next.png │ │ ├── b_pause.png │ │ ├── b_play.png │ │ ├── back.png │ │ ├── banner1.png │ │ ├── banner2.png │ │ ├── banner3.png │ │ ├── banner4.png │ │ ├── banner5.png │ │ ├── banner6.png │ │ ├── bytemusic.png │ │ ├── find_list.png │ │ ├── find_newdate.png │ │ ├── find_song.png │ │ ├── ic_back.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── last.png │ │ ├── list_button_dialog_music_icon.png │ │ ├── list_dialog_like.png │ │ ├── local_dialog_album.png │ │ ├── local_dialog_delete.png │ │ ├── local_dialog_share.png │ │ ├── local_dialog_size.png │ │ ├── local_dialog_song.png │ │ ├── local_dialog_time.png │ │ ├── localmenu.png │ │ ├── localplay.png │ │ ├── low.png │ │ ├── m_icon_player_loading.png │ │ ├── m_icon_player_next_normal.png │ │ ├── m_icon_player_pause_normal.png │ │ ├── m_icon_player_play_normal.png │ │ ├── m_icon_player_previous_normal.png │ │ ├── my_download.png │ │ ├── my_local.png │ │ ├── nav_about.png │ │ ├── nav_close.png │ │ ├── nav_home.png │ │ ├── nav_key.png │ │ ├── nav_menu.png │ │ ├── next.png │ │ ├── pause.png │ │ ├── play.png │ │ ├── play_down.png │ │ ├── play_head.png │ │ ├── stackblur_default.png │ │ ├── toolbar_search.png │ │ └── wave.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── array.xml │ │ ├── colors.xml │ │ ├── dimen.xml │ │ ├── drawables.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── viewpagertext │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/assetWizardSettings.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | .idea/caches 44 | 45 | # Keystore files 46 | # Uncomment the following line if you do not want to check your keystore files in. 47 | #*.jks 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | 52 | # Google Services (e.g. APIs or Firebase) 53 | google-services.json 54 | 55 | # Freeline 56 | freeline.py 57 | freeline/ 58 | freeline_project_description.json 59 | 60 | # fastlane 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | fastlane/readme.md 66 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | -------------------------------------------------------------------------------- /.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 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2 | 名称:安浊音乐 3 | 4 | 5 | 2019.10.25:接口已失效 6 | 7 | 初学代码 8 | 9 | 10 | ![](https://img-blog.csdnimg.cn/20190629210808662.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMjY5NjQy,size_16,color_FFFFFF,t_70) 11 | 12 | ![](https://img-blog.csdnimg.cn/20190629210824388.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMjY5NjQy,size_16,color_FFFFFF,t_70) 13 | 14 | ![](https://img-blog.csdnimg.cn/20190629210745479.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMjY5NjQy,size_16,color_FFFFFF,t_70) 15 | 16 | ![](https://img-blog.csdnimg.cn/2019062921064528.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMjY5NjQy,size_16,color_FFFFFF,t_70) 17 | 18 | ![](https://img-blog.csdnimg.cn/20190629210703332.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMjY5NjQy,size_16,color_FFFFFF,t_70) 19 | 20 | 21 | 网络视频API(百思不得姐):https://api.apiopen.top 22 | 23 | 网络音乐API(MessApi):https://www.bzqll.com/ 24 | 25 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.viewpagertext" 7 | minSdkVersion 17 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | signingConfig signingConfigs.debug 17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 18 | } 19 | 20 | } 21 | 22 | // dataBinding 加入 23 | dataBinding { 24 | enabled = true 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(include: ['*.jar'], dir: 'libs') 30 | implementation 'androidx.appcompat:appcompat:1.0.0' 31 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 32 | testImplementation 'junit:junit:4.12' 33 | androidTestImplementation 'androidx.test:runner:1.1.0' 34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 35 | implementation 'com.github.LillteZheng:ViewPagerHelper:v1.3' 36 | implementation 'com.makeramen:roundedimageview:2.3.0' 37 | implementation 'com.google.android.material:material:1.0.0' 38 | implementation 'com.github.pinguo-zhouwei:MZBannerView:v2.0.2' 39 | implementation 'com.blankj:utilcode:1.11.1' 40 | implementation 'com.github.glomadrian:Grav:1.1' 41 | implementation 'org.greenrobot:eventbus:3.1.1' 42 | implementation 'com.github.bumptech.glide:glide:3.7.0' 43 | implementation 'jp.wasabeef:glide-transformations:2.0.1' 44 | implementation 'cn.youngkaaa:yviewpager:0.4' 45 | implementation 'com.squareup.okhttp3:okhttp:3.10.0' 46 | implementation 'com.google.code.gson:gson:2.8.5' 47 | implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'//节操视频播放 48 | } 49 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/viewpagertext/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.viewpagertext", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 19 | 23 | 24 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/assets/Satisfy-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xiosn/AndroidMusic/14721662e59a8175499c86bc86baa8e5fd68889d/app/src/main/assets/Satisfy-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/Lrc/DefaultLrcBuilder.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.Lrc; 2 | 3 | import android.util.Log; 4 | import java.io.BufferedReader; 5 | import java.io.IOException; 6 | import java.io.StringReader; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | //========================================================================================================= 12 | 13 | 14 | // ####DefaultLrcBuilder歌词解析构造器 15 | // 16 | // DefaultLrcBuilder实现ILrcBuilder接口,List getLrcRows(String rawLrc)方法会循环地读取歌词的每一行, 17 | // 然后调用LrcRow类的List createRows(String standardLrcLine)方法,得到解析每一行歌词之后的LrcRow集合, 18 | // 再将每一行得到LrcRow集合中得到的LrcRow实体加入一个总 的到LrcRow集合rows中去,然后将rows集合根据歌词行的时间排序, 19 | // 得到排序后的LrcRow集合,该集合就是最终的解析歌词后的内容了。 20 | 21 | 22 | //========================================================================================================= 23 | 24 | 25 | 26 | 27 | /** 28 | * 解析歌词,得到LrcRow的集合 29 | */ 30 | public class DefaultLrcBuilder implements ILrcBuilder { 31 | static final String TAG = "DefaultLrcBuilder"; 32 | 33 | public List getLrcRows(String rawLrc) { 34 | Log.d(TAG,"getLrcRows by rawString"); 35 | if(rawLrc == null || rawLrc.length() == 0){ 36 | Log.e(TAG,"getLrcRows rawLrc null or empty"); 37 | return null; 38 | } 39 | StringReader reader = new StringReader(rawLrc); 40 | BufferedReader br = new BufferedReader(reader); 41 | String line = null; 42 | List rows = new ArrayList(); 43 | try{ 44 | //循环地读取歌词的每一行 45 | do{ 46 | line = br.readLine(); 47 | /** 48 | 一行歌词只有一个时间的 例如:徐佳莹 《我好想你》 49 | [01:15.33]我好想你 好想你 50 | 51 | 一行歌词有多个时间的 例如:草蜢 《失恋战线联盟》 52 | [02:34.14][01:07.00]当你我不小心又想起她 53 | [02:45.69][02:42.20][02:37.69][01:10.60]就在记忆里画一个叉 54 | **/ 55 | Log.d(TAG,"lrc raw line: " + line); 56 | if(line != null && line.length() > 0){ 57 | //解析每一行歌词 得到每行歌词的集合,因为有些歌词重复有多个时间,就可以解析出多个歌词行来 58 | List lrcRows = LrcRow.createRows(line); 59 | if(lrcRows != null && lrcRows.size() > 0){ 60 | for(LrcRow row : lrcRows){ 61 | rows.add(row); 62 | } 63 | } 64 | } 65 | }while(line != null); 66 | 67 | if( rows.size() > 0 ){ 68 | // 根据歌词行的时间排序 69 | Collections.sort(rows); 70 | if(rows!=null&&rows.size()>0){ 71 | for(LrcRow lrcRow:rows){ 72 | Log.d(TAG, "lrcRow:" + lrcRow.toString()); 73 | } 74 | } 75 | } 76 | }catch(Exception e){ 77 | Log.e(TAG,"parse exceptioned:" + e.getMessage()); 78 | return null; 79 | }finally{ 80 | try { 81 | br.close(); 82 | } catch (IOException e) { 83 | e.printStackTrace(); 84 | } 85 | reader.close(); 86 | } 87 | return rows; 88 | } 89 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/Lrc/ILrcBuilder.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.Lrc; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 解析歌词,得到LrcRow的集合 7 | */ 8 | public interface ILrcBuilder { 9 | List getLrcRows(String rawLrc); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/Lrc/ILrcView.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.Lrc; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 展示歌词的接口 7 | */ 8 | public interface ILrcView { 9 | 10 | /** 11 | * 设置要展示的歌词行集合 12 | */ 13 | void setLrc(List lrcRows); 14 | 15 | /** 16 | * 音乐播放的时候调用该方法滚动歌词,高亮正在播放的那句歌词 17 | */ 18 | void seekLrcToTime(long time); 19 | /** 20 | * 设置歌词拖动时候的监听类 21 | */ 22 | void setListener(ILrcViewListener l); 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/Lrc/ILrcViewListener.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.Lrc; 2 | 3 | /** 4 | * 歌词拖动时候的监听类 5 | * 6 | * 当歌词被用户上下拖动的时候回调该方法 7 | */ 8 | 9 | 10 | public interface ILrcViewListener { 11 | /** 12 | * 当歌词被用户上下拖动的时候回调该方法 13 | */ 14 | void onLrcSeeked(int newPosition, LrcRow row); 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/Lrc/LrcRow.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.Lrc; 2 | 3 | import android.util.Log; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * 歌词行 10 | * 包括该行歌词的时间,歌词内容 11 | */ 12 | public class LrcRow implements Comparable{ 13 | public final static String TAG = "LrcRow"; 14 | 15 | /** 该行歌词要开始播放的时间,格式如下:[02:34.14] */ 16 | public String strTime; 17 | 18 | /** 该行歌词要开始播放的时间,由[02:34.14]格式转换为long型, 19 | * 即将2分34秒14毫秒都转为毫秒后 得到的long型值:time=02*60*1000+34*1000+14 20 | */ 21 | public long time; 22 | 23 | /** 该行歌词的内容 */ 24 | public String content; 25 | 26 | 27 | public LrcRow(){} 28 | 29 | public LrcRow(String strTime,long time,String content){ 30 | this.strTime = strTime; 31 | this.time = time; 32 | this.content = content; 33 | // Log.d(TAG,"strTime:" + strTime + " time:" + time + " content:" + content); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "[" + strTime + " ]" + content; 39 | } 40 | 41 | /** 42 | * 读取歌词的每一行内容,转换为LrcRow,加入到集合中 43 | */ 44 | public static List createRows(String standardLrcLine){ 45 | /** 46 | 一行歌词只有一个时间的 例如:徐佳莹 《我好想你》 47 | [01:15.33]我好想你 好想你 48 | 49 | 一行歌词有多个时间的 例如:草蜢 《失恋战线联盟》 50 | [02:34.14][01:07.00]当你我不小心又想起她 51 | [02:45.69][02:42.20][02:37.69][01:10.60]就在记忆里画一个叉 52 | **/ 53 | try{ 54 | if(standardLrcLine.indexOf("[") != 0 || standardLrcLine.indexOf("]") != 9 ){ 55 | return null; 56 | } 57 | //[02:34.14][01:07.00]当你我不小心又想起她 58 | //找到最后一个 ‘]’ 的位置 59 | int lastIndexOfRightBracket = standardLrcLine.lastIndexOf("]"); 60 | //歌词内容就是 ‘]’ 的位置之后的文本 eg: 当你我不小心又想起她 61 | String content = standardLrcLine.substring(lastIndexOfRightBracket + 1, standardLrcLine.length()); 62 | //歌词时间就是 ‘]’ 的位置之前的文本 eg: [02:34.14][01:07.00] 63 | 64 | /** 65 | 将时间格式转换一下 [mm:ss.SS][mm:ss.SS] 转换为 -mm:ss.SS--mm:ss.SS- 66 | 即:[02:34.14][01:07.00] 转换为 -02:34.14--01:07.00- 67 | */ 68 | String times = standardLrcLine.substring(0,lastIndexOfRightBracket + 1).replace("[", "-").replace("]", "-"); 69 | //通过 ‘-’ 来拆分字符串 70 | String arrTimes[] = times.split("-"); 71 | List listTimes = new ArrayList(); 72 | for(String temp : arrTimes){ 73 | if(temp.trim().length() == 0){ 74 | continue; 75 | } 76 | /** [02:34.14][01:07.00]当你我不小心又想起她 77 | * 78 | 上面的歌词的就可以拆分为下面两句歌词了 79 | [02:34.14]当你我不小心又想起她 80 | [01:07.00]当你我不小心又想起她 81 | */ 82 | LrcRow lrcRow = new LrcRow(temp, timeConvert(temp), content); 83 | listTimes.add(lrcRow); 84 | } 85 | return listTimes; 86 | }catch(Exception e){ 87 | Log.e(TAG,"createRows exception:" + e.getMessage()); 88 | return null; 89 | } 90 | } 91 | 92 | /** 93 | * 将解析得到的表示时间的字符转化为Long型 94 | */ 95 | private static long timeConvert(String timeString){ 96 | //因为给如的字符串的时间格式为XX:XX.XX,返回的long要求是以毫秒为单位 97 | //将字符串 XX:XX.XX 转换为 XX:XX:XX 98 | timeString = timeString.replace('.', ':'); 99 | //将字符串 XX:XX:XX 拆分 100 | String[] times = timeString.split(":"); 101 | // mm:ss:SS 102 | return Integer.valueOf(times[0]) * 60 * 1000 +//分 103 | Integer.valueOf(times[1]) * 1000 +//秒 104 | Integer.valueOf(times[2]) ;//毫秒 105 | } 106 | 107 | /** 108 | * 排序的时候,根据歌词的时间来排序 109 | */ 110 | public int compareTo(LrcRow another) { 111 | return (int)(this.time - another.time); 112 | } 113 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/activitys/LocalActivity.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.activitys; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | import androidx.databinding.DataBindingUtil; 5 | import androidx.fragment.app.Fragment; 6 | import android.os.Bundle; 7 | import com.viewpagertext.R; 8 | import com.viewpagertext.adapters.LocalAdapter; 9 | import com.viewpagertext.databinding.ActivityLocalBinding; 10 | import com.viewpagertext.fragments.localSongFragment; 11 | import com.viewpagertext.utils.StatusBarUtil; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * name :小龙虾 18 | * time :2019.5.21 19 | * type :本地音乐YViewPager切换 20 | */ 21 | 22 | public class LocalActivity extends AppCompatActivity { 23 | 24 | private List mDatas; 25 | private ActivityLocalBinding binding; 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | binding=DataBindingUtil.setContentView(this,R.layout.activity_local); 30 | initView(); 31 | } 32 | private void initView(){ 33 | initDatas(); 34 | LocalAdapter localAdapter=new LocalAdapter(getSupportFragmentManager(),mDatas); 35 | binding.localYViewPager.setAdapter(localAdapter); 36 | } 37 | 38 | private void initDatas(){ 39 | mDatas=new ArrayList<>(); 40 | mDatas.add(new localSongFragment()); 41 | // mDatas.add(new LocalPlayFragment()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/activitys/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.activitys; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import androidx.fragment.app.FragmentManager; 7 | import androidx.fragment.app.FragmentTransaction; 8 | import android.view.View; 9 | import com.viewpagertext.R; 10 | import com.viewpagertext.fragments.LoginFragment; 11 | import com.viewpagertext.utils.StatusBarUtil; 12 | 13 | /** 14 | * name:小龙虾 15 | * time:2019.5.4 16 | */ 17 | 18 | public class LoginActivity extends AppCompatActivity { 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_login); 24 | StatusBarUtil.setTransparent(this); 25 | initView();//Fragment切换 26 | } 27 | 28 | 29 | /** 30 | * 登录/注册页面切换 31 | * 替换为LoginFragment碎片 32 | */ 33 | private void initView(){ 34 | FragmentManager fragmentManager=getSupportFragmentManager(); 35 | FragmentTransaction ft=fragmentManager.beginTransaction(); 36 | ft.replace(R.id.frameContain,new LoginFragment()); 37 | ft.commit(); 38 | } 39 | 40 | /** 41 | * 登录界面Back返回按钮的回调 42 | */ 43 | public void backBtnOnClick(View v){ 44 | finish(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/activitys/PlayActivity.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.activitys; 2 | 3 | 4 | import androidx.databinding.DataBindingUtil; 5 | import androidx.fragment.app.Fragment; 6 | import android.os.Bundle; 7 | 8 | import androidx.appcompat.app.AppCompatActivity; 9 | import com.viewpagertext.R; 10 | import com.viewpagertext.adapters.PlayFragmentPagerAdapter; 11 | import com.viewpagertext.databinding.ActivityPlayBinding; 12 | import com.viewpagertext.fragments.ListFragment; 13 | import com.viewpagertext.fragments.SongFragment; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | 19 | /** 20 | * name:小龙虾 21 | * time:2019.5.4 22 | */ 23 | 24 | public class PlayActivity extends AppCompatActivity { 25 | 26 | private List mDatas; 27 | private ActivityPlayBinding binding; 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | 31 | super.onCreate(savedInstanceState); 32 | 33 | binding=DataBindingUtil.setContentView(this,R.layout.activity_play); 34 | 35 | initView();//实例化控件 36 | } 37 | 38 | private void initView(){ 39 | initDatas(); 40 | PlayFragmentPagerAdapter playFragmentPagerAdapter=new PlayFragmentPagerAdapter(getSupportFragmentManager(),mDatas); 41 | binding.playViewpager.setAdapter(playFragmentPagerAdapter); 42 | } 43 | 44 | private void initDatas(){ 45 | mDatas=new ArrayList<>(); 46 | mDatas.add(new ListFragment()); 47 | mDatas.add(new SongFragment()); 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/activitys/ProjectHomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.activitys; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | import androidx.databinding.DataBindingUtil; 5 | import android.os.Bundle; 6 | import android.webkit.WebViewClient; 7 | import com.viewpagertext.R; 8 | import com.viewpagertext.databinding.ActivityProjectHomeBinding; 9 | import com.viewpagertext.utils.StatusBarUtil; 10 | 11 | /** 12 | * name:小龙虾 13 | * time:2019.6.29 14 | */ 15 | public class ProjectHomeActivity extends AppCompatActivity { 16 | 17 | private ActivityProjectHomeBinding binding; 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_project_home); 22 | binding = DataBindingUtil.setContentView(this,R.layout.activity_project_home); 23 | StatusBarUtil.StatusBarTextColor(this,true); 24 | initView(); 25 | } 26 | 27 | private void initView(){ 28 | binding.ProjectHomeWebView.getSettings().setJavaScriptEnabled(true); 29 | binding.ProjectHomeWebView.setWebViewClient(new WebViewClient()); 30 | binding.ProjectHomeWebView.loadUrl("https://github.com/hsxiaodev/Share-Music"); 31 | } 32 | 33 | @Override 34 | public void onBackPressed() { 35 | super.onBackPressed(); 36 | finish(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/activitys/WelcomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.activitys; 2 | 3 | import android.content.Intent; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.WindowManager; 7 | import com.viewpagertext.R; 8 | import com.viewpagertext.utils.TypefacesUtil; 9 | import com.viewpagertext.views.Lead; 10 | import com.viewpagertext.views.LeadTextView; 11 | 12 | /** 13 | * name:小龙虾 14 | * time:2019.5.4 15 | * Type:启动欢迎页 16 | */ 17 | 18 | 19 | public class WelcomeActivity extends AppCompatActivity { 20 | 21 | LeadTextView leadTv; 22 | private static final int mDuration = 3000; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_welcome); 28 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏状态栏 29 | initView();//延时秒数 30 | initLeadText();//添加启动页动画 31 | } 32 | 33 | 34 | private void initLeadText(){ 35 | leadTv=findViewById(R.id.my_text_view); 36 | leadTv.setTypeface(TypefacesUtil.get(this,"Satisfy-Regular.ttf")); 37 | final Lead lead = new Lead(mDuration); 38 | lead.start(leadTv); 39 | new Lead(mDuration).start(leadTv); 40 | } 41 | 42 | 43 | private void initView(){ 44 | Thread td=new Thread(new Runnable() { 45 | @Override 46 | public void run() { 47 | try { 48 | Thread.sleep(3*900); 49 | toMain(); 50 | } catch (InterruptedException e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | }); 55 | td.start(); 56 | } 57 | 58 | 59 | /** 60 | * 跳转到主页MainActivity 61 | */ 62 | private void toMain(){ 63 | Intent intent=new Intent(this,MainActivity.class); 64 | startActivity(intent); 65 | finish(); 66 | overridePendingTransition(R.anim.in_from_left,R.anim.out_to_right);//过渡动画 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/BannerViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.widget.ImageView; 7 | import com.viewpagertext.R; 8 | import com.zhouwei.mzbanner.holder.MZViewHolder; 9 | 10 | /** 11 | * name:小龙虾 12 | * time:2019.5.4 13 | * Type:发现页Banner轮播图适配器 14 | */ 15 | 16 | public class BannerViewHolder implements MZViewHolder { 17 | 18 | private ImageView imageView; 19 | @Override 20 | public View createView(Context context) { 21 | View view= LayoutInflater.from(context).inflate(R.layout.banner_item,null); 22 | imageView=view.findViewById(R.id.banner_image); 23 | return view; 24 | } 25 | 26 | @Override 27 | public void onBind(Context context, int i, Integer integer) { 28 | imageView.setImageResource(integer); 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/HomeFragmentStatePagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.fragment.app.Fragment; 5 | import androidx.fragment.app.FragmentManager; 6 | import androidx.fragment.app.FragmentStatePagerAdapter; 7 | import android.view.ViewGroup; 8 | import java.util.List; 9 | 10 | /** 11 | * name:小龙虾 12 | * time:2019.5.4 13 | * Type:主页ViewPager适配器 14 | */ 15 | 16 | public class HomeFragmentStatePagerAdapter extends FragmentStatePagerAdapter { 17 | 18 | private List mDatas; 19 | 20 | 21 | public HomeFragmentStatePagerAdapter(FragmentManager fm, List mDatas) { 22 | super(fm); 23 | this.mDatas=mDatas; 24 | } 25 | 26 | /** 27 | * 获取子项 28 | * @param position 29 | * @return 30 | */ 31 | @Override 32 | public Fragment getItem(int position) { 33 | return mDatas.get(position); 34 | } 35 | 36 | 37 | /** 38 | * 获取子项数量 39 | * @return 40 | */ 41 | @Override 42 | public int getCount() { 43 | return mDatas.size(); 44 | } 45 | 46 | /** 47 | * 初始化子项 48 | * @param container 49 | * @param position 50 | * @return 51 | */ 52 | @NonNull 53 | @Override 54 | public Object instantiateItem(@NonNull ViewGroup container, int position) { 55 | return super.instantiateItem(container, position); 56 | } 57 | 58 | /** 59 | * 销毁子项 60 | * @param container 61 | * @param position 62 | * @param object 63 | */ 64 | @Override 65 | public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { 66 | super.destroyItem(container, position, object); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/ListRecAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.recyclerview.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | 13 | import com.viewpagertext.R; 14 | import com.viewpagertext.json.ListFragmentSongMusics; 15 | 16 | import java.util.ArrayList; 17 | 18 | import static com.blankj.utilcode.util.ActivityUtils.startActivity; 19 | 20 | /** 21 | * name:小龙虾 22 | * time:2019.5.4 23 | * Type:发现页9宫格RecyclerView适配器 24 | */ 25 | 26 | public class ListRecAdapter extends RecyclerView.Adapter implements View.OnClickListener{ 27 | private Context mContext; 28 | private ArrayList mData; 29 | public ListRecAdapter(Context context, ArrayList mData) { 30 | this.mContext=context; 31 | this.mData=mData; 32 | } 33 | 34 | @Override 35 | public NormalTextViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 36 | NormalTextViewHolder holder=new NormalTextViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_layout,viewGroup,false)); 37 | return holder; 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(NormalTextViewHolder viewHolder, final int position) { 42 | ListFragmentSongMusics.DataBean data=mData.get(position); 43 | viewHolder.Listt_song.setText(data.getName()); 44 | viewHolder.Listt_singer.setText(data.getSinger());//设置歌手 45 | 46 | viewHolder.itemView.setTag(position); 47 | viewHolder.ListFragment_menu.setTag(position); 48 | viewHolder.Listt_postion.setText(data.getNumber());//设置编号 49 | viewHolder.ListintoPlayPage.setTag(position); 50 | } 51 | 52 | //获取数据的数量 53 | @Override 54 | public int getItemCount() { 55 | return mData.size(); 56 | } 57 | 58 | 59 | //自定义的ViewHolder,持有每个Item的的所有界面元素 60 | public class NormalTextViewHolder extends RecyclerView.ViewHolder { 61 | TextView Listt_song,Listt_postion,Listt_singer; 62 | ImageView ListFragment_menu; 63 | LinearLayout ListintoPlayPage; 64 | 65 | public NormalTextViewHolder(View view){ 66 | super(view); 67 | 68 | ListFragment_menu=view.findViewById(R.id.ListFragment_menu);//菜单弹窗 69 | Listt_song = view.findViewById(R.id.Listt_song);//歌名 70 | Listt_postion=view.findViewById(R.id.Listt_postion); 71 | Listt_singer=view.findViewById(R.id.Listt_singer); 72 | ListintoPlayPage=view.findViewById(R.id.ListintoPlayPage); 73 | 74 | itemView.setOnClickListener(ListRecAdapter.this); 75 | ListFragment_menu.setOnClickListener(ListRecAdapter.this); 76 | ListintoPlayPage.setOnClickListener(ListRecAdapter.this); 77 | } 78 | } 79 | 80 | 81 | //=======================以下为item中的button控件点击事件处理=================================== 82 | 83 | //item里面有多个控件可以点击(item+item内部控件) 84 | public enum ViewName { 85 | ITEM, 86 | PRACTISE 87 | } 88 | 89 | 90 | //自定义一个回调接口来实现Click和LongClick事件 91 | public interface OnItemClickListener { 92 | void onItemClick(View v, ViewName viewName, int position); 93 | void onItemLongClick(View v); 94 | } 95 | 96 | 97 | private OnItemClickListener mOnItemClickListener;//声明自定义的接口 98 | 99 | 100 | //定义方法并传给外面的使用者 101 | public void setOnItemClickListener(OnItemClickListener listener) { 102 | this.mOnItemClickListener = listener; 103 | } 104 | 105 | @Override 106 | public void onClick(View v) { 107 | int position = (int) v.getTag(); //getTag()获取数据 108 | if (mOnItemClickListener != null) { 109 | switch (v.getId()){ 110 | case R.id.xrv_list: 111 | mOnItemClickListener.onItemClick(v, ViewName.PRACTISE, position); 112 | break; 113 | default: 114 | mOnItemClickListener.onItemClick(v, ViewName.ITEM, position); 115 | break; 116 | } 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/LocalAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import androidx.fragment.app.Fragment; 4 | import androidx.fragment.app.FragmentManager; 5 | import androidx.fragment.app.FragmentPagerAdapter; 6 | import java.util.List; 7 | 8 | /** 9 | * name:小龙虾 10 | * time:20.19.5.21 11 | */ 12 | public class LocalAdapter extends FragmentPagerAdapter { 13 | 14 | 15 | private List Datas; 16 | public LocalAdapter(FragmentManager fm,List Datas) { 17 | super(fm); 18 | this.Datas=Datas; 19 | } 20 | 21 | @Override 22 | public Fragment getItem(int position) { 23 | return Datas.get(position); 24 | } 25 | 26 | @Override 27 | public int getCount() { 28 | return Datas.size(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/LocalSongRecAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | import androidx.annotation.NonNull; 10 | import androidx.recyclerview.widget.RecyclerView; 11 | import com.viewpagertext.R; 12 | import com.viewpagertext.constructor.Song; 13 | import java.util.List; 14 | 15 | public class LocalSongRecAdapter extends RecyclerView.Adapterimplements View.OnClickListener{ 16 | 17 | private Context context; 18 | private List list; 19 | 20 | public LocalSongRecAdapter(Context context,List list){ 21 | this.context=context; 22 | this.list=list; 23 | } 24 | 25 | @NonNull 26 | @Override 27 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 28 | MyViewHolder myViewHodler=new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.load_item,parent,false)); 29 | return myViewHodler; 30 | 31 | } 32 | 33 | @Override 34 | public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { 35 | holder.t_position.setText(position + 1 + ""); 36 | holder.t_song.setText(list.get(position).song); 37 | holder.t_singer.setText(list.get(position).singer); 38 | 39 | holder.itemView.setTag(position); 40 | holder.t_position.setTag(position); 41 | holder.t_song.setTag(position); 42 | holder.t_singer.setTag(position); 43 | holder.localmenu.setTag(position); 44 | } 45 | 46 | @Override 47 | public int getItemCount() { 48 | return list.size(); 49 | } 50 | 51 | class MyViewHolder extends RecyclerView.ViewHolder{ 52 | 53 | private TextView t_position,t_song,t_singer; 54 | private ImageView localmenu; 55 | public MyViewHolder(View itemView) { 56 | super(itemView); 57 | t_position=itemView.findViewById(R.id.t_postion); 58 | t_song=itemView.findViewById(R.id.t_song); 59 | t_singer=itemView.findViewById(R.id.t_singer); 60 | localmenu=itemView.findViewById(R.id.localmenu); 61 | 62 | itemView.setOnClickListener(LocalSongRecAdapter.this); 63 | localmenu.setOnClickListener(LocalSongRecAdapter.this); 64 | } 65 | } 66 | 67 | //=======================以下为item中的button控件点击事件处理=================================== 68 | 69 | //item里面有多个控件可以点击(item+item内部控件) 70 | public enum ViewName { 71 | ITEM, 72 | PRACTISE 73 | } 74 | 75 | //自定义一个回调接口来实现Click和LongClick事件 76 | public interface OnItemClickListener { 77 | void onItemClick(View v, ViewName viewName, int position); 78 | void onItemLongClick(View v); 79 | } 80 | 81 | private OnItemClickListener mOnItemClickListener;//声明自定义的接口 82 | 83 | //定义方法并传给外面的使用者 84 | public void setOnItemClickListener(OnItemClickListener listener) { 85 | this.mOnItemClickListener = listener; 86 | } 87 | 88 | @Override 89 | public void onClick(View v) { 90 | int position = (int) v.getTag(); //getTag()获取数据 91 | if (mOnItemClickListener != null) { 92 | switch (v.getId()){ 93 | case R.id.mylist: 94 | mOnItemClickListener.onItemClick(v, ViewName.PRACTISE, position); 95 | break; 96 | default: 97 | mOnItemClickListener.onItemClick(v, ViewName.ITEM, position); 98 | break; 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/MusicGridAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.TextView; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.viewpagertext.R; 15 | import com.viewpagertext.activitys.PlayActivity; 16 | import com.viewpagertext.constructor.MessageEvent; 17 | import com.viewpagertext.constructor.SongsDatas; 18 | import com.viewpagertext.views.MyRoundedImageView; 19 | 20 | import org.greenrobot.eventbus.EventBus; 21 | 22 | import java.util.ArrayList; 23 | 24 | import static com.blankj.utilcode.util.ActivityUtils.startActivity; 25 | 26 | /** 27 | * name:小龙虾 28 | * time:2019.5.4 29 | * Type:发现页9宫格RecyclerView适配器 30 | */ 31 | 32 | public class MusicGridAdapter extends RecyclerView.Adapter{ 33 | private Context mContext; 34 | private ArrayList mDatas; 35 | public static String FindImgUrlPath; 36 | public static long FindSongsId; 37 | public MusicGridAdapter(Context context,ArrayList mDatas) { 38 | this.mContext=context; 39 | this.mDatas=mDatas; 40 | } 41 | 42 | @Override 43 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 44 | ViewHolder holder=new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.find_grid_music,viewGroup,false)); 45 | return holder; 46 | } 47 | 48 | @Override 49 | public void onBindViewHolder(final ViewHolder viewHolder, final int position) { 50 | viewHolder.grid_text.setText(mDatas.get(position).getTitle()); 51 | Glide.with(mContext).load(mDatas.get(position).getImageurl()).into(viewHolder.grid_image); 52 | viewHolder.find_songs_play_num.setText(mDatas.get(position).getPlayCount()); 53 | 54 | viewHolder.itemView.setOnClickListener(new View.OnClickListener() { 55 | @Override 56 | public void onClick(View v) { 57 | 58 | Intent intent=new Intent(mContext, PlayActivity.class); 59 | FindImgUrlPath=mDatas.get(position).getImageurl();//获取图片地址设置全局供ListFragment接收 60 | FindSongsId=mDatas.get(position).getId();//获取FindFragment歌单ID 61 | // Toast.makeText(mContext,"我的ID是:"+FindSongsId,Toast.LENGTH_SHORT).show(); 62 | //EventBus发送数据消息 63 | String ft=viewHolder.grid_text.getText().toString(); 64 | long l=mDatas.get(position).getId(); 65 | EventBus.getDefault().postSticky(new MessageEvent(ft));//发送 66 | mContext.startActivity(intent); 67 | } 68 | }); 69 | } 70 | 71 | //获取数据的数量 72 | @Override 73 | public int getItemCount() { 74 | return mDatas.size(); 75 | } 76 | 77 | 78 | //自定义的ViewHolder,持有每个Item的的所有界面元素 79 | public static class ViewHolder extends RecyclerView.ViewHolder { 80 | TextView grid_text,find_songs_play_num; 81 | MyRoundedImageView grid_image; 82 | public ViewHolder(View view){ 83 | super(view); 84 | grid_text = view.findViewById(R.id.grid_song_name);//子项的名称 85 | grid_image=view.findViewById(R.id.iv_Grid_Icon);//子项的图片 86 | find_songs_play_num=view.findViewById(R.id.find_songs_play_num);//歌单播放数量 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/PlayFragmentPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import androidx.fragment.app.Fragment; 4 | import androidx.fragment.app.FragmentManager; 5 | import androidx.fragment.app.FragmentPagerAdapter; 6 | import java.util.List; 7 | 8 | /** 9 | * name:小龙虾 10 | * time:20.19.5.25 11 | * type:获取本地音乐的适配器 12 | */ 13 | 14 | public class PlayFragmentPagerAdapter extends FragmentPagerAdapter { 15 | 16 | 17 | private List mData; 18 | public PlayFragmentPagerAdapter(FragmentManager fm,List mData) { 19 | super(fm); 20 | this.mData=mData; 21 | } 22 | 23 | @Override 24 | public Fragment getItem(int position) { 25 | return mData.get(position); 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | return mData.size(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/adapters/VideoAdapter.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.adapters; 2 | 3 | import android.content.Context; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | import com.bumptech.glide.Glide; 10 | import com.makeramen.roundedimageview.RoundedImageView; 11 | import com.viewpagertext.R; 12 | import com.viewpagertext.json.HotVideo; 13 | import java.util.ArrayList; 14 | import cn.jzvd.JZVideoPlayerStandard; 15 | 16 | /** 17 | * name:小龙虾 18 | * time:2019.5.28 19 | * type:获取本地音乐的适配器 20 | */ 21 | 22 | public class VideoAdapter extends RecyclerView.Adapter { 23 | 24 | private Context context; 25 | private ArrayList mList; 26 | 27 | public VideoAdapter(Context context, ArrayList list) { 28 | this.context = context; 29 | this.mList = list; 30 | } 31 | 32 | @Override 33 | public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 34 | MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.friend_video_item, viewGroup, false)); 35 | return holder; 36 | } 37 | 38 | @Override 39 | public void onBindViewHolder(final MyViewHolder myViewHolder, int i) { 40 | Glide.with(context).load(mList.get(i).getHeader()).into(myViewHolder.video_pic); 41 | myViewHolder.video_name.setText(mList.get(i).getName()); 42 | myViewHolder.video_text.setText(mList.get(i).getText()); 43 | myViewHolder.video_time.setText(mList.get(i).getPasstime()); 44 | myViewHolder.videoplayer.setUp(mList.get(i).getVideo(),JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL,mList.get(i).getName()); 45 | Glide.with(context).load(mList.get(i).getThumbnail()).into(myViewHolder.videoplayer.thumbImageView); 46 | 47 | 48 | } 49 | 50 | @Override 51 | public int getItemCount() { 52 | return mList.size(); 53 | } 54 | 55 | 56 | 57 | 58 | class MyViewHolder extends RecyclerView.ViewHolder { 59 | 60 | RoundedImageView video_pic; 61 | TextView video_name, video_text, video_time; 62 | JZVideoPlayerStandard videoplayer; 63 | 64 | public MyViewHolder(View itemView) { 65 | super(itemView); 66 | video_pic = itemView.findViewById(R.id.video_pic); 67 | video_name = itemView.findViewById(R.id.video_name); 68 | video_text = itemView.findViewById(R.id.video_text); 69 | videoplayer = itemView.findViewById(R.id.videoplayer); 70 | video_time = itemView.findViewById(R.id.video_time); 71 | } 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/app/ScrollShapeUIApplication.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.app; 2 | 3 | import android.app.Application; 4 | 5 | public class ScrollShapeUIApplication extends Application { 6 | 7 | private static ScrollShapeUIApplication cloudReaderApplication; 8 | 9 | 10 | public static ScrollShapeUIApplication getInstance() { 11 | return cloudReaderApplication; 12 | } 13 | 14 | 15 | 16 | public void onCreate() { 17 | super.onCreate(); 18 | cloudReaderApplication = this; 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/constructor/ListToPlayEvent.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.constructor; 2 | 3 | /** 4 | * name:小龙虾 5 | * time:2019.6.14 6 | * type:定义用来传输的数据的类型,用于歌单详情页传递数据网络到播放页 7 | * GitHub:https://github.com/greenrobot/EventBus 8 | */ 9 | 10 | public class ListToPlayEvent { 11 | private String Pic; 12 | private String Name; 13 | private String Singer; 14 | private String Lrc; 15 | private String url; 16 | private String time; 17 | 18 | public ListToPlayEvent(String Pic,String Name,String Singer,String Lrc,String url,String time){ 19 | this.Pic=Pic; 20 | this.Name=Name; 21 | this.Singer=Singer; 22 | this.Lrc=Lrc; 23 | this.url=url; 24 | this.time=time; 25 | } 26 | 27 | public String getPic() { 28 | return Pic; 29 | } 30 | 31 | public void setPic(String pic) { 32 | Pic = pic; 33 | } 34 | 35 | public String getName() { 36 | return Name; 37 | } 38 | 39 | public void setName(String name) { 40 | Name = name; 41 | } 42 | 43 | public String getSinger() { 44 | return Singer; 45 | } 46 | 47 | public void setSinger(String singer) { 48 | Singer = singer; 49 | } 50 | 51 | public String getLrc() { 52 | return Lrc; 53 | } 54 | 55 | public void setLrc(String lrc) { 56 | Lrc = lrc; 57 | } 58 | 59 | public String getUrl() { 60 | return url; 61 | } 62 | 63 | public void setUrl(String url) { 64 | this.url = url; 65 | } 66 | 67 | public String getTime() { 68 | return time; 69 | } 70 | 71 | public void setTime(String time) { 72 | this.time = time; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/constructor/MessageEvent.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.constructor; 2 | 3 | /** 4 | * name:小龙虾 5 | * time:2019.5.4 6 | * type:定义用来传输的数据的类型,用于发现页传递数据歌单详情页 7 | * GitHub:https://github.com/greenrobot/EventBus 8 | */ 9 | 10 | public class MessageEvent { 11 | public String findGridItemName; 12 | 13 | public MessageEvent(String findGridItemName) { 14 | this.findGridItemName = findGridItemName; 15 | } 16 | 17 | public String getFindGridItemName() { 18 | return findGridItemName; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/constructor/Song.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.constructor; 2 | 3 | public class Song { 4 | 5 | public String song;//歌曲名 6 | public String singer;//歌手 7 | public long size;//歌曲所占空间大小 8 | public int duration;//歌曲时间长度 9 | public String path;//歌曲地址 10 | public String album;//专辑 11 | public long albumId;//专辑海报 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/constructor/SongsDatas.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.constructor; 2 | 3 | public class SongsDatas { 4 | private String title;//歌单标题 5 | private String imageurl;//歌单图片地址 6 | private String playCount;//歌单播放数量 7 | private long id;//歌单id 8 | 9 | public String getTitle() { 10 | return title; 11 | } 12 | 13 | public void setTitle(String title) { 14 | this.title = title; 15 | } 16 | 17 | public String getImageurl() { 18 | return imageurl; 19 | } 20 | 21 | public void setImageurl(String imageurl) { 22 | this.imageurl = imageurl; 23 | } 24 | 25 | public String getPlayCount() { 26 | return playCount; 27 | } 28 | 29 | public void setPlayCount(String playCount) { 30 | this.playCount = playCount; 31 | } 32 | 33 | public long getId() { 34 | return id; 35 | } 36 | 37 | public void setId(long id) { 38 | this.id = id; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/fragments/FindFragment.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.fragments; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import androidx.fragment.app.Fragment; 7 | import androidx.recyclerview.widget.GridLayoutManager; 8 | import androidx.recyclerview.widget.RecyclerView; 9 | import android.util.Log; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.Toast; 14 | import com.viewpagertext.R; 15 | import com.viewpagertext.adapters.BannerViewHolder; 16 | import com.viewpagertext.adapters.MusicGridAdapter; 17 | import com.viewpagertext.constructor.SongsDatas; 18 | import com.viewpagertext.json.HotSongs; 19 | import com.viewpagertext.utils.HttpUtil; 20 | import com.viewpagertext.views.GridSpaceitemDecoration; 21 | import com.zhouwei.mzbanner.MZBannerView; 22 | import com.zhouwei.mzbanner.holder.MZHolderCreator; 23 | import org.json.JSONArray; 24 | import org.json.JSONObject; 25 | import java.io.IOException; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import okhttp3.Call; 29 | import okhttp3.Response; 30 | 31 | /** 32 | * name:小龙虾 33 | * time:2019.5.4 34 | * Type:发现页Fragment 35 | */ 36 | 37 | public class FindFragment extends Fragment { 38 | 39 | private MZBannerView mzBanner; 40 | private RecyclerView rv_Grid; 41 | private MusicGridAdapter musicGridAdapter; 42 | private ArrayList mDatas=new ArrayList<>(); 43 | private View view; 44 | private String findsongs="http://v1.itooi.cn/netease/songList/hot?&page=0&pageSize=6"; 45 | private int[] RES={R.mipmap.banner1,R.mipmap.banner2,R.mipmap.banner3,R.mipmap.banner4,R.mipmap.banner5,R.mipmap.banner6}; 46 | @Override 47 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 48 | view= inflater.inflate(R.layout.fragment_find,container,false); 49 | initBanner(view);//Banner 50 | 51 | initRvGird(view);//RecyclerViewGrid 52 | sendRequestWithOkHttp(); 53 | return view; 54 | } 55 | 56 | public void initBanner(View view) { 57 | 58 | List list=new ArrayList<>(); 59 | for (int i=0;i() { 65 | @Override 66 | public BannerViewHolder createViewHolder() { 67 | return new BannerViewHolder(); 68 | } 69 | }); 70 | } 71 | 72 | public void initRvGird(View view){ 73 | rv_Grid=view.findViewById(R.id.rv_Grid); 74 | rv_Grid.setLayoutManager(new GridLayoutManager(getActivity(),3)); 75 | rv_Grid.addItemDecoration(new GridSpaceitemDecoration(getResources().getDimensionPixelSize(R.dimen.dp_5),rv_Grid)); 76 | rv_Grid.setFocusable(false);//获取焦点 77 | musicGridAdapter=new MusicGridAdapter(getActivity(),mDatas); 78 | rv_Grid.setAdapter(musicGridAdapter); 79 | } 80 | 81 | 82 | public void sendRequestWithOkHttp(){ 83 | 84 | HttpUtil.sendOkHttpRequest(findsongs, new okhttp3.Callback() { 85 | @Override 86 | public void onFailure(Call call, IOException e) { 87 | // Toast.makeText(getActivity(),"IO发生异常",Toast.LENGTH_SHORT).show(); 88 | } 89 | 90 | @Override 91 | public void onResponse(Call call, Response response) throws IOException { 92 | String responseData=response.body().string();//得到服务器返回的具体内容 93 | // Log.d("MainActivity","测试结果"+responseData); 94 | parseJSONWithGSON(responseData); 95 | } 96 | }); 97 | } 98 | 99 | 100 | public HotSongs parseJSONWithGSON(String jsonData) { 101 | mDatas.clear(); 102 | try { 103 | JSONObject jsonObject1 = new JSONObject(jsonData); 104 | JSONArray jsonArray=jsonObject1.getJSONArray("data"); 105 | Log.d("MainActivity","Data共有多少条数据"+jsonArray.length()); 106 | for (int i=0;i list=new ArrayList<>(); 38 | private VideoAdapter videoAdapter; 39 | private String videoApi="https://api.apiopen.top/getJoke?page=1&count=50&type=video"; 40 | @Override 41 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 42 | binding = DataBindingUtil.inflate(inflater,R.layout.fragment_friend,container,false); 43 | initView(); 44 | return binding.getRoot(); 45 | } 46 | 47 | private void initView(){ 48 | binding.videoRec.setLayoutManager(new LinearLayoutManager(getActivity())); 49 | videoAdapter=new VideoAdapter(getActivity(),list); 50 | 51 | binding.videoRec.setAdapter(videoAdapter); 52 | } 53 | 54 | private void sendRequestOkHttp(){//访问接口 55 | HttpUtil.sendOkHttpRequest(videoApi, new okhttp3.Callback() { 56 | @Override 57 | public void onFailure(Call call, IOException e) { 58 | } 59 | 60 | @Override 61 | public void onResponse(Call call, Response response) throws IOException { 62 | String videoDatas=response.body().string(); 63 | parseJSONWithGSON(videoDatas); 64 | } 65 | }); 66 | } 67 | 68 | @Override 69 | public void onPause() { 70 | super.onPause(); 71 | JZVideoPlayer.releaseAllVideos(); 72 | } 73 | 74 | 75 | private HotVideo parseJSONWithGSON(String jsonData){ 76 | 77 | list.clear(); 78 | try { 79 | JSONObject jsonObject=new JSONObject(jsonData); 80 | JSONArray jsonArray=jsonObject.getJSONArray("result"); 81 | // Log.d("ListFragment","Data共有多少条数据"+jsonArray.length()); 82 | for (int i=0;i list; 32 | public static Song song; 33 | private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); 34 | 35 | public static List getmusic(Context context) { 36 | 37 | list = new ArrayList<>(); 38 | String remove=".mp3"; 39 | 40 | Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI 41 | , null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC); 42 | 43 | if (cursor != null) { 44 | 45 | while (cursor.moveToNext()) { 46 | 47 | song = new Song(); 48 | String removemp3 = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)).trim(); 49 | song.song=removemp3.replace(remove,""); 50 | song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)).trim(); 51 | song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)).trim(); 52 | song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); 53 | song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)); 54 | song.album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)); 55 | song.albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)); 56 | 57 | 58 | // 把歌曲名字和歌手切割开 59 | if (song.size > 1000 * 800) { 60 | if (song.song.contains("-")) { 61 | String[] str = song.song.split("-"); 62 | song.singer = str[0]; 63 | song.song = str[1]; 64 | } 65 | list.add(song); 66 | } 67 | 68 | } 69 | } 70 | 71 | cursor.close(); 72 | return list; 73 | 74 | } 75 | 76 | 77 | // 转换歌曲时间的格式 78 | public static String formatTime(int time) { 79 | if (time / 1000 % 60 < 10) { 80 | String tt = time / 1000 / 60 + ":0" + time / 1000 % 60; 81 | return tt; 82 | } else { 83 | String tt = time / 1000 / 60 + ":" + time / 1000 % 60; 84 | return tt; 85 | } 86 | } 87 | 88 | 89 | 90 | 91 | public static Bitmap getMusicBitemp(Context context, long songid, long albumid) { 92 | Bitmap bm = null; 93 | // 专辑id和歌曲id小于0说明没有专辑、歌曲,并抛出异常 94 | if (albumid < 0 && songid < 0) { 95 | throw new IllegalArgumentException( 96 | "Must specify an album or a song id"); 97 | } 98 | try { 99 | if (albumid < 0) { 100 | Uri uri = Uri.parse("content://media/external/audio/media/" 101 | + songid + "/albumart"); 102 | ParcelFileDescriptor pfd = context.getContentResolver() 103 | .openFileDescriptor(uri, "r"); 104 | if (pfd != null) { 105 | FileDescriptor fd = pfd.getFileDescriptor(); 106 | bm = BitmapFactory.decodeFileDescriptor(fd); 107 | } 108 | } else { 109 | Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid); 110 | ParcelFileDescriptor pfd = context.getContentResolver() 111 | .openFileDescriptor(uri, "r"); 112 | if (pfd != null) { 113 | FileDescriptor fd = pfd.getFileDescriptor(); 114 | bm = BitmapFactory.decodeFileDescriptor(fd); 115 | 116 | 117 | } else { 118 | return null; 119 | } 120 | } 121 | } catch (FileNotFoundException ex) { 122 | } 123 | //如果获取的bitmap为空,则返回一个默认的bitmap 124 | if (bm == null) { 125 | Resources resources = context.getResources(); 126 | Drawable drawable = resources.getDrawable(R.mipmap.play_head); 127 | //Drawable 转 Bitmap 128 | BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; 129 | bm = bitmapDrawable.getBitmap(); 130 | } 131 | 132 | return Bitmap.createScaledBitmap(bm, 150, 150, true); 133 | } 134 | 135 | } -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/utils/PermissionUtils.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.utils; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.pm.PackageManager; 8 | import android.net.Uri; 9 | import android.os.Build; 10 | import androidx.core.app.ActivityCompat; 11 | import androidx.core.content.ContextCompat; 12 | 13 | /** 14 | * 权限工具类 15 | */ 16 | public class PermissionUtils { 17 | 18 | //检查权限 19 | public static void initCheckSelfPermission(Activity context){ 20 | 21 | if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){ 22 | ActivityCompat.requestPermissions(context,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1); 23 | } 24 | } 25 | 26 | /** 27 | * 跳转到应用权限设置界面 28 | * @param context 29 | */ 30 | public static void getAppDetailSettingIntent(Context context) { 31 | Intent localIntent = new Intent(); 32 | localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 33 | if (Build.VERSION.SDK_INT >= 9) { 34 | localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); 35 | localIntent.setData(Uri.fromParts("package", context.getPackageName(), null)); 36 | } else if (Build.VERSION.SDK_INT <= 8) { 37 | localIntent.setAction(Intent.ACTION_VIEW); 38 | localIntent.setClassName("com.android.settings","com.android.settings.InstalledAppDetails"); 39 | localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName()); 40 | } 41 | context.startActivity(localIntent); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/utils/StatusBarView.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.utils; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | 7 | /** 8 | * 9 | * Email: chjie.jaeger@gmail.com 10 | * GitHub: https://github.com/laobie 11 | */ 12 | public class StatusBarView extends View { 13 | public StatusBarView(Context context, AttributeSet attrs) { 14 | super(context, attrs); 15 | } 16 | 17 | public StatusBarView(Context context) { 18 | super(context); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/utils/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.utils; 2 | 3 | import java.util.Locale; 4 | 5 | public class TimeUtil { 6 | public static String formatSeconds(long seconds){ 7 | String standardTime; 8 | if (seconds <= 0){ 9 | standardTime = "00:00"; 10 | } else if (seconds < 60) { 11 | standardTime = String.format(Locale.getDefault(), "00:%02d", seconds % 60); 12 | } else if (seconds < 3600) { 13 | standardTime = String.format(Locale.getDefault(), "%02d:%02d", seconds / 60, seconds % 60); 14 | } else { 15 | standardTime = String.format(Locale.getDefault(), "%02d:%02d:%02d", seconds / 3600, seconds % 3600 / 60, seconds % 60); 16 | } 17 | return standardTime; 18 | } 19 | 20 | 21 | //时间显示函数,我们获得音乐信息的是以毫秒为单位的,把把转换成我们熟悉的00:00格式 22 | public static String ShowTime(int time) { 23 | time /= 1000; 24 | int minute = time / 60; 25 | int hour = minute / 60; 26 | int second = time % 60; 27 | minute %= 60; 28 | return String.format("%02d:%02d", minute, second); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/utils/TypefacesUtil.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.utils; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.util.Log; 6 | 7 | import java.util.Hashtable; 8 | 9 | /** 10 | * name: 小龙虾 11 | * time: 2019/04/19 12 | * Type: 字体转换的工具 13 | */ 14 | 15 | 16 | public class TypefacesUtil { 17 | private static final String TAG = "Typefaces"; 18 | private static final Hashtable cache = new Hashtable(); 19 | 20 | public static Typeface get(Context c, String assetPath) { 21 | synchronized (cache) { 22 | if (!cache.containsKey(assetPath)) { 23 | try { 24 | Typeface t = Typeface.createFromAsset(c.getAssets(), assetPath); 25 | cache.put(assetPath, t); 26 | } catch (Exception e) { 27 | Log.e(TAG, "Could not get typeface '" + assetPath + "' because " + e.getMessage()); 28 | return null; 29 | } 30 | } 31 | return cache.get(assetPath); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/utils/UserUtils.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.utils; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.util.TypedValue; 6 | import android.widget.TextView; 7 | 8 | 9 | 10 | /** 11 | * name: 小龙虾 12 | * time: 2019/04/19 13 | * Type: 字体通用属性 14 | */ 15 | 16 | public class UserUtils { 17 | 18 | 19 | /** 20 | * //设置字体大小 21 | * @param tv 22 | * @param size 23 | */ 24 | public static void setTextSize(TextView tv,int size){ 25 | tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,size); 26 | } 27 | 28 | /** 29 | * 设置字体颜色 30 | * @param tv 31 | * @param context 32 | * @param color 33 | */ 34 | public static void setTextColor(TextView tv, Context context,int color){ 35 | tv.setTextColor(context.getResources().getColor(color)); 36 | } 37 | 38 | /** 39 | * 字体是否加粗 40 | */ 41 | public static void setTypeface(TextView tv,int BOLD){ 42 | tv.setTypeface(Typeface.defaultFromStyle(BOLD)); 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/GridSpaceitemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | 3 | import android.graphics.Rect; 4 | import androidx.annotation.NonNull; 5 | import androidx.recyclerview.widget.RecyclerView; 6 | import android.view.View; 7 | import android.widget.LinearLayout; 8 | 9 | 10 | /** 11 | * name:小龙虾 12 | * time:2019.5.4 13 | * Type:自定义分割线 14 | */ 15 | 16 | public class GridSpaceitemDecoration extends RecyclerView.ItemDecoration { 17 | 18 | private int mSpace; 19 | 20 | public GridSpaceitemDecoration(int space,RecyclerView parent){ 21 | mSpace=space; 22 | getRecyclerViewOffsets(parent); 23 | } 24 | 25 | /** 26 | * 27 | * @param outRect Item的矩形边界 28 | * @param view ItemView 29 | * @param parent RecyclerView 30 | * @param state RecyclerView的状态 31 | */ 32 | @Override 33 | public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { 34 | super.getItemOffsets(outRect, view, parent, state); 35 | 36 | outRect.left=mSpace; 37 | //判断Item是不是每一行第一个Item 38 | // if (parent.getChildLayoutPosition(view)%3==0){ 39 | // outRect.left=0; 40 | // } 41 | 42 | } 43 | 44 | private void getRecyclerViewOffsets(RecyclerView parent){ 45 | //View margin 46 | //margin为正,则View回距离边界产生一个距离 47 | //margin为负,则View会超出边界产生一个距离 48 | LinearLayout.LayoutParams layoutParams=(LinearLayout.LayoutParams) parent.getLayoutParams(); 49 | layoutParams.leftMargin=-mSpace; 50 | parent.setLayoutParams(layoutParams); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/Lead.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | import android.animation.Animator; 3 | import android.animation.AnimatorSet; 4 | import android.animation.ObjectAnimator; 5 | import android.animation.ValueAnimator; 6 | import android.os.Build; 7 | import android.view.animation.LinearInterpolator; 8 | 9 | /** 10 | * name: 小龙虾 11 | * time: 2019/04/19 12 | * Type: 动画实现的效果 13 | */ 14 | 15 | public class Lead { 16 | private AnimatorSet animatorSet; 17 | private Animator.AnimatorListener animatorListener; 18 | private int mDuration; 19 | 20 | public Lead(int duration) { 21 | mDuration = duration; 22 | } 23 | 24 | 25 | public void start(final LeadTextView textView) { 26 | 27 | final Runnable animate = new Runnable() { 28 | @Override 29 | public void run() { 30 | 31 | textView.setSinking(true); 32 | 33 | // horizontal animation. 200 = wave.png width 34 | ObjectAnimator maskXAnimator = ObjectAnimator.ofFloat(textView, "maskX", 0, 200); 35 | maskXAnimator.setRepeatCount(ValueAnimator.INFINITE); 36 | maskXAnimator.setDuration(1000); 37 | maskXAnimator.setStartDelay(0); 38 | 39 | int h = textView.getHeight(); 40 | 41 | // vertical animation 42 | // maskY = 0 -> wave vertically centered 43 | // repeat mode REVERSE to go back and forth 44 | ObjectAnimator maskYAnimator = ObjectAnimator.ofFloat(textView, "maskY", h / 2, -h / 2); 45 | maskYAnimator.setRepeatCount(ValueAnimator.INFINITE); 46 | maskYAnimator.setRepeatMode(ValueAnimator.REVERSE); 47 | maskYAnimator.setDuration(2850); 48 | maskYAnimator.setStartDelay(0); 49 | 50 | // now play both animations together 51 | animatorSet = new AnimatorSet(); 52 | animatorSet.playTogether(maskXAnimator, maskYAnimator); 53 | animatorSet.setInterpolator(new LinearInterpolator()); 54 | animatorSet.addListener(new Animator.AnimatorListener() { 55 | @Override 56 | public void onAnimationStart(Animator animation) { 57 | } 58 | 59 | @Override 60 | public void onAnimationEnd(Animator animation) { 61 | textView.setSinking(false); 62 | 63 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 64 | textView.postInvalidate(); 65 | } else { 66 | textView.postInvalidateOnAnimation(); 67 | } 68 | 69 | animatorSet = null; 70 | } 71 | 72 | @Override 73 | public void onAnimationCancel(Animator animation) { 74 | 75 | } 76 | 77 | @Override 78 | public void onAnimationRepeat(Animator animation) { 79 | 80 | } 81 | }); 82 | 83 | 84 | if (animatorListener != null) { 85 | animatorSet.addListener(animatorListener); 86 | } 87 | 88 | animatorSet.start(); 89 | } 90 | }; 91 | 92 | if (!textView.isSetUp()) { 93 | textView.setAnimationSetupCallback(new LeadTextView.AnimationSetupCallback() { 94 | @Override 95 | public void onSetupAnimation(final LeadTextView target) { 96 | animate.run(); 97 | } 98 | }); 99 | } else { 100 | animate.run(); 101 | } 102 | } 103 | 104 | public void cancel() { 105 | if (animatorSet != null) { 106 | animatorSet.cancel(); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/LeadTextView.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | 3 | import android.content.Context; 4 | import android.content.res.ColorStateList; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapShader; 7 | import android.graphics.Canvas; 8 | import android.graphics.Matrix; 9 | import android.graphics.Shader; 10 | import android.graphics.drawable.Drawable; 11 | import androidx.appcompat.widget.AppCompatTextView; 12 | import android.util.AttributeSet; 13 | 14 | import com.viewpagertext.R; 15 | 16 | /** 17 | * name : 小龙虾 18 | * time : 2019/04/19 19 | * type : 自定义TextView,可实现水波纹升浪 20 | */ 21 | 22 | 23 | public class LeadTextView extends AppCompatTextView { 24 | 25 | public interface AnimationSetupCallback { 26 | void onSetupAnimation(LeadTextView titanicTextView); 27 | } 28 | 29 | // callback fired at first onSizeChanged 30 | private AnimationSetupCallback animationSetupCallback; 31 | // wave shader coordinates 32 | private float maskX, maskY; 33 | // if true, the shader will display the wave 34 | private boolean sinking; 35 | // true after the first onSizeChanged 36 | private boolean setUp; 37 | 38 | // shader containing a repeated wave 39 | private BitmapShader shader; 40 | // shader matrix 41 | private Matrix shaderMatrix; 42 | // wave drawable 43 | private Drawable wave; 44 | // (getHeight() - waveHeight) / 2 45 | private float offsetY; 46 | 47 | public LeadTextView(Context context) { 48 | super(context); 49 | init(); 50 | } 51 | 52 | public LeadTextView(Context context, AttributeSet attrs) { 53 | super(context, attrs); 54 | init(); 55 | } 56 | 57 | public LeadTextView(Context context, AttributeSet attrs, int defStyle) { 58 | super(context, attrs, defStyle); 59 | init(); 60 | } 61 | 62 | private void init() { 63 | shaderMatrix = new Matrix(); 64 | } 65 | 66 | public AnimationSetupCallback getAnimationSetupCallback() { 67 | return animationSetupCallback; 68 | } 69 | 70 | public void setAnimationSetupCallback(AnimationSetupCallback animationSetupCallback) { 71 | this.animationSetupCallback = animationSetupCallback; 72 | } 73 | 74 | public float getMaskX() { 75 | return maskX; 76 | } 77 | 78 | public void setMaskX(float maskX) { 79 | this.maskX = maskX; 80 | invalidate(); 81 | } 82 | 83 | public float getMaskY() { 84 | return maskY; 85 | } 86 | 87 | public void setMaskY(float maskY) { 88 | this.maskY = maskY; 89 | invalidate(); 90 | } 91 | 92 | public boolean isSinking() { 93 | return sinking; 94 | } 95 | 96 | public void setSinking(boolean sinking) { 97 | this.sinking = sinking; 98 | } 99 | 100 | public boolean isSetUp() { 101 | return setUp; 102 | } 103 | 104 | @Override 105 | public void setTextColor(int color) { 106 | super.setTextColor(color); 107 | createShader(); 108 | } 109 | 110 | @Override 111 | public void setTextColor(ColorStateList colors) { 112 | super.setTextColor(colors); 113 | createShader(); 114 | } 115 | 116 | @Override 117 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 118 | super.onSizeChanged(w, h, oldw, oldh); 119 | 120 | createShader(); 121 | 122 | if (!setUp) { 123 | setUp = true; 124 | if (animationSetupCallback != null) { 125 | animationSetupCallback.onSetupAnimation(LeadTextView.this); 126 | } 127 | } 128 | } 129 | 130 | /** 131 | * Create the shader 132 | * draw the wave with current color for a background 133 | * repeat the bitmap horizontally, and clamp colors vertically 134 | */ 135 | private void createShader() { 136 | 137 | if (wave == null) { 138 | wave = getResources().getDrawable(R.mipmap.wave); 139 | } 140 | 141 | int waveW = wave.getIntrinsicWidth(); 142 | int waveH = wave.getIntrinsicHeight(); 143 | 144 | Bitmap b = Bitmap.createBitmap(waveW, waveH, Bitmap.Config.ARGB_8888); 145 | Canvas c = new Canvas(b); 146 | 147 | c.drawColor(getCurrentTextColor()); 148 | 149 | wave.setBounds(0, 0, waveW, waveH); 150 | wave.draw(c); 151 | 152 | shader = new BitmapShader(b, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); 153 | getPaint().setShader(shader); 154 | 155 | offsetY = (getHeight() - waveH) / 2; 156 | } 157 | 158 | @Override 159 | protected void onDraw(Canvas canvas) { 160 | 161 | // modify text paint shader according to sinking state 162 | if (sinking && shader != null) { 163 | 164 | // first call after sinking, assign it to our paint 165 | if (getPaint().getShader() == null) { 166 | getPaint().setShader(shader); 167 | } 168 | 169 | // translate shader accordingly to maskX maskY positions 170 | // maskY is affected by the offset to vertically center the wave 171 | shaderMatrix.setTranslate(maskX, maskY + offsetY); 172 | 173 | // assign matrix to invalidate the shader 174 | shader.setLocalMatrix(shaderMatrix); 175 | } else { 176 | getPaint().setShader(null); 177 | } 178 | 179 | super.onDraw(canvas); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/MarqueeTextView.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | 3 | import android.content.Context; 4 | import androidx.appcompat.widget.AppCompatTextView; 5 | import android.util.AttributeSet; 6 | 7 | /** 8 | * name:小龙虾 9 | * time:2019/6/9 10 | * type:文字走马灯 11 | */ 12 | public class MarqueeTextView extends AppCompatTextView { 13 | public MarqueeTextView(Context context) { 14 | super(context); 15 | } 16 | 17 | public MarqueeTextView(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | @Override 26 | public boolean isFocused() {//必须重写,且返回值是true,表示始终获取焦点 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/MyNestedScrollView.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | 3 | import android.content.Context; 4 | import androidx.core.widget.NestedScrollView; 5 | import android.util.AttributeSet; 6 | 7 | /** 8 | * Created by jingbin on 2016/12/6. 9 | * 系统的滚动监听只能api23以上用,这为了兼容 10 | */ 11 | 12 | public class MyNestedScrollView extends NestedScrollView { 13 | 14 | private ScrollInterface scrollInterface; 15 | 16 | /** 17 | * 定义滑动接口 18 | */ 19 | public interface ScrollInterface { 20 | void onScrollChange(int scrollX, int scrollY, int oldScrollX, int oldScrollY); 21 | } 22 | 23 | public MyNestedScrollView(Context context) { 24 | super(context); 25 | } 26 | 27 | public MyNestedScrollView(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | 31 | public MyNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 32 | super(context, attrs, defStyleAttr); 33 | } 34 | 35 | @Override 36 | protected void onScrollChanged(int l, int t, int oldl, int oldt) { 37 | if (scrollInterface != null) { 38 | scrollInterface.onScrollChange(l, t, oldl, oldt); 39 | } 40 | super.onScrollChanged(l, t, oldl, oldt); 41 | } 42 | 43 | public void setOnMyScrollChangeListener(ScrollInterface t) { 44 | this.scrollInterface = t; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/MyRoundedImageView.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | 3 | 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | import com.makeramen.roundedimageview.RoundedImageView; 7 | 8 | /** 9 | * name : 小龙虾 10 | * time : 2019/04/19 11 | * type :自定义ImageView的宽高,使其高=宽 12 | */ 13 | public class MyRoundedImageView extends RoundedImageView { 14 | 15 | 16 | public MyRoundedImageView(Context context) { 17 | super(context); 18 | } 19 | 20 | public MyRoundedImageView(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | } 23 | 24 | public MyRoundedImageView(Context context, AttributeSet attrs, int defStyle) { 25 | super(context, attrs, defStyle); 26 | } 27 | 28 | @Override 29 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 30 | super.onMeasure(widthMeasureSpec, widthMeasureSpec); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/viewpagertext/views/MyYViewpager.java: -------------------------------------------------------------------------------- 1 | package com.viewpagertext.views; 2 | 3 | import android.content.Context; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | import android.util.AttributeSet; 8 | import android.view.MotionEvent; 9 | import com.viewpagertext.R; 10 | import cn.youngkaaa.yviewpager.YViewPager; 11 | 12 | /** 13 | * name:小龙虾 14 | * time:2019.5.7 15 | * type:解决详情页切换到播放页 16 | * viewpager与recyclerview滑动冲突问题 17 | */ 18 | 19 | public class MyYViewpager extends YViewPager { 20 | 21 | private int mFirstX =0,mFirstY=0; 22 | 23 | public MyYViewpager(@NonNull Context context) { 24 | super(context); 25 | } 26 | 27 | public MyYViewpager(@NonNull Context context, @Nullable AttributeSet attrs) { 28 | super(context, attrs); 29 | } 30 | 31 | @Override 32 | public boolean onInterceptTouchEvent(MotionEvent ev) { 33 | 34 | boolean isIntercept=false; 35 | int x=(int) ev.getX(); 36 | int y=(int) ev.getY(); 37 | RecyclerView recyclerView=findViewById(R.id.xrv_list); 38 | switch (ev.getAction()){ 39 | /** 40 | * 父容器必须返回false,即不拦截ACTION_DOWN事件, 41 | * 否则后续的ACTION_MOVE,ACTION_UP事件都会直接交给父容器处理, 42 | * 事件没办法再传递给子元素了 43 | */ 44 | case MotionEvent.ACTION_DOWN://按下 45 | // isIntercept=false; 46 | // break; 47 | case MotionEvent.ACTION_MOVE://移动过程中 48 | // if (recyclerView.canScrollVertically(-1)==true){ 49 | // isIntercept=false;//不拦截 50 | // } 51 | break; 52 | case MotionEvent.ACTION_UP://放开 53 | // if (recyclerView.canScrollVertically(-1)==false){ 54 | // return super.onInterceptTouchEvent(ev); 55 | // } 56 | // isIntercept=false; 57 | break; 58 | default: 59 | break; 60 | } 61 | mFirstX=x; 62 | mFirstY=y; 63 | return isIntercept; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_animo_alph_close.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_animo_alph_open.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/in_from_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/main_bottom_pic_rotate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/out_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/rotate_player_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_login_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_login_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_h.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_n.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_nav_close_n.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_nav_close_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layer_player_playing_progress.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/my_icon_h.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/my_icon_n.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/my_icon_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_player_playing_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/stroke_radius.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |