自学java和android三个月了,完全是看网上的****以及文章,说实话,网络大神们太神,有的代码高深莫测,有的“大神”写的代码小弟我有的根本看不通逻辑,哎,苦逼,谁让我是学俄语的,还是自学java和android,没人教啊,也没有做软件的朋友。。。自己写了几个小软件,一个悬浮球自己一直在用,挺简单的,没啥好说的,不扯了,进入正题:先看看目录架构。
类比较多,主Activity 用到了AppBarLayout+ViewPager,viewPager里三个fragment采用RecyclerView,可以伸缩ToolBar,喜爱列表写进了SQL,支持添加删除和清空,清空功能在右上的menu里,是单开了一个Thread,artist列表用了图片缓存,要不然加载起来卡的要死。搜索歌曲单做了一个空白activity,cardview里放一个editview,高度随键盘变化,也是用到了AppBarLayout。editview注册了addTextChangedListener。 本地列表添加了右侧快速导航栏,哎,这个逻辑是完全自己写的代码,别人是实现SectionIndexer接口,但是我真是看不懂网上大神们写的关于此接口的介绍和使用,没办法,又想实现这个功能,就只能自己写喽。逻辑很简单。写在了DataUtil里当工具用了。
歌词用的是一个大神写的代码,代码不多,但是好用~~
public static Boolean displayAA(List<Music> list,int position) { StringBuilder sb = new StringBuilder(26); for (int i = 0; i < list.size(); i++) { String name = list.get(i).getName(); String pinyin = Pinyin.toPinyin(name.charAt(0)); String pp = pinyin.substring(0, 1); sb.append(pp); } int A = sb.indexOf("A");int B = sb.indexOf("B"); int C = sb.indexOf("C");int D = sb.indexOf("D"); int E = sb.indexOf("E"); int F = sb.indexOf("F");int G = sb.indexOf("G");int H = sb.indexOf("H"); int I = sb.indexOf("I");int J = sb.indexOf("J"); int K = sb.indexOf("K");int L = sb.indexOf("L");int M = sb.indexOf("M"); int N = sb.indexOf("N");int O = sb.indexOf("O"); int P = sb.indexOf("P");int Q = sb.indexOf("Q");int R = sb.indexOf("R"); int S = sb.indexOf("S");int T = sb.indexOf("T"); int U = sb.indexOf("U");int V = sb.indexOf("V");int W = sb.indexOf("W"); int X = sb.indexOf("X");int Y = sb.indexOf("Y"); int Z = sb.indexOf("Z"); if (position ==A ||position ==B ||position ==C ||position ==D ||position ==E ||position ==F ||position ==G ||position ==H ||position ==I ||position ==J ||position ==K ||position ==L ||position ==M ||position ==N ||position ==O ||position ==P ||position ==Q || position ==R ||position ==S ||position ==T ||position ==U ||position ==V ||position ==W ||position ==X ||position ==Y || position ==Z ){ return true; }else{ return false; } } 上面的是决定哪个position对应的item显示A-Z这些字母。 下面的是触摸时让recyclerView找到应该滚动到的position。 public static int[] abc_index(List<Music> list){ StringBuilder sb = new StringBuilder(26); for (int i = 0; i< list.size(); i++){ String name = list.get(i).getName(); String pinyin = Pinyin.toPinyin(name.charAt(0)); String pp = pinyin.substring(0,1); sb.append(pp); } int A = sb.indexOf("A");int B = sb.indexOf("B"); int C = sb.indexOf("C");int D = sb.indexOf("D"); int E = sb.indexOf("E"); int F = sb.indexOf("F");int G = sb.indexOf("G");int H = sb.indexOf("H"); int I = sb.indexOf("I");int J = sb.indexOf("J"); int K = sb.indexOf("K");int L = sb.indexOf("L");int M = sb.indexOf("M"); int N = sb.indexOf("N");int O = sb.indexOf("O"); int P = sb.indexOf("P");int Q = sb.indexOf("Q");int R = sb.indexOf("R"); int S = sb.indexOf("S");int T = sb.indexOf("T"); int U = sb.indexOf("U");int V = sb.indexOf("V");int W = sb.indexOf("W"); int X = sb.indexOf("X");int Y = sb.indexOf("Y"); int Z = sb.indexOf("Z"); int[] abc_z = {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z}; return abc_z; }
A-Z的导航我做成悬浮窗了,在主activity里new出来的,viewpager翻页时sortView实现GONE。本来也写了一个在静态放在fragment里,但是因为ToolBar上下滑动,它也跟着动,烦,就写成悬浮了,测试了几个悬浮级别TYPE,实测LAST_APPLICATION_WINDOW 和 TYPE_APPLICATION_STARTING 最适用,既做到应用内的悬浮和可触摸,而且不会挡住我的悬浮球:)看完图片上代码吧,一句两句说不完,ca~~~
类太多了,布局就不上了,要不然这么多代码要死人的。。。
package xiamusic.com.yinyuejie.activity; import android.annotation.SuppressLint; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.graphics.Palette; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import java.util.ArrayList; import java.util.List; import xiamusic.com.yinyuejie.view.Audio_View; import xiamusic.com.yinyuejie.music.Music; import xiamusic.com.yinyuejie.service.MyService; import xiamusic.com.yinyuejie.util.Play_final; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.adapter.RvAdapter_artist_musicTab; import static xiamusic.com.yinyuejie.fragment.FragmentArtist.sp; import static xiamusic.com.yinyuejie.service.MyService.FLAGS; import static xiamusic.com.yinyuejie.service.MyService.mp; import static xiamusic.com.yinyuejie.service.MyService.play_id; import static xiamusic.com.yinyuejie.service.MyService.play_ing_music; public class Activity_artist_music extends AppCompatActivity { List<Music> musicList = new ArrayList<>(); List<Music> tempScanList; GridLayoutManager gg; RecyclerView recycler_artistActivity; RvAdapter_artist_musicTab adapter; ImageView imageView; String artist; Audio_View audio_view; LinearLayout linearLayout; @SuppressLint("CommitPrefEdits") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_artist_music); getSupportActionBar().hide(); initView(); setListener(); } public void initView(){ linearLayout = findViewById(R.id.line_artist_Back_Activity); imageView = findViewById(R.id.image_artist_music); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); recycler_artistActivity = findViewById(R.id.recycler_artistActivity); adapter = new RvAdapter_artist_musicTab(this); gg = new GridLayoutManager(this,1); audio_view = findViewById(R.id.audio_View); artist = sp.getString("ar","蔡淳佳"); new initListTask().execute(artist); } public void setListener(){ adapter.setOnItemClickListener(new RvAdapter_artist_musicTab.OnItemClickListener() { @Override public void onItemClick(View view, int position) { play_ing_music = musicList; play_id = position; FLAGS = Play_final.ONE_MUSIC; String url = play_ing_music.get(position).getUrl(); Uri uri = Uri.parse(url); Intent im = new Intent(Activity_artist_music.this, MyService.class); im.setAction("action"); im.putExtra("cmd", Play_final.PLAY); im.setData(uri); startService(im); Intent intent = new Intent("upTime"); sendBroadcast(intent); handler.post(runnable_audio); } }); } @Override protected void onResume() { super.onResume(); new ScanAsyncTask().execute(artist); if (mp.isPlaying()){ handler.post(runnable_audio); } } @SuppressLint("StaticFieldLeak") class ScanAsyncTask extends AsyncTask<String,Integer,Bitmap>{ @Override protected Bitmap doInBackground(String... strings) { tempScanList = MusicActivity.dataUtil.scan(Activity_artist_music.this); play_ing_music = tempScanList; Bitmap bitmap = MusicActivity.mMemoryCache.get(strings[0]); return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { if (bitmap == null){ imageView.setImageResource(R.drawable.yinyue); }else { imageView.setImageBitmap(bitmap); paletteRgb(bitmap); } super.onPostExecute(bitmap); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } } @SuppressLint("StaticFieldLeak") class initListTask extends AsyncTask<String,Integer,List<Music>>{ @Override protected List<Music> doInBackground(String... voids) { String artist = voids[0]; tempScanList = MusicActivity.dataUtil.scan(Activity_artist_music.this); List<Music> m = new ArrayList<>(); if ( artist != null){ for (Music music : tempScanList){ if (music.getName().contains(artist)||music.getArtist().equals(artist)){ m.add(music); } } } return m; } @Override protected void onPostExecute(List<Music> music) { musicList = music; adapter.notifyDataSetChanged(); adapter.setDataList(musicList); recycler_artistActivity.setLayoutManager(gg); recycler_artistActivity.setAdapter(adapter); super.onPostExecute(music); } } private Handler handler = new Handler(); private Runnable runnable_audio = new Runnable() { @Override public void run() { if (mp.isPlaying()){ audio_view.invalidate(); handler.postDelayed(this,200); } } }; public void paletteRgb(Bitmap bitmap){ Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() { @Override public void onGenerated(Palette palette) { Palette.Swatch muted = palette.getLightMutedSwatch(); if (muted != null){ linearLayout.setBackgroundColor(muted.getRgb()); } } }); } }
下面这个可以不看,写了个网络加载图片玩的AsyncTask;
package xiamusic.com.yinyuejie.activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.adapter.RvAdapter_actInt_Ima; public class Activity_int_ima extends AppCompatActivity implements View.OnClickListener { RvAdapter_actInt_Ima adapter; List<String> pathList = new ArrayList<>(); List<Bitmap> bitmapList = new ArrayList<>(); GridLayoutManager layoutManager; RecyclerView recyclerView; Button btup,budown; int a = 0; static final int pager = 8; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_int_ima); getSupportActionBar().hide(); layoutManager = new GridLayoutManager(this,2); adapter = new RvAdapter_actInt_Ima(this); recyclerView = findViewById(R.id.xRecycler_actINTima); btup = findViewById(R.id.pagerUP); budown = findViewById(R.id.pagerDown); btup.setOnClickListener(this); budown.setOnClickListener(this); initBitPath(); setListener(); } public void initBitPath(){ pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207404104&di=0f28363596ec443d22e019ada5f2dc1b&imgtype=jpg&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D1524594730%2C3632212272%26fm%3D214%26gp%3D0.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207061729&di=2f7a29c55e83ff49909d183141fca7d7&imgtype=0&src=http%3A%2F%2Fpic14.photophoto.cn%2F20100225%2F0036036896563815_b.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196934&di=5299b444caa17d0933fd371fa96ade2c&src=http://pic23.nipic.com/20120908/6809035_154005567000_2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521197403&di=e50b1348bd4083695e85757d918b86ea&src=http://ww1.sinaimg.cn/large/005EpPx2gw1ewc7o0i69ej30jg0smdj1.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207581427&di=014759fb2b97c5b267d1e2fca6347fba&imgtype=0&src=http%3A%2F%2Fimg.qq745.com%2Fuploads%2Fallimg%2F160910%2F11-160910095R2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521206922810&di=f0b0d170e4be9ec68d2ebf670c422158&imgtype=0&src=http%3A%2F%2Fww1.sinaimg.cn%2Flarge%2Fad85bdb8gw1eq2awf46gij20p00vvncg.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521206825945&di=e66c5abbbd10335cbaa08577cb261744&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201510%2F26%2F20151026083328_USdis.jpeg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521206762550&di=8dfe1504c52a7e240f1bfae09a0df131&imgtype=0&src=http%3A%2F%2Fwx2.sinaimg.cn%2Fmw690%2F006yCHQygy1fji19zzsljj30m80etdgu.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196583&di=37bb07c5a7ea3f9fe1a7f191db6332c1&src=http://img.newyx.net/newspic/image/201511/18/ff9ae55616.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521206608951&di=f80664c5f347a322a8f831b9693cea7b&imgtype=" + "0&src=http%3A%2F%2Fww1.sinaimg.cn%2Forj480%2F006wDFlegw1f7oj87wizej30jg0t60u7.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521206581742&di=509754fc2fefd95219f9d446a23594dd&imgtype=0&src=http%3A%2F%2F" + "www.guangyuanol.cn%2Fuploads%2Fallimg%2Fc160723%2F14E25a3212350-1W0Z.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196071&di=d4b1ca6e580f3c3ef14602cdd38d921d&src=http://pic7.nipic.com/20100512/3017209_112310353598_2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196180&di=95f20390b54621da3bce07ecf581ac68&src=http://pic17.photophoto.cn/20101222/0036036896355909_b.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196197&di=34283709d4f94e761bf971801053e3c7&src=http://pic9.nipic.com/20100908/1304280_110546082533_2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196222&di=4636ebec4d5d6c4a9b2e85c54b18be00&src=http:" + "//img3.redocn.com/20130926/Redocn_2013092313102846.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207923641&di=b69e69523c9c4714f23f09471c8ad188&imgtype=0&src=http%3A%2F%2Fs3.sinaimg.cn%2Fmw690%2F002YJJOnzy74BE7vyCu92%26690"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207864136&di=303ef6ece01a842180b2da24a185712e&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2Fcc11728b4710b9122f6515c4c8fdfc0392452260.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521197632&di=86f2da82b4a80e6c9c3428fd78693d24&src=http://img10.cn.gcimg.net/gcproduct/day_20141123/de4dc53717ff76675ab9aa21b7c4f090.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207673571&di=c51272ecc84b80e96c4b6e23617c4ad9&imgtype=0&src=http%3A%2F%2Fimage9.huangye88.com%2F2015%2F04%2F16%2F07ca31375a0236fd.png"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521197647&di=42e173e5b5b3abacb7cd0fed485f6c9b&src=http://img.c-c.com/Timg/2015/03/13/11/lianyunchen1115310532.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521197647&di=ee4973cd25ad428e3e76724233e59497&src=http://img10.cn.gcimg.net/gcproduct/day_20141124/73d51f622cee738c97af5b76984a65f4.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521197681&di=8ce78c8457d24ff4e0642fa2222b395d&src=http://img10.cn.gcimg.net/gcproduct/day_20141124/73d51f622cee738c97af5b76984a65f4.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521207581427&di=014759fb2b97c5b267d1e2fca6347fba&imgtype=0&src=http%3A%2F%2Fimg.qq745.com%2Fuploads%2Fallimg%2F160910%2F11-160910095R2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521196375&di=b8567b9c292a28ab91a35dfc5ae2a23a&src=" + "http://pic7.nipic.com/20100524/3017209_125803878322_2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521206517027&di=d0ddd31902e5180b48a6dc93f3e7b1be&imgtype=" + "0&src=http%3A%2F%2Fwx4.sinaimg.cn%2Fmw690%2F006yCHQygy1fji19wr7vuj30jg0t6mz0.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521193126967&di=3a83d14a55b95188f7b105918e02a475&imgtype=" + "0&src=http%3A%2F%2Fimg3.redocn.com%2F20130428%2FRedocn_2013042810251047.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521193141852&di=476991bf1e6d30f435d4705cdc178e53&imgtype=" + "0&src=http%3A%2F%2Fwww.hao76.com%2Fupload%2Fimages%2F2016%2F02%2F17%2F1455674293455015.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=" + "1521183541&di=f55b6ec30acbc08dbb681f923d1daa28&src=http://pic66.nipic.com/file/20150420/10825287_205411048000_2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=" + "1521191615540&di=5e52a3731c80b1b4564f036014fb9987&imgtype=0&src=http%3A%2F%2Fpic8.nipic.com%2F20100617%2F2177138_161905591633_2.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=" + "1521191671311&di=ba894cd7242e6aa0b3a227bc40128ac9&imgtype=0&src=http%3A%2F%2Fpic14.photophoto.cn%2F20100323%2F0036036847921098_b.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521183587&di=dab0dff0921e9d187704b0a981470961&src=http:" + "//www.taopic.com/uploads/allimg/140211/240454-14021113543021.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521183142&di=52d0a50424180c70c41a2947f3f780b7&src" + "=http://img0.ph.126.net/y_GOmy6bGxC7cdgZa2NwMQ==/6631304160703994265.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521193231397&di=682720a88df4c1a508a1ea5ae949d655&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu." + "com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D1753bfd1bd4543a9e116f28f767ee0f7%2F8326cffc1e178a821d4b1e85fc03738da977e8a4.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1521183213&di=d511b4ad3f2daf44785a69aa5650b92b&src=" + "http://imglf1.ph.126.net/eRi8Ek7fjQ9reHdmy1o0JA==/6619587764793673594.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521196807267&di=4bed32da6ae264cc00910e4845f59ad9&imgtype=" + "0&src=http%3A%2F%2Fimg2.ph.126.net%2FJCPcUtlztCBlYRaraDnoUQ%3D%3D%2F6631285469007192491.jpg"); pathList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521196971666&di=55f0eaff04a489b9c13b57e02eda1747&imgtype=" + "0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F140617%2F267820-14061FUJ794.jpg"); new ImaAsyncTask().execute(pathList); } public void setListener(){ adapter.setOnItemClick(new RvAdapter_actInt_Ima.OnItemClick() { @Override public void onClickItem(View view, int position) { Toast.makeText(Activity_int_ima.this, "我是美女吗"+position, Toast.LENGTH_SHORT).show(); } }); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.pagerUP : a -= pager; if (a<0){ a = pathList.size()-pager; // return; } new ImaAsyncTask().execute(pathList); break; case R.id.pagerDown : a += pager; if (a > pathList.size() - pager){ a = 0; } new ImaAsyncTask().execute(pathList); break; } } class ImaAsyncTask extends AsyncTask<List<String>,Integer,List<Bitmap>>{ @Override protected List<Bitmap> doInBackground(List<String>[] lists) { InputStream is; List<Bitmap> bitmapList = new ArrayList<>(); String path; Bitmap bitmap = null; for (int i = a; i < a+pager; i++){ List<String> pathList = lists[0]; path = pathList.get(i); try { URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); int code = connection.getResponseCode(); if (code == 200){ is = connection.getInputStream(); bitmap = BitmapFactory.decodeStream(is); } } catch (IOException e) { e.printStackTrace(); } bitmapList.add(bitmap); } return bitmapList; } @Override protected void onPostExecute(List<Bitmap> bitmaps) { super.onPostExecute(bitmaps); if (bitmaps != null){ bitmapList = bitmaps; adapter.setDataList(bitmapList); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); } } } long time = 0; @Override public void onBackPressed() { long currentTime = System.currentTimeMillis(); if (currentTime - time < 2000){ super.onBackPressed(); }else{ Toast.makeText(this,"再按一次退出",Toast.LENGTH_SHORT).show(); } time = currentTime; } }
package xiamusic.com.yinyuejie.activity; import android.content.Intent; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ListView; import java.util.ArrayList; import java.util.List; import xiamusic.com.yinyuejie.adapter.ListViewAdapter; import xiamusic.com.yinyuejie.music.Music; import xiamusic.com.yinyuejie.service.MyService; import xiamusic.com.yinyuejie.util.Play_final; import xiamusic.com.yinyuejie.R; import static xiamusic.com.yinyuejie.service.MyService.FLAGS; import static xiamusic.com.yinyuejie.service.MyService.play_id; import static xiamusic.com.yinyuejie.service.MyService.play_ing_music; public class Activity_sou extends AppCompatActivity { ListViewAdapter listViewAdapter; ListView listViewsou; EditText et; List<Music> musicList_sou = new ArrayList<>(); List<Music> list_scanAll; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sou); getSupportActionBar().hide(); //-------------------------------------- listViewAdapter = new ListViewAdapter(this); listViewsou = findViewById(R.id.listView_sou); et = findViewById(R.id.e_souMudic); listViewsou.setAdapter(listViewAdapter); list_scanAll = MusicActivity.dataUtil.scan(this); listViewsou.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { play_ing_music = musicList_sou; play_id = position; FLAGS = Play_final.ONE_MUSIC; String url = musicList_sou.get(position).getUrl(); Uri uri = Uri.parse(url); Intent im = new Intent(Activity_sou.this, MyService.class); im.setAction("action"); im.putExtra("cmd", Play_final.PLAY); im.setData(uri); startService(im); Intent intent = new Intent("upTime"); sendBroadcast(intent); } }); et.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { editSouMusic(); } }); } public void editSouMusic(){ List<Music> list = new ArrayList<>(); String name1 = et.getText().toString(); for (Music music : list_scanAll){ if (music.getName().contains(name1)||music.getArtist().contains(name1)){ list.add(music); } } musicList_sou = list; listViewAdapter.notifyDataSetChanged(); listViewAdapter.setDataList(musicList_sou); list = new ArrayList<>(); if (name1.isEmpty()){ listViewAdapter.notifyDataSetChanged(); listViewAdapter.setDataList(list); } } }
package xiamusic.com.yinyuejie.activity; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.SeekBar; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; import xiamusic.com.yinyuejie.util.LrcUtil; import xiamusic.com.yinyuejie.view.LrcView; import xiamusic.com.yinyuejie.music.Music; import xiamusic.com.yinyuejie.service.MyService; import xiamusic.com.yinyuejie.util.Play_final; import xiamusic.com.yinyuejie.R; import static xiamusic.com.yinyuejie.service.MyService.mp; import static xiamusic.com.yinyuejie.service.MyService.play_id; import static xiamusic.com.yinyuejie.service.MyService.play_ing_music; import static xiamusic.com.yinyuejie.util.PhotoUtil.suoFang; public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener, View.OnClickListener { SeekBar seekBar; LrcUtil lrcUtil; LrcView lrcView; ImageView h_qian,h_hou; ImageView h_pause; List<Music> musicList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportActionBar().hide(); widgetInit(); } @SuppressLint({"CutPasteId", "CommitPrefEdits"}) public void widgetInit() { lrcUtil = new LrcUtil(this); lrcView = findViewById(R.id.lrc_view); seekBar = findViewById(R.id.seekBar); h_qian = findViewById(R.id.h_qian); h_hou = findViewById(R.id.h_hou); h_pause = findViewById(R.id.h_pause); h_qian.setOnClickListener(this); h_hou.setOnClickListener(this); h_pause.setOnClickListener(this); seekBar.setOnSeekBarChangeListener(this); musicList = MusicActivity.dataUtil.scan(this); //------------------------------------------------------------------------------------------------------------------- if (play_ing_music == null){ return; }else{ String name = "/"+play_ing_music.get(play_id).getName()+".lrc"; //打开时自动刷新了,invalidate...onCreate File file = new File(MusicActivity.lrcPath + name); lrcView.invalidate(); lrcView.loadLrc(file); } //-------------------------------------------------------------------------------------------------------------------- lrcView.setOnPlayClickListener(new LrcView.OnPlayClickListener() { @Override public boolean onPlayClick(long time) { mp.seekTo((int) time); if (!mp.isPlaying()) { mp.start(); handler_lrcView.post(runnable_lrcView); } return true; } }); LrcReceiver receiver = new LrcReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("lrc"); registerReceiver(receiver,filter); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.h_qian : play_id --; if (play_id <=1){ play_id = musicList.size()-1; return; } else { String url = musicList.get(play_id).getUrl(); Uri uri = Uri.parse(url); Intent intent = new Intent(this,MyService.class); intent.setData(uri); intent.setAction("acton"); intent.putExtra("cmd", Play_final.PLAY); startService(intent); handler_sek.post(run_sek); updateLrc(); } suoFang(h_qian,0.9f,1f,150); break; case R.id.h_hou : play_id ++; if (play_id == musicList.size() - 1){ play_id = 0; return; } else { String url = musicList.get(play_id).getUrl(); Uri uri = Uri.parse(url); Intent intent = new Intent(this,MyService.class); intent.setData(uri); intent.setAction("acton"); intent.putExtra("cmd",Play_final.PLAY); startService(intent); handler_sek.post(run_sek); updateLrc(); } suoFang(h_hou,0.9f,1f,150); break; case R.id.h_pause : suoFang(h_pause,0.9f,1f,150); Intent ipa = new Intent(this, MyService.class); ipa.setAction("action"); ipa.putExtra("cmd", Play_final.PAUSE); startService(ipa); if (mp != null){ if (!mp.isPlaying()) { handler_sek.post(run_sek); } else if (mp.isPlaying()){ handler_sek.removeCallbacks(run_sek); } } break; } } public void updateLrc(){ String name = "/"+play_ing_music.get(play_id).getName()+".lrc"; //打开时自动刷新了,invalidate...onCreate File file = new File(MusicActivity.filePath + name); lrcView.invalidate(); lrcView.loadLrc(file); } Handler handler_sek = new Handler(); private Runnable run_sek = new Runnable() { @Override public void run() { seekBar.setMax(mp.getDuration()); seekBar.setProgress(mp.getCurrentPosition()); handler_sek.postDelayed(this,1000); } }; Handler handler_lrcView = new Handler(); private Runnable runnable_lrcView = new Runnable() { @Override public void run() { if (mp.isPlaying()) { long time = mp.getCurrentPosition(); lrcView.updateTime(time); seekBar.setProgress((int) time); } handler_lrcView.postDelayed(this, 300); } }; private String getLrcText(String fileName) { String lrcText = null; try { InputStream is = getAssets().open(fileName); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); lrcText = new String(buffer); } catch (IOException e) { e.printStackTrace(); } return lrcText; } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { seekBar.setMax(mp.getDuration()); mp.seekTo(seekBar.getProgress()); } @Override protected void onResume() { handler_sek.post(run_sek); handler_lrcView.post(runnable_lrcView); play_ing_music = musicList; super.onResume(); } @Override protected void onPause() { super.onPause(); } class LrcReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { } } } // public void souMusic() { // String name = edit_souMusic.getText().toString(); // List<Music> musicList = new ArrayList<>(); // for (Music music : musicList1) { // if (music.getName().contains(name) || music.getArtist().contains(name)) { // musicList.add(music); // } // } // musicList1 = musicList; // adapter.setDataList(musicList1); // adapter.notifyDataSetChanged(); // edit_souMusic.setText(""); // if (!name.isEmpty()){ // delayed_handler.sendEmptyMessageDelayed(Play_final.H_SOUGE,5000); // } // }
package xiamusic.com.yinyuejie.activity; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; import android.util.LruCache; import android.view.Gravity; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.PopupMenu; import android.widget.TextView; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import xiamusic.com.yinyuejie.util.DataUtil; import xiamusic.com.yinyuejie.fragment.FragmentArtist; import xiamusic.com.yinyuejie.fragment.Fragment_Love; import xiamusic.com.yinyuejie.fragment.Fragment_fill; import xiamusic.com.yinyuejie.service.MyService; import xiamusic.com.yinyuejie.util.PhotoUtil; import xiamusic.com.yinyuejie.util.Play_final; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.view.Sort_View; import static xiamusic.com.yinyuejie.fragment.Fragment_fill.recyclerView; import static xiamusic.com.yinyuejie.music.ComparatorName.sortName; import static xiamusic.com.yinyuejie.service.MyService.FLAGS; import static xiamusic.com.yinyuejie.service.MyService.mp; import static xiamusic.com.yinyuejie.service.MyService.play_id; import static xiamusic.com.yinyuejie.service.MyService.play_ing_music; import static xiamusic.com.yinyuejie.util.PhotoUtil.rotateView; import static xiamusic.com.yinyuejie.util.PhotoUtil.suoFang; public class MusicActivity extends AppCompatActivity implements View.OnClickListener, PopupMenu.OnMenuItemClickListener { List<Fragment> fragmentList = new ArrayList<>(); List<String> strTitle = new ArrayList<>(); ViewPager viewPager; // PagerTabStrip strip; PagerAdapter adapter; Toolbar toolbar; @SuppressLint("StaticFieldLeak") public static ImageView img_artist; @SuppressLint("StaticFieldLeak") public static ImageView img_musicPause; TextView time_view, song_view; public static DataUtil dataUtil; static File lrcPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); public static File filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); public String cRImagePath; public static LruCache<String, Bitmap> mMemoryCache; ImageView ivsou; ImageView iv_menu, iv_sort; TabLayout tabLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_music); getSupportActionBar().hide(); cRImagePath = getExternalFilesDir(null).getPath(); init(); createMemory(); showView(); setPageTransformer(); } public void createMemory() { final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount() / 1024; } }; } public void init() { iv_sort = findViewById(R.id.image_sort); tabLayout = findViewById(R.id.tablayout); iv_menu = findViewById(R.id.ima_menu); ivsou = findViewById(R.id.fill_sou); // strip = findViewById(R.id.tabs); toolbar = findViewById(R.id.toolbar); img_artist = findViewById(R.id.img_artist); img_musicPause = findViewById(R.id.music_pause); time_view = findViewById(R.id.time_textview); song_view = findViewById(R.id.song_textview); viewPager = this.findViewById(R.id.viewpager); tabLayout.setupWithViewPager(viewPager); dataUtil = new DataUtil(this); img_artist.setOnClickListener(this); img_musicPause.setOnClickListener(this); song_view.setOnClickListener(this); ivsou.setOnClickListener(this); iv_menu.setOnClickListener(this); iv_sort.setOnClickListener(this); // strip.setTabIndicatorColorResource(R.color.colorAccent); newFragment(); adapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); UpTimeReceiver receiver = new UpTimeReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("upTime"); registerReceiver(receiver, intentFilter); if (play_ing_music == null) { play_ing_music = dataUtil.scan(this); } toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return false; } }); } public void newFragment() { Fragment f1 = new Fragment_fill(); Fragment f2 = new Fragment_Love(); Fragment f3 = new FragmentArtist(); fragmentList.add(f1); fragmentList.add(f2); fragmentList.add(f3); strTitle.add("本地音乐"); strTitle.add("喜爱列表"); strTitle.add("艺术家专辑"); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.img_artist: //随机 suoFang(img_artist, 0.9f, 1f, 300); FLAGS = Play_final.NoONE_MUSIC; if (play_ing_music == null) { return; } else { play_id = ThreadLocalRandom.current().nextInt(0, play_ing_music.size()); // play_id = (int) Math.floor((Math.random() * play_ing_music.size())); Uri uri = Uri.parse(play_ing_music.get(play_id).getUrl()); Intent intent = new Intent(this, MyService.class); intent.setAction("action"); intent.setData(uri); intent.putExtra("cmd", Play_final.SUIJI); startService(intent); handler.post(runnable); } break; case R.id.music_pause: Intent ipa = new Intent(this, MyService.class); ipa.setAction("action"); ipa.putExtra("cmd", Play_final.PAUSE); startService(ipa); suoFang(img_musicPause, 0.9f, 1f, 150); Runnable_updateSong(); break; case R.id.song_textview: Intent intent1 = new Intent(this, MainActivity.class); startActivity(intent1); break; case R.id.fill_sou: suoFang(ivsou, 0.9f, 1f, 100); Intent intent2 = new Intent(this, Activity_sou.class); startActivity(intent2); break; case R.id.image_sort: sortName = !sortName; Intent intent = new Intent("search"); sendBroadcast(intent); if (sortName) { rotateView(iv_sort, 0, 180f, 200); } else { rotateView(iv_sort, 180f, 0f, 200); } break; //-------------------------------------------------------------------------------Menu--------------------------- case R.id.ima_menu: rotateView(v, 0f, 90f, 300); PopupMenu popupMenu = new PopupMenu(this, v); popupMenu.inflate(R.menu.music_activity_topmenu); popupMenu.show(); popupMenu.setOnMenuItemClickListener(this); popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() { @Override public void onDismiss(PopupMenu menu) { rotateView(iv_menu, 90f, 0f, 300); } }); break; } } public void Runnable_updateSong() { if (mp != null) { if (!mp.isPlaying()) { handler.post(runnable); } else if (mp.isPlaying()) { handler.removeCallbacks(runnable); } } } Handler handler = new Handler(); private Runnable runnable = new Runnable() { @SuppressLint("SetTextI18n") @Override public void run() { int sum = (mp.getCurrentPosition() / 1000); int m = sum / 60; int s = sum - m * 60; if (s < 10) { time_view.setText("0" + m + ":0" + s); } else { time_view.setText("0" + m + ":" + s); } if (mp.isPlaying()) { song_view.setText(play_ing_music.get(play_id).getName()); } handler.postDelayed(this, 1000); // handler.post(runnable);**任务, } }; @Override protected void onResume() { Intent intent = new Intent(this, MyService.class); intent.setAction("action"); intent.putExtra("cmd", Play_final.UPDATA_PIC); startService(intent); Intent intent1 = new Intent("upTime"); sendBroadcast(intent1); super.onResume(); } @Override public boolean onMenuItemClick(MenuItem item) { //-------------------menu------------------------- switch (item.getItemId()) { case R.id.menu_Crop_Bitmap: new Thread(new Runnable() { @Override public void run() { PhotoUtil p = new PhotoUtil(MusicActivity.this); p.scanPic_Crop_Save(); } }).start(); break; case R.id.menu_delete_love: new Thread(new Runnable() { @Override public void run() { dataUtil.resetMusiclove(); } }).start(); break; case R.id.activity_intIma: Intent intent = new Intent(this, Activity_int_ima.class); startActivity(intent); break; } return true; } class UpTimeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("upTime")) { handler.post(runnable); } } } /** */ class PagerAdapter extends FragmentPagerAdapter { public PagerAdapter(FragmentManager fm) { super(fm); } @Override public android.support.v4.app.Fragment getItem(int position) { return fragmentList.get(position); } @Override public int getCount() { return fragmentList.size(); } @Override public CharSequence getPageTitle(int position) { return strTitle.get(position); } } //------------sortView--------------------------- public static Boolean sortView_visibility; public static Sort_View sortView; public WindowManager windowManager; public WindowManager.LayoutParams myLayoutParams; public void setPageTransformer(){ viewPager.setPageTransformer(true, new ViewPager.PageTransformer() { @Override public void transformPage(View page, float position) { if (sortView_visibility){ if (position >= -0.1){ sortView.setVisibility(View.VISIBLE); }else{ sortView.setVisibility(View.GONE); } } } }); } @SuppressLint({"ClickableViewAccessibility", "RtlHardcoded"}) public void showView(){ sortView = new Sort_View(this); windowManager = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE); myLayoutParams = new WindowManager.LayoutParams(); myLayoutParams.width = 80; myLayoutParams.height = 1600; myLayoutParams.gravity = Gravity.RIGHT; myLayoutParams.x = 0; myLayoutParams.y = 38; myLayoutParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; //这个也可以在程序里显示。TYPE_APPLICATION_STARTING myLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; myLayoutParams.format = PixelFormat.RGBA_8888; windowManager.addView(sortView,myLayoutParams); } //------------sortView-------------------------------- }接下来是几个adapter,
package xiamusic.com.yinyuejie.adapter; import android.annotation.SuppressLint; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.SectionIndexer; import android.widget.TextView; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Music; /** * Created by Administrator on 2018/3/10. */ public class ListViewAdapter extends BaseAdapter { private Context context; private List<Music> dataList; //这里是方便给adapter添加不同列表。 public ListViewAdapter(Context context) { this.context = context; } public List<Music> getDataList() { return dataList; } public void setDataList(List<Music> dataList) { this.dataList = dataList; } @Override public int getCount() { if (null != dataList) { return dataList.size(); } return 0; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @SuppressLint({"InflateParams", "SetTextI18n"}) @Override public View getView(int position, View convertView, ViewGroup parent) { HolderLove viewHolder = null; if (null == convertView) { convertView = LayoutInflater.from(context).inflate(R.layout.item_sou, null); viewHolder = new HolderLove(); viewHolder.image_album = convertView.findViewById(R.id.im_album_sou); viewHolder.tv1 = (TextView) convertView.findViewById(R.id.text_soujieguo); convertView.setTag(viewHolder); } else { viewHolder = (HolderLove) convertView.getTag(); } viewHolder.image_album.setImageResource(R.drawable.mymusic_sou); viewHolder.tv1.setText(dataList.get(position).getArtist() +"--"+dataList.get(position).getName()); return convertView; } class HolderLove { ImageView image_album; TextView tv1; } }
package xiamusic.com.yinyuejie.adapter; import android.content.Context; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import java.util.List; import xiamusic.com.yinyuejie.R; /** * Created by Administrator on 2018/3/16. */ public class RvAdapter_actInt_Ima extends RecyclerView.Adapter<RvAdapter_actInt_Ima.ViewHolder> { private List<Bitmap> dataList; private Context context; public RvAdapter_actInt_Ima(Context context){ this.context = context; } public void setDataList(List<Bitmap> dataList){ this.dataList = dataList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_act_int_ima,parent,false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(final ViewHolder holder, int position) { Bitmap bitmap = dataList.get(position); holder.iv.setImageBitmap(bitmap); if (onItemClick != null){ holder.iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getLayoutPosition(); onItemClick.onClickItem(holder.iv,position); } }); } } @Override public int getItemCount() { return (null != dataList ? dataList.size() : 0); } class ViewHolder extends RecyclerView.ViewHolder { ImageView iv; ViewHolder(View itemView) { super(itemView); iv = itemView.findViewById(R.id.xRv_act_image1); } } public interface OnItemClick{ void onClickItem(View view,int position); } public OnItemClick onItemClick; public void setOnItemClick(OnItemClick onItemClick){ this.onItemClick = onItemClick; } }
package xiamusic.com.yinyuejie.adapter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Music; /** * Created by Administrator on 2018/3/12. */ public class RvAdapter_artist_musicTab extends RecyclerView.Adapter<RvAdapter_artist_musicTab.HolderMusicTab> { Context context; List<Music> dataList; public RvAdapter_artist_musicTab(Context context){ this.context = context; } public void setDataList(List<Music> dataList){ this.dataList = dataList; } @Override public HolderMusicTab onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.adapter_artist_musictab,parent,false); HolderMusicTab holder = new HolderMusicTab(view); return holder; } @Override public void onBindViewHolder(final HolderMusicTab holder, int position) { holder.iv.setImageResource(R.drawable.yinyue); holder.tv.setText(dataList.get(position).getName()); if (mOnItemClickListener != null){ holder.ll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = holder.getLayoutPosition(); mOnItemClickListener.onItemClick(holder.ll,p); } }); } } @Override public int getItemCount() { return (null != dataList ? dataList.size() : 0); } public class HolderMusicTab extends RecyclerView.ViewHolder { ImageView iv; LinearLayout ll; TextView tv; public HolderMusicTab(View itemView) { super(itemView); ll = itemView.findViewById(R.id.lin_musicTab); iv = itemView.findViewById(R.id.im_musicTab); tv = itemView.findViewById(R.id.text_musicTab); } } public interface OnItemClickListener{ void onItemClick(View view,int position); } private OnItemClickListener mOnItemClickListener; public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; } }
package xiamusic.com.yinyuejie.adapter; import android.annotation.SuppressLint; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.github.promeg.pinyinhelper.Pinyin; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Music; import xiamusic.com.yinyuejie.util.DataUtil; /** * Created by Administrator on 2018/3/10. */ public class RvAdapterAllMusic extends RecyclerView.Adapter<RvAdapterAllMusic.MyViewHolder> { private List<Music> dataList; private Context context; public static int[] aaa; public RvAdapterAllMusic(Context context){ this.context = context; } public void setDataList(List<Music> list){ this.dataList = list; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_allmusic,parent,false)); } @SuppressLint("SetTextI18n") @Override public void onBindViewHolder(final MyViewHolder holder, int position) { String name = dataList.get(position).getName(); String artist = dataList.get(position).getArtist(); holder.tv1.setText(name); holder.tv2.setText(artist); if (onItemListener != null){ holder.linearLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = holder.getLayoutPosition(); onItemListener.OnItemClickListener(holder.linearLayout,p); } }); holder.line_shoucang.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = holder.getLayoutPosition(); onItemListener.OnItemClickListener(holder.line_shoucang,p); } }); } String pinyin0 = Pinyin.toPinyin(name.charAt(0)); String pp0 = pinyin0.substring(0,1); aaa = DataUtil.abc_index(dataList); Boolean a = DataUtil.displayAA(dataList,position); if (a){ holder.tv_ABDC.setVisibility(View.VISIBLE); holder.tv_ABDC.setText(" "+pp0); }else{ holder.tv_ABDC.setVisibility(View.GONE); } } @Override public int getItemCount() { return dataList.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ ImageView iv1,iv2; TextView tv1,tv2,tv_ABDC; LinearLayout linearLayout,line_shoucang; MyViewHolder(View itemView) { super(itemView); line_shoucang = itemView.findViewById(R.id.line_item_AllMusic); iv1 = itemView.findViewById(R.id.iv_title_allMusic); iv2 = itemView.findViewById(R.id.iv2_allMusic); tv1 = itemView.findViewById(R.id.tv1_allMusic); tv2 = itemView.findViewById(R.id.tv2_allMusic); tv_ABDC = itemView.findViewById(R.id.index_ABCD); linearLayout = itemView.findViewById(R.id.line_AllMusic); } } public interface OnItemListener{ void OnItemClickListener(View view,int position); } private OnItemListener onItemListener; public void setOnItemListener(OnItemListener listener){ this.onItemListener = listener; } }
package xiamusic.com.yinyuejie.adapter; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.graphics.Palette; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.io.File; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Artist; import static xiamusic.com.yinyuejie.activity.MusicActivity.filePath; import static xiamusic.com.yinyuejie.activity.MusicActivity.mMemoryCache; /** * Created by Administrator on 2018/3/10. */ public class RvAdapterArtist extends RecyclerView.Adapter<RvAdapterArtist.MyHolder> { private List<Artist> dataList; Context context; public void setDataList(List<Artist> list){ this.dataList = list; } public RvAdapterArtist(Context context){ this.context = context; } @Override public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_artist_cardview,parent,false); MyHolder viewHolder = new MyHolder(view); return viewHolder; } @SuppressLint("SetTextI18n") @Override public void onBindViewHolder(final MyHolder holder, int position) { String artist = dataList.get(position).artist; holder.tv1.setText(dataList.get(position).artist); holder.tv2.setText(dataList.get(position).songCont+ " 首歌曲"); if ( mMemoryCache.get(artist) == null){ File[] files = filePath.listFiles(); for (File item : files) { if (item.getName().equals(artist + ".jpg")) { String path = item.getPath(); Bitmap bitmap = BitmapFactory.decodeFile(path); mMemoryCache.put(artist, bitmap); } } } Bitmap bitmap = mMemoryCache.get(dataList.get(position).artist); if (bitmap != null){ holder.iv1.setImageBitmap(bitmap); Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() { @Override public void onGenerated(Palette palette) { Palette.Swatch swatch = palette.getLightVibrantSwatch(); if (swatch != null){ holder.line_artist_cardview.setBackgroundColor(swatch.getRgb()); } } }); }else { holder.iv1.setImageResource(R.drawable.yinyue); } if(mOnItemClickListener != null){ //为ItemView设置监听器 holder.iv1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getLayoutPosition(); mOnItemClickListener.onItemClick(holder.itemView,position); } }); } } @Override public int getItemCount() { return (null != dataList ? dataList.size() : 0); } class MyHolder extends RecyclerView.ViewHolder{ TextView tv1,tv2; ImageView iv1; LinearLayout line_artist_cardview; MyHolder(View itemView) { super(itemView); line_artist_cardview = itemView.findViewById(R.id.line_artist_cardview); tv1 = itemView.findViewById(R.id.artist_name); tv2 = itemView.findViewById(R.id.artist_album); iv1 = itemView.findViewById(R.id.artist_artist); } } public interface OnItemClickListener{ void onItemClick(View view,int position); } private OnItemClickListener mOnItemClickListener; public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; } }
package xiamusic.com.yinyuejie.adapter; import android.content.Context; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Music; import static xiamusic.com.yinyuejie.activity.MusicActivity.mMemoryCache; import static xiamusic.com.yinyuejie.util.PhotoUtil.scanImage; /** * Created by Administrator on 2018/3/10. */ public class RvAdapterLove extends RecyclerView.Adapter<RvAdapterLove.MyHolder> { private List<Music> dataList; Context context; public void setDataList(List<Music> list){ this.dataList = list; } public RvAdapterLove(Context context){ this.context = context; } @Override public RvAdapterLove.MyHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_love,parent,false); MyHolder holder = new MyHolder(view); return holder; } @Override public void onBindViewHolder(final MyHolder holder, int position) { holder.tv1.setText(dataList.get(position).getName()); holder.tv2.setText(dataList.get(position).getArtist()); String artist = dataList.get(position).getArtist(); if ( mMemoryCache.get(artist) == null){ Bitmap b = scanImage(artist); if (b != null){ mMemoryCache.put(artist,b); } } Bitmap bitmap = mMemoryCache.get(dataList.get(position).getArtist()); if (bitmap != null){ holder.iv1.setImageBitmap(bitmap); }else { holder.iv1.setImageResource(R.drawable.yinyue); } if (onItemListener != null) { holder.linearLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = holder.getLayoutPosition(); onItemListener.onItemClick(holder.linearLayout, p); } }); holder.iv2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = holder.getLayoutPosition(); onItemListener.onItemClick(holder.iv2,p); } }); } } @Override public int getItemCount() { return dataList.size(); } class MyHolder extends RecyclerView.ViewHolder{ TextView tv1,tv2; ImageView iv1,iv2; LinearLayout linearLayout; MyHolder(View itemView) { super(itemView); linearLayout = itemView.findViewById(R.id.lin_recyclerView); tv1 = itemView.findViewById(R.id.adapter_t1); tv2 = itemView.findViewById(R.id.adapter_t2); iv1 = itemView.findViewById(R.id.adapter_album); iv2 = itemView.findViewById(R.id.adpter_delete); } } public interface OnAdapterItemListener{ void onItemClick(View view,int position); } private OnAdapterItemListener onItemListener; public void setOnItemClickListener(OnAdapterItemListener listener){ this.onItemListener = listener; } }
package xiamusic.com.yinyuejie.adapter; import android.content.Context; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Music; import static xiamusic.com.yinyuejie.activity.MusicActivity.mMemoryCache; import static xiamusic.com.yinyuejie.util.PhotoUtil.scanImage; /** * Created by Administrator on 2018/3/11. */ public class XRecyclerView_Adapter extends RecyclerView.Adapter<XRecyclerView_Adapter.XviewHolder> { Context context; private List<Music> dataList; public XRecyclerView_Adapter(Context context){ this.context = context; } public void setDataList(List<Music> dataList){ this.dataList = dataList; } @Override public XviewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_internet_cardview,parent,false); XviewHolder holder = new XviewHolder(view); return holder; } @Override public void onBindViewHolder(final XviewHolder holder, int position) { String song = dataList.get(position).getName(); String artist = dataList.get(position).getArtist(); holder.text_song.setText(song); holder.text_artist.setText(artist); if ( mMemoryCache.get(song) == null){ Bitmap b = scanImage(song); if (b != null){ mMemoryCache.put(song,b); } } Bitmap bitmap = mMemoryCache.get(dataList.get(position).getName()); if (bitmap != null){ holder.imageView.setImageBitmap(bitmap); }else { holder.imageView.setImageResource(R.drawable.yinyue); } if (itemListener != null){ holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = holder.getLayoutPosition(); itemListener.onItemClickListener(holder.imageView,p); } }); } } @Override public int getItemCount() { return dataList.size(); } class XviewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView text_song; TextView text_artist; XviewHolder(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.int_card_Image); text_song = itemView.findViewById(R.id.int_card_song); text_artist = itemView.findViewById(R.id.int_card_artist); } } public interface OnItemClickListener{ void onItemClickListener(View view,int position); } private OnItemClickListener itemListener; public void onItemClickListener(OnItemClickListener listener ){ this.itemListener = listener; } }
下面是三个列表的fragment
package xiamusic.com.yinyuejie.fragment; import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import java.util.Collections; import java.util.List; import xiamusic.com.yinyuejie.activity.MusicActivity; import xiamusic.com.yinyuejie.music.ComparatorName; import xiamusic.com.yinyuejie.service.MyService; import xiamusic.com.yinyuejie.util.Play_final; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.adapter.RvAdapterAllMusic; import xiamusic.com.yinyuejie.music.Music; import xiamusic.com.yinyuejie.view.Sort_View; import static xiamusic.com.yinyuejie.activity.MusicActivity.dataUtil; import static xiamusic.com.yinyuejie.activity.MusicActivity.img_artist; import static xiamusic.com.yinyuejie.activity.MusicActivity.img_musicPause; import static xiamusic.com.yinyuejie.activity.MusicActivity.sortView_visibility; import static xiamusic.com.yinyuejie.service.MyService.mp; import static xiamusic.com.yinyuejie.service.MyService.play_ing_music; import static xiamusic.com.yinyuejie.service.MyService.FLAGS; import static xiamusic.com.yinyuejie.service.MyService.play_id; import static xiamusic.com.yinyuejie.util.PhotoUtil.rotateImg; import static xiamusic.com.yinyuejie.util.PhotoUtil.scanFile_Crop_imageView; /** * Created by Administrator on 2018/3/10. */ public class Fragment_fill extends Fragment { List<Music> list_fill; public static RecyclerView recyclerView; public RvAdapterAllMusic fill_adapter; LinearLayoutManager manager; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @SuppressLint("InflateParams") View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_fill,null); recyclerView = view.findViewById(R.id.recyclerView_fill); initView(); initListener(); registerReceiver(); return view; } public void initView(){ fill_adapter = new RvAdapterAllMusic(getContext()); manager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false); if (list_fill == null){ new Scan_fillTask().execute(); }else{ fill_adapter.setDataList(list_fill); recyclerView.setLayoutManager(manager); recyclerView.setAdapter(fill_adapter); } } public void initListener(){ fill_adapter.setOnItemListener(new RvAdapterAllMusic.OnItemListener() { @Override public void OnItemClickListener(View view, int position) { switch(view.getId()){ case R.id.line_AllMusic : play_ing_music = list_fill; play_id = position; FLAGS = Play_final.ONE_MUSIC; String url = play_ing_music.get(position).getUrl(); Uri uri = Uri.parse(url); Intent im = new Intent(getContext(), MyService.class); im.setAction("action"); im.putExtra("cmd", Play_final.PLAY); im.setData(uri); getContext().startService(im); Intent intent = new Intent("upTime"); getContext().sendBroadcast(intent); handler.post(runnable); break; case R.id.line_item_AllMusic : Toast.makeText(getContext(), "已添加--"+list_fill.get(position).getName()+"--到收藏", Toast.LENGTH_SHORT).show(); new UpLoveListTask().execute(position); break; } } }); } Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { img_musicPause.setImageResource(R.drawable.pause_fill); scanFile_Crop_imageView(play_ing_music.get(play_id).getArtist(),img_artist); int mss = mp.getDuration(); int aa = mss / 360; int bb = aa * 360; rotateImg(img_artist, bb / 100, mss); } }; @SuppressLint("StaticFieldLeak") class UpLoveListTask extends AsyncTask<Integer,Integer,List<Music>> { @Override protected List<Music> doInBackground(Integer... integers) { int position = integers[0]; String artist = list_fill.get(position).getArtist(); String url2 = list_fill.get(position).getUrl(); //从音乐扫来的url String album = list_fill.get(position).getAlbum(); String name = list_fill.get(position).getName(); dataUtil.addMusicLove(name,artist,album,url2); List<Music> m; m = dataUtil.scan_Love_list(); Collections.sort(m,new ComparatorName()); //排序后再返回; return m; } @Override protected void onPostExecute(List<Music> music) { Fragment_Love.list_fMusicLove = music; Fragment_Love.adapter_Love.notifyDataSetChanged(); Fragment_Love.adapter_Love.setDataList(Fragment_Love.list_fMusicLove); super.onPostExecute(music); } } class Scan_fillTask extends AsyncTask<Void,Integer,List<Music>>{ @Override protected List<Music> doInBackground(Void... voids) { List<Music> musics = dataUtil.scan(getContext()); Collections.sort(musics,new ComparatorName()); return musics; } @Override protected void onPostExecute(List<Music> music) { list_fill = music; fill_adapter.setDataList(list_fill); recyclerView.setLayoutManager(manager); recyclerView.setAdapter(fill_adapter); super.onPostExecute(music); } } public void registerReceiver(){ SearchReceiver receiver = new SearchReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("search"); getActivity().registerReceiver(receiver,filter); } class SearchReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("search")){ Collections.sort(list_fill,new ComparatorName()); fill_adapter.notifyDataSetChanged(); } } } @Override public void setUserVisibleHint(boolean isVisibleToUser) { if (isVisibleToUser) { MusicActivity.sortView.setVisibility(View.VISIBLE); sortView_visibility = true; }else { sortView_visibility = false; } } }
package xiamusic.com.yinyuejie.fragment; import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import java.util.List; import xiamusic.com.yinyuejie.service.MyService; import xiamusic.com.yinyuejie.util.Play_final; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.adapter.RvAdapterLove; import xiamusic.com.yinyuejie.music.Music; import static xiamusic.com.yinyuejie.activity.MusicActivity.dataUtil; import static xiamusic.com.yinyuejie.activity.MusicActivity.img_artist; import static xiamusic.com.yinyuejie.activity.MusicActivity.img_musicPause; import static xiamusic.com.yinyuejie.activity.MusicActivity.sortView; import static xiamusic.com.yinyuejie.service.MyService.FLAGS; import static xiamusic.com.yinyuejie.service.MyService.mp; import static xiamusic.com.yinyuejie.service.MyService.play_id; import static xiamusic.com.yinyuejie.service.MyService.play_ing_music; import static xiamusic.com.yinyuejie.util.PhotoUtil.rotateImg; import static xiamusic.com.yinyuejie.util.PhotoUtil.scanFile_Crop_imageView; /** * Created by Administrator on 2018/3/10. */ public class Fragment_Love extends Fragment { RecyclerView recyclerView; LinearLayoutManager linearLayoutManager; static RvAdapterLove adapter_Love; static List<Music> list_fMusicLove; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_love,null); recyclerView = view.findViewById(R.id.recyclerView_love); initView(); initListener(); return view; } public void initView(){ list_fMusicLove = dataUtil.scan_Love_list(); linearLayoutManager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false); adapter_Love = new RvAdapterLove(getContext()); recyclerView.setLayoutManager(linearLayoutManager); adapter_Love.setDataList(list_fMusicLove); recyclerView.setAdapter(adapter_Love); } public void initListener(){ adapter_Love.setOnItemClickListener(new RvAdapterLove.OnAdapterItemListener() { @Override public void onItemClick(View view, int position) { switch(view.getId()){ case R.id.lin_recyclerView: play_ing_music = list_fMusicLove; play_id = position; FLAGS = Play_final.ONE_MUSIC; String url = list_fMusicLove.get(position).getUrl(); Uri uri = Uri.parse(url); Intent im = new Intent(getContext(), MyService.class); im.setAction("action"); im.putExtra("cmd", Play_final.PLAY); im.setData(uri); getContext().startService(im); Intent intent = new Intent("upTime"); getContext().sendBroadcast(intent); handler.post(runnable); break; case R.id.adpter_delete : dataUtil.deleteLoveOne(list_fMusicLove.get(position).getName()); han_delete.sendEmptyMessageDelayed(0,1000); Toast.makeText(getContext(),"从喜欢中删除--"+list_fMusicLove.get(position).getName(), Toast.LENGTH_SHORT).show(); break; } } }); } @SuppressLint("HandlerLeak") Handler han_delete = new Handler(){ @Override public void handleMessage(Message msg) { adapter_Love.notifyDataSetChanged(); list_fMusicLove = dataUtil.scan_Love_list(); if (mp.isPlaying()){ adapter_Love.setDataList(list_fMusicLove); }else{ play_ing_music = list_fMusicLove; adapter_Love.setDataList(list_fMusicLove); } } }; Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { img_musicPause.setImageResource(R.drawable.pause_fill); scanFile_Crop_imageView(play_ing_music.get(play_id).getArtist(),img_artist); int mss = mp.getDuration(); int aa = mss / 360; int bb = aa * 360; rotateImg(img_artist, bb / 100, mss); } }; @Override public void setUserVisibleHint(boolean isVisibleToUser) { if (isVisibleToUser){ sortView.setVisibility(View.GONE); } } }
package xiamusic.com.yinyuejie.fragment; import android.annotation.SuppressLint; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.Collections; import java.util.List; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.activity.Activity_artist_music; import xiamusic.com.yinyuejie.adapter.RvAdapterArtist; import xiamusic.com.yinyuejie.music.Artist; import xiamusic.com.yinyuejie.music.ComparatorArtist; import static android.content.Context.MODE_PRIVATE; import static xiamusic.com.yinyuejie.activity.MusicActivity.dataUtil; /** * Created by Administrator on 2018/3/7. */ public class FragmentArtist extends Fragment { RecyclerView recyclerView; GridLayoutManager gridLayoutManager; RvAdapterArtist adapterArtist; List<Artist> artistsList; public static SharedPreferences sp; SharedPreferences.Editor editor; @SuppressLint("CommitPrefEdits") @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { @SuppressLint("InflateParams") View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_artist,null); recyclerView = view.findViewById(R.id.recyclerView); sp = getActivity().getSharedPreferences("PROF",MODE_PRIVATE); editor = sp.edit(); initView(); initListener(); return view; } public void initView(){ gridLayoutManager = new GridLayoutManager(getContext(),2); adapterArtist = new RvAdapterArtist(getContext()); if (artistsList == null){ artistsList = dataUtil.getArtist(getContext()); Collections.sort(artistsList,new ComparatorArtist()); //按拼音混排 recyclerView.setLayoutManager(gridLayoutManager); adapterArtist.setDataList(artistsList); recyclerView.setAdapter(adapterArtist); }else{ recyclerView.setLayoutManager(gridLayoutManager); adapterArtist.setDataList(artistsList); recyclerView.setAdapter(adapterArtist); } } public void initListener(){ adapterArtist.setOnItemClickListener(new RvAdapterArtist.OnItemClickListener() { @Override public void onItemClick(View view, int position) { String ar = artistsList.get(position).artist; editor.putString("ar",ar); editor.commit(); handler.postDelayed(runnable,300); } }); } Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { Intent intent = new Intent(getContext(),Activity_artist_music.class); startActivity(intent); } }; }
下面是几个实体Bean 和排序类
package xiamusic.com.yinyuejie.music; /** * Created by Administrator on 2018/3/12. */ public class Artist { public int artistId; public String artist; public int albumCont; public int songCont; }
package xiamusic.com.yinyuejie.music; import com.github.promeg.pinyinhelper.Pinyin; import java.util.Comparator; /** * Created by Administrator on 2018/3/22. */ public class ComparatorArtist implements Comparator<Artist>{ @Override public int compare(Artist o1, Artist o2) { String pf = Pinyin.toPinyin(o1.artist.charAt(0)); String pf2 = Pinyin.toPinyin(o2.artist.charAt(0)); return pf.compareTo(pf2); } }
package xiamusic.com.yinyuejie.music; import com.github.promeg.pinyinhelper.Pinyin; import java.text.CollationKey; import java.text.Collator; import java.util.Comparator; import java.util.function.Function; import java.util.function.ToDoubleFunction; import java.util.function.ToIntFunction; import java.util.function.ToLongFunction; /** * Created by Administrator on 2018/3/19. */ public class ComparatorName implements Comparator<Music> { Collator collator = Collator.getInstance(); public static Boolean sortName = false; public void setSortName(Boolean sortName) { this.sortName = sortName; } @Override public int compare(Music o1, Music o2) { // CollationKey key1 = collator.getCollationKey(((Music) o1).getName()); // 按中文拼音首字母排序;英在最下面。 // CollationKey key2 = collator.getCollationKey(((Music) o2).getName()); // int a = key1.compareTo(key2); // return (sortName == false ? a : -a); String p1 = Pinyin.toPinyin(o1.getName().charAt(0)); String p2 = Pinyin.toPinyin(o2.getName().charAt(0)); int a = p1.compareTo(p2); return (sortName == false ? a : -a); //中英混排 } @Override public Comparator<Music> reversed() { return null; } @Override public Comparator<Music> thenComparing(Comparator<? super Music> other) { return null; } @Override public <U> Comparator<Music> thenComparing(Function<? super Music, ? extends U> keyExtractor, Comparator<? super U> keyComparator) { return null; } @Override public <U extends Comparable<? super U>> Comparator<Music> thenComparing(Function<? super Music, ? extends U> keyExtractor) { return null; } @Override public Comparator<Music> thenComparingInt(ToIntFunction<? super Music> keyExtractor) { return null; } @Override public Comparator<Music> thenComparingLong(ToLongFunction<? super Music> keyExtractor) { return null; } @Override public Comparator<Music> thenComparingDouble(ToDoubleFunction<? super Music> keyExtractor) { return null; } }
package xiamusic.com.yinyuejie.music; /** * Created by Administrator on 2018/3/4. */ public class LRC{ //保存当前时间 public long currentTime; //保存内容 public String content; public long getCurrentTime() { return currentTime; } public void setContent(String content) { this.content = content; } public void setCurrentTime(long currentTime) { this.currentTime = currentTime; } public String getContent() { return content; } // @Override // public int compareTo(@NonNull LRC o) { // return 0; // } }
package xiamusic.com.yinyuejie.music; /** * Created by Administrator on 2018/2/28. */ public class Music { public String name; //display_name public String artist; //艺术家 public int resId ; public String url; //路径 public long time; //时长 public long size; //字节 public String album; //唱片 public int musicId; public int albumId; public String fileName; public Music(){} public Music(String name,int resId,String artist,long size,String album,int musicId,int albumId,String fileName,String url,long time){ super(); this.name = name; this.resId = resId; this.artist = artist; this.size = size; this.album = album; this.musicId = musicId; this.albumId = albumId; this.fileName = fileName; this.url = url; this.time = time; } public void setFileName(String fileName){ this.fileName = fileName; } public String getFileName(){ return fileName; } public void setSize(long size){ this.size = size; } public long getSize(){ return size; } public void setAlbumId(int albumId){ this.albumId = albumId; } public int getAlbumId(){ return albumId; } public void setMusicId(int musicId){ this.musicId = musicId; } public int getMusicId(){ return musicId; } public void setAlbum(String album){ this.album = album; } public String getAlbum(){ return album; } public void setArtist(String artist){ this.artist = artist; } public String getArtist(){ return artist; } public void setNme(String name){ this.name=name; } public String getName(){ return name; } public void setResId(int resId){ this.resId=resId; } public int getResId(){ return resId; } public void setUrl(String url){ this.url = url; } public String getUrl(){ return url; } public void setTime(long time){ this.time = time; } public long getTime(){ return time; } }
下面是service,mp写在了这里,当然,也做成了静态,没办法,这么多地方要用到他的数据。。。
package xiamusic.com.yinyuejie.service; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.support.annotation.Nullable; import java.io.IOException; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import xiamusic.com.yinyuejie.R; import xiamusic.com.yinyuejie.music.Music; import xiamusic.com.yinyuejie.util.Play_final; import static xiamusic.com.yinyuejie.activity.MusicActivity.img_artist; import static xiamusic.com.yinyuejie.activity.MusicActivity.img_musicPause; import static xiamusic.com.yinyuejie.util.PhotoUtil.rotateImg; import static xiamusic.com.yinyuejie.util.PhotoUtil.scanFile_Crop_imageView; /** * Created by Administrator on 2018/2/28. */ public class MyService extends Service { public static List<Music> play_ing_music; public static MediaPlayer mp; public static int FLAGS = Play_final.NoONE_MUSIC; public static int play_id ; @Override public void onCreate() { super.onCreate(); mp = new MediaPlayer(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { int i = intent.getIntExtra("cmd", -1); switch (i) { case Play_final.PLAY: Uri uri = intent.getData(); readyPlay(uri); break; case Play_final.PAUSE: pause(); break; case Play_final.SUIJI: readyPlay(intent.getData()); handler.post(runnable); if (FLAGS == Play_final.NoONE_MUSIC){ suiJi(); } break; case Play_final.STOPPLAY: mp.stop(); mp.reset(); //让他空闲就行,否则点暂停会挂掉。 break; case Play_final.UPDATA_PIC : if (mp.isPlaying()){ handler.post(runnable); img_musicPause.setImageResource(R.drawable.pause_fill); } if (!mp.isPlaying()){ img_musicPause.setImageResource(R.drawable.player_btn); } break; } return super.onStartCommand(intent, flags, startId); } public void suiJi(){ mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { play_id = (int) Math.floor((Math.random() * play_ing_music.size())); // ThreadLocalRandom.current().nextInt(0,play_ing_music.size()); try { mp.reset(); mp.setDataSource(play_ing_music.get(play_id).getUrl()); mp.prepare(); } catch (IOException e) { e.printStackTrace(); } mp.start(); handler.post(runnable); } }); } Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { scanFile_Crop_imageView(play_ing_music.get(play_id).getArtist(),img_artist); int mss = mp.getDuration(); int aa = mss / 360; int bb = aa * 360; rotateImg(img_artist, bb / 100, mss); } }; private void readyPlay(Uri uri) { mp.reset(); //先让他重置,空闲 try { mp.setDataSource(this, uri); } catch (IOException e) { e.printStackTrace(); } try { mp.prepare(); } catch (IOException e) { e.printStackTrace(); } mp.start(); } //------------------------------------下面是暂停逻辑--------------------------- private void pause() { if (mp.isPlaying()) { mp.pause(); img_musicPause.setImageResource(R.drawable.player_btn); return; } if (!mp.isPlaying()) { mp.start(); img_musicPause.setImageResource(R.drawable.pause_fill); } } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }
下面是几个工具类和数据库
package xiamusic.com.yinyuejie.util; import android.Manifest; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.provider.MediaStore; import android.support.v4.app.ActivityCompat; import android.widget.Toast; import com.github.promeg.pinyinhelper.Pinyin; import java.util.ArrayList; import java.util.List; import xiamusic.com.yinyuejie.music.Artist; import xiamusic.com.yinyuejie.music.Music; /** * Created by Administrator on 2018/2/28. */ public class DataUtil { private MySQLiteOpenHelper helper; public DataUtil(Context context){ helper = new MySQLiteOpenHelper(context); } public void addMusic(String name,String artist,String album,String url,String fileName,int musicId,int albumId,long size,long time,long resId){ SQLiteDatabase db; db = helper.getWritableDatabase(); db.execSQL("insert into music00(name,artist,album,url,fileName,musicId,albumId,size,time,resId) values(?,?,?,?,?,?,?,?,?,?)", new Object[]{name,artist,album,url,fileName,musicId,albumId,size,time,resId}); db.close(); } public void addMusicLove(String name,String artist,String album,String url){ SQLiteDatabase db; db = helper.getWritableDatabase(); db.execSQL("insert into musiclove(name,artist,album,url) values(?,?,?,?)", new Object[]{name,artist,album,url}); db.close(); } public void deleteLoveOne(String name){ SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("delete from musiclove where name=?",new Object[]{name}); db.close(); } public void resetMusic_SQL(){ SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("delete from music00"); db.close(); } public void resetMusiclove(){ SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("delete from musiclove"); db.close(); } public List<Music> scan_Love_list(){ //返回一个列表 SQLiteDatabase db = helper.getReadableDatabase(); List<Music> loveList = new ArrayList<>(); @SuppressLint("Recycle") Cursor cursor = db.rawQuery("select * from musiclove",null); while (cursor.moveToNext()){ Music music = new Music(); music.name = cursor.getString(1); music.artist = cursor.getString(2); music.album = cursor.getString(3); music.url = cursor.getString(4); //五列是url,是从音乐中点击喜欢,到数据库中的 loveList.add(music); } db.close(); return loveList; } //------------------------------------------下面的扫描很重要------------------------------------------------------------ public List<Music> scan(Context context){ //扫描本地音乐,返回一个列表,这个很重要。 List<Music> musicList = new ArrayList<>(); ContentResolver cr = context.getContentResolver(); @SuppressLint("Recycle") Cursor cursor = cr.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null,null,MediaStore.Audio.AudioColumns.IS_MUSIC); assert cursor != null; while (cursor.moveToNext()){ Music music = new Music(); music.name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); music.fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); music.url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); music.time = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); music.album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)); music.artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); //-------- music.musicId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)); music.albumId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)); music.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)); //------- musicList.add(music); } cursor.close(); return musicList; } //-----------------------------------以上扫描很重要---------------------------------------------------------------------------- /** * * @param */ //----------------------------以下是基本没用的-------------------------------------------------------------------------------------------- public void scanLocal_SQL(Context context){ //扫描本地音乐入music00数据库 // resetMusic_SQL(); ContentResolver cr = context.getContentResolver(); @SuppressLint("Recycle") Cursor cursor = cr.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null,null,MediaStore.Audio.AudioColumns.IS_MUSIC); assert cursor != null; while (cursor.moveToNext()){ String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)); String fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); String url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); long time = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)); String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); int musicId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)); int albumId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)); long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)); long resId = 1; addMusic( name, artist, album, url, fileName, musicId, albumId, size, time,resId); } cursor.close(); } public List<Music> scanSQL_list(){ //扫描总库返回一个列表 SQLiteDatabase db = helper.getReadableDatabase(); List<Music> sqllist = new ArrayList<>(); @SuppressLint("Recycle") Cursor cursor = db.rawQuery("select * from music00",null); while (cursor.moveToNext()) { Music music = new Music(); music.name = cursor.getString(1); music.artist = cursor.getString(2); music.album = cursor.getString(3); music.url = cursor.getString(4); music.fileName = cursor.getString(5); music.musicId = cursor.getInt(6); music.albumId = cursor.getInt(7); music.size = cursor.getLong(8); music.time = cursor.getLong(9); sqllist.add(music); } db.close(); return sqllist; } /** * -----------------------------------以上基本用不到------------------------------------------------------------------------------------------- */ public List<Artist> getArtist(Context context){ ContentResolver cr = context.getContentResolver(); @SuppressLint("Recycle") Cursor cursor = cr.query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, null,null,null,null); List<Artist> artistList = new ArrayList<>(); assert cursor != null; while (cursor.moveToNext()){ Artist artist = new Artist(); artist.albumCont = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.NUMBER_OF_ALBUMS)); artist.artist = cursor.getString(1); //artist.artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.ARTIST)); artist.songCont = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.NUMBER_OF_TRACKS)); artist.artistId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists._ID)); artistList.add(artist); } return artistList; } static void eqPermission(Context context){ int permission = ActivityCompat.checkSelfPermission(context, Manifest.permission. WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { Toast.makeText(context,"请开启存储卡读写权限",Toast.LENGTH_SHORT).show(); return; } } public static Boolean displayAA(List<Music> list,int position) { StringBuilder sb = new StringBuilder(26); for (int i = 0; i < list.size(); i++) { String name = list.get(i).getName(); String pinyin = Pinyin.toPinyin(name.charAt(0)); String pp = pinyin.substring(0, 1); sb.append(pp); } int A = sb.indexOf("A");int B = sb.indexOf("B"); int C = sb.indexOf("C");int D = sb.indexOf("D"); int E = sb.indexOf("E"); int F = sb.indexOf("F");int G = sb.indexOf("G");int H = sb.indexOf("H"); int I = sb.indexOf("I");int J = sb.indexOf("J"); int K = sb.indexOf("K");int L = sb.indexOf("L");int M = sb.indexOf("M"); int N = sb.indexOf("N");int O = sb.indexOf("O"); int P = sb.indexOf("P");int Q = sb.indexOf("Q");int R = sb.indexOf("R"); int S = sb.indexOf("S");int T = sb.indexOf("T"); int U = sb.indexOf("U");int V = sb.indexOf("V");int W = sb.indexOf("W"); int X = sb.indexOf("X");int Y = sb.indexOf("Y"); int Z = sb.indexOf("Z"); if (position ==A ||position ==B ||position ==C ||position ==D ||position ==E ||position ==F ||position ==G ||position ==H ||position ==I ||position ==J ||position ==K ||position ==L ||position ==M ||position ==N ||position ==O ||position ==P ||position ==Q || position ==R ||position ==S ||position ==T ||position ==U ||position ==V ||position ==W ||position ==X ||position ==Y || position ==Z ){ return true; }else{ return false; } } public static int[] abc_index(List<Music> list){ StringBuilder sb = new StringBuilder(26); for (int i = 0; i< list.size(); i++){ String name = list.get(i).getName(); String pinyin = Pinyin.toPinyin(name.charAt(0)); String pp = pinyin.substring(0,1); sb.append(pp); } int A = sb.indexOf("A");int B = sb.indexOf("B"); int C = sb.indexOf("C");int D = sb.indexOf("D"); int E = sb.indexOf("E"); int F = sb.indexOf("F");int G = sb.indexOf("G");int H = sb.indexOf("H"); int I = sb.indexOf("I");int J = sb.indexOf("J"); int K = sb.indexOf("K");int L = sb.indexOf("L");int M = sb.indexOf("M"); int N = sb.indexOf("N");int O = sb.indexOf("O"); int P = sb.indexOf("P");int Q = sb.indexOf("Q");int R = sb.indexOf("R"); int S = sb.indexOf("S");int T = sb.indexOf("T"); int U = sb.indexOf("U");int V = sb.indexOf("V");int W = sb.indexOf("W"); int X = sb.indexOf("X");int Y = sb.indexOf("Y"); int Z = sb.indexOf("Z"); int[] abc_z = {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z}; return abc_z; } }
package xiamusic.com.yinyuejie.util; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; import android.text.format.DateUtils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Administrator on 2018/3/6. */ public class LrcEntry implements Comparable<LrcEntry> { private long time; private String text; private StaticLayout staticLayout; private float offset = Float.MIN_VALUE; private LrcEntry(long time, String text) { this.time = time; this.text = text; } public void init(TextPaint paint, int width) { staticLayout = new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_CENTER, 1f, 0f, false); } public long getTime() { return time; } public StaticLayout getStaticLayout() { return staticLayout; } public int getHeight() { if (staticLayout == null) { return 0; } return staticLayout.getHeight(); } public float getOffset() { return offset; } public void setOffset(float offset) { this.offset = offset; } @Override public int compareTo(LrcEntry entry) { if (entry == null) { return -1; } return (int) (time - entry.getTime()); } public static List<LrcEntry> parseLrc(File lrcFile) { if (lrcFile == null || !lrcFile.exists()) { return null; } List<LrcEntry> entryList = new ArrayList<>(); try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(lrcFile), "gbk")); String line; while ((line = br.readLine()) != null) { List<LrcEntry> list = parseLine(line); if (list != null && !list.isEmpty()) { entryList.addAll(list); } } br.close(); } catch (IOException e) { e.printStackTrace(); } Collections.sort(entryList); return entryList; } public static List<LrcEntry> parseLrc(String lrcText) { if (TextUtils.isEmpty(lrcText)) { return null; } List<LrcEntry> entryList = new ArrayList<>(); String[] array = lrcText.split("\\n"); for (String line : array) { List<LrcEntry> list = parseLine(line); if (list != null && !list.isEmpty()) { entryList.addAll(list); } } Collections.sort(entryList); return entryList; } private static List<LrcEntry> parseLine(String line) { if (TextUtils.isEmpty(line)) { return null; } line = line.trim(); Matcher lineMatcher = Pattern.compile("((\\[\\d\\d:\\d\\d\\.\\d\\d\\])+)(.+)").matcher(line); if (!lineMatcher.matches()) { return null; } String times = lineMatcher.group(1); String text = lineMatcher.group(3); List<LrcEntry> entryList = new ArrayList<>(); Matcher timeMatcher = Pattern.compile("\\[(\\d\\d):(\\d\\d)\\.(\\d\\d)\\]").matcher(times); while (timeMatcher.find()) { long min = Long.parseLong(timeMatcher.group(1)); long sec = Long.parseLong(timeMatcher.group(2)); long mil = Long.parseLong(timeMatcher.group(3)); long time = min * DateUtils.MINUTE_IN_MILLIS + sec * DateUtils.SECOND_IN_MILLIS + mil * 10; entryList.add(new LrcEntry(time, text)); } return entryList; } }
package xiamusic.com.yinyuejie.util; import android.content.Context; import android.text.format.DateUtils; import android.util.Log; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import xiamusic.com.yinyuejie.music.LRC; /** * Created by Administrator on 2018/3/4. */ public class LrcUtil { private List<LRC> lrcLists = new ArrayList<>(); private Context context; public LrcUtil(Context context){ this.context = context; } public List<LRC> readLrc_list(String path) { InputStream inputStream; try { inputStream = new FileInputStream(path); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "gbk")); String str = null; //逐行解析 while ((str = reader.readLine()) != null) { if (!str.equals("")) { decodeLine(str); } } //全部解析完后,设置lrcLists return lrcLists; } catch (FileNotFoundException e) { e.printStackTrace(); LRC lrc = new LRC(); //设置时间点和内容的映射 lrc.setContent("歌词文件没发现!"); lrcLists.add(lrc); return lrcLists; } catch (IOException e) { e.printStackTrace(); LRC lrcList = new LRC(); //设置时间点和内容的映射 lrcList.setContent("木有读取到歌词!"); // lrcLists.add(lrcList); //可有可无的。。。 return lrcLists; } } /** * 单行解析 */ private LRC decodeLine(String str) { LRC lrc = new LRC(); long currentTime = 0; String currentContent; String timeflag = "\\[(\\d{1,2}:\\d{1,2}\\.\\d{1,2})\\]|\\[(\\d{1,2}:\\d{1,2})\\]"; Pattern pattern = Pattern.compile(timeflag); Matcher matcher = pattern.matcher(str); //如果存在匹配项则执行如下操作 while (matcher.find()) { //得到匹配的内容 int groupCount = matcher.groupCount(); for (int index = 0; index < groupCount; index++) { String timeStr = matcher.group(index); if (index == 0) { //将第二组中的内容设置为当前的一个时间点 currentTime = str2Long(timeStr.substring(1, timeStr.length() - 1)); } } //得到时间点后的内容 String[] content = pattern.split(str); //将内容设置为当前内容,需要判断只出现时间的情况,没有内容的情况 if (content.length == 0) { currentContent = ""; } else { currentContent = content[content.length - 1]; } lrc.setCurrentTime(currentTime); //一句的对象 lrc.setContent(currentContent); lrcLists.add(lrc); } return lrc; } private long str2Long(String timeStr) { //将时间格式为xx:xx.xx,返回的long要求以毫秒为单位 Log.i("", "timeStr=" + timeStr); String[] s = timeStr.split("\\:"); int min = Integer.parseInt(s[0]); int sec = 0; int mill = 0; if (s[1].contains(".")) { String[] ss = s[1].split("\\."); sec = Integer.parseInt(ss[0]); mill = Integer.parseInt(ss[1]); Log.i("", "s[0]=" + s[0] + "s[1]" + s[1] + "ss[0]=" + ss[0] + "ss[1]=" + ss[1]); } else { sec = Integer.parseInt(s[1]); Log.i("", "s[0]=" + s[0] + "s[1]" + s[1]); } //时间的组成 return min * 60 * 1000 + sec * 1000 + mill * 10; } /** *------------------------------------------------------------------------------------------------------------------------------------------------- */ public static String formatTime(long milli) { int m = (int) (milli / DateUtils.MINUTE_IN_MILLIS); int s = (int) ((milli / DateUtils.SECOND_IN_MILLIS) % 60); String mm = String.format(Locale.getDefault(), "%02d", m); String ss = String.format(Locale.getDefault(), "%02d", s); return mm + ":" + ss; } public static String StringFilter(String str)throws PatternSyntaxException { // String regEx = "[^a-zA-Z0-9]"; // 只允许字母和数字 // 清除掉所有特殊字符(除了~之外) String regEx = "[0-9a-z_A-Z_<_>_?_)_(]"; Pattern pattern = Pattern.compile(regEx); Matcher matcher = pattern.matcher(str); return matcher.replaceAll("").trim(); } public static String xx_xxChar(String str)throws PatternSyntaxException { // String regEx = "[^a-zA-Z0-9]"; // 只允许字母和数字 // 清除掉所有特殊字符(除了~之外) String regEx = "[<_>]"; Pattern pattern = Pattern.compile(regEx); Matcher matcher = pattern.matcher(str); return matcher.replaceAll("").trim(); } }
package xiamusic.com.yinyuejie.util; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by Administrator on 2018/2/28. */ public class MySQLiteOpenHelper extends SQLiteOpenHelper { public MySQLiteOpenHelper(Context context) { super(context, "xin.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table music00(_id integer primary key autoincrement," + "name text not null,artist text not null,album text not null,url text not null,fileName text not null,musicId varchar not null," + "albumId text not null,size text not null,time text not null,resId text not null)"); db.execSQL("create table musiclove(_id integer primary key autoincrement," + "name text not null,artist text not null,album text not null,url text not null)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
package xiamusic.com.yinyuejie.util; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.os.Environment; import android.view.View; import android.widget.ImageView; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import static xiamusic.com.yinyuejie.activity.MusicActivity.filePath; /** * Created by Administrator on 2018/2/28. */ public class PhotoUtil { Context context; public PhotoUtil(Context context){ this.context = context; } public static void scanFile_Crop_imageView(String name,ImageView imageView) { // File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); File file = filePath; File[] files = file.listFiles(); for (File item : files) { if (item.getName().equals(name+".jpg")) { String path = item.getPath(); Bitmap bitmap = BitmapFactory.decodeFile(path);Bitmap bitmap1 =CropBitmap(bitmap); if (bitmap1!=null){ imageView.setImageBitmap(bitmap1); } } } } public static Bitmap scan_Crop_Pic(String name){ //扫图成圆返回 String path; Bitmap b = null; File[] files = filePath.listFiles(); for (File item : files) { if (item.getName().equals(name+".jpg")) { path = item.getPath(); if (!path.isEmpty()){ b = CropBitmap(BitmapFactory.decodeFile(path)); } } } return b; } public static Bitmap scanImage(String name){ //扫图 String path; Bitmap b = null; File[] files = filePath.listFiles(); for (File item : files) { if (item.getName().equals(name+".jpg")) { path = item.getPath(); if (!path.isEmpty()){ b = BitmapFactory.decodeFile(path); } } } return b; } public void saveBmp(Bitmap bmp, String fileName){ //传入想保存成什么名字 // File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); String dir = context.getExternalFilesDir(null).getPath(); //data下面自已包里生成个文件夹files 能保存文件. File file = new File(dir,fileName); try { FileOutputStream fos = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.PNG,90,fos); try { fos.flush(); } catch (IOException e) { e.printStackTrace(); } try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } } public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); //画笔默认为FILL ,实心圆 final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); //左上右下 final RectF rectF = new RectF(rect); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); //一张透明画布。 paint.setColor(0xff424242); //画笔全不透明 canvas.drawRoundRect(rectF, roundPx, roundPx, paint); //rx,ry,两个方向的半径 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, 0, 0, paint); //左 上 return output; /** * 图像混合模式,SRC_IN只在相交的位置绘制 * 相交的位置是圆的内部,外部不绘制,仍是透明色。。。 */ } public static Bitmap CropBitmap(Bitmap bitmap){ //裁剪圆形图,无论高宽。 Paint paint = new Paint(); int w = bitmap.getWidth(); int h = bitmap.getHeight(); if (w > h){ w = h; } if (h > w){ h = w; } Bitmap output = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Rect rect = new Rect(0, 0, w, h); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); int x ; if (w > h){ x = h; }else { x = w; } canvas.drawCircle(x / 2, x / 2, x/2 , paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } static void alphaChanged(ImageView iv,float sta,float sto,int t,int ci){ ObjectAnimator oo = ObjectAnimator.ofFloat(iv, "alpha", sta, sto); oo.setDuration(t); oo.setRepeatCount(ci); oo.start(); } public static void rotateImg(View iv, float c, int s) { final ObjectAnimator op = ObjectAnimator.ofFloat(iv, "rotation", 0f, c);//旋转的总圈数, op.setDuration(s);//总时间长度 op.start(); //有cancel pause方法,end方法直接跳到最后一帧. } public static void rotateView(View iv, float cstart,float cstop, int s) { final ObjectAnimator op = ObjectAnimator.ofFloat(iv, "rotation", cstart, cstop);//旋转的总圈数, op.setDuration(s);//总时间长度 op.start(); //有cancel pause方法,end方法直接跳到最后一帧. } public static void suoFang(ImageView imView, float sta, float sto, int t) { AnimatorSet st = new AnimatorSet(); ObjectAnimator x1 = ObjectAnimator.ofFloat(imView, "scaleX", sta, sto); ObjectAnimator y1 = ObjectAnimator.ofFloat(imView, "scaleY", sta, sto); st.play(x1).with(y1); st.setDuration(t); st.start(); } public void scanPic_Crop_Save(){ File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); File[] files = dir.listFiles(); for (File item : files){ String path = item.getPath(); String name = item.getName(); Bitmap bitmap = BitmapFactory.decodeFile(path); if (bitmap != null){ Bitmap b = CropBitmap(bitmap); saveBmp(b,name); } } } }
package xiamusic.com.yinyuejie.util; /** * Created by Administrator on 2018/2/28. */ public class Play_final { public static final int PLAY = 1; public static final int PAUSE = 2; public static final int STOPPLAY=4; public static final int SUIJI = 5; public static final int UPDATA_PIC = 6; public static final int ONE_MUSIC = 7; public static final int NoONE_MUSIC = 8; public static final int H_SOUGE = 11; public static final int QIE_GE = 12; public static final int ROTATE = 13; // static final int TIAO_SHI=100; }
最后是歌词view,伪频谱view以及侧栏view。
package xiamusic.com.yinyuejie.view; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Looper; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.animation.LinearInterpolator; import android.widget.Scroller; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; import xiamusic.com.yinyuejie.util.LrcEntry; import xiamusic.com.yinyuejie.util.LrcUtil; import xiamusic.com.yinyuejie.R; /** * Created by Administrator on 2018/3/4. */ public class LrcView extends View { private static final long ADJUST_DURATION = 100; private static final long TIMELINE_KEEP_TIME = 4 * DateUtils.SECOND_IN_MILLIS; public List<LrcEntry> mLrcEntryList = new ArrayList<>(); private TextPaint mLrcPaint = new TextPaint(); private TextPaint mTimePaint = new TextPaint(); private Paint.FontMetrics mTimeFontMetrics; private Drawable mPlayDrawable; private float mDividerHeight; private long mAnimationDuration; private int mNormalTextColor; private int mCurrentTextColor; private int mTimelineTextColor; private int mTimelineColor; private int mTimeTextColor; private int mDrawableWidth; private int mTimeTextWidth; private String mDefaultLabel; private float mLrcPadding; private OnPlayClickListener mOnPlayClickListener; private ValueAnimator mAnimator; private GestureDetector mGestureDetector; private Scroller mScroller; private float mOffset; private int mCurrentLine; private Object mFlag; private boolean isShowTimeline; private boolean isTouching; private boolean isFling; /** * 播放按钮点击监听器,点击后应该跳转到指定播放位置 */ public interface OnPlayClickListener { /** * 播放按钮被点击,应该跳转到指定播放位置 * * @return 是否成功消费该事件,如果成功消费,则会更新UI */ boolean onPlayClick(long time); } public LrcView(Context context) { this(context, null); } public LrcView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public LrcView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.LrcView); float lrcTextSize = ta.getDimension(R.styleable.LrcView_lrcTextSize, getResources().getDimension(R.dimen.lrc_text_size)); mDividerHeight = ta.getDimension(R.styleable.LrcView_lrcDividerHeight, getResources().getDimension(R.dimen.lrc_divider_height)); int defDuration = getResources().getInteger(R.integer.lrc_animation_duration); mAnimationDuration = ta.getInt(R.styleable.LrcView_lrcAnimationDuration, defDuration); mAnimationDuration = (mAnimationDuration < 0) ? defDuration : mAnimationDuration; mNormalTextColor = ta.getColor(R.styleable.LrcView_lrcNormalTextColor, getResources().getColor(R.color.lrc_normal_text_color)); mCurrentTextColor = ta.getColor(R.styleable.LrcView_lrcCurrentTextColor, getResources().getColor(R.color.lrc_current_text_color)); mTimelineTextColor = ta.getColor(R.styleable.LrcView_lrcTimelineTextColor, getResources().getColor(R.color.lrc_timeline_text_color)); mDefaultLabel = ta.getString(R.styleable.LrcView_lrcLabel); mDefaultLabel = TextUtils.isEmpty(mDefaultLabel) ? getContext().getString(R.string.lrc_label) : mDefaultLabel; mLrcPadding = ta.getDimension(R.styleable.LrcView_lrcPadding, 0); mTimelineColor = ta.getColor(R.styleable.LrcView_lrcTimelineColor, getResources().getColor(R.color.lrc_timeline_color)); float timelineHeight = ta.getDimension(R.styleable.LrcView_lrcTimelineHeight, getResources().getDimension(R.dimen.lrc_timeline_height)); mPlayDrawable = ta.getDrawable(R.styleable.LrcView_lrcPlayDrawable); mPlayDrawable = (mPlayDrawable == null) ? getResources().getDrawable(R.drawable.lrc_play) : mPlayDrawable; mTimeTextColor = ta.getColor(R.styleable.LrcView_lrcTimeTextColor, getResources().getColor(R.color.lrc_time_text_color)); float timeTextSize = ta.getDimension(R.styleable.LrcView_lrcTimeTextSize, getResources().getDimension(R.dimen.lrc_time_text_size)); ta.recycle(); mDrawableWidth = (int) getResources().getDimension(R.dimen.lrc_drawable_width); mTimeTextWidth = (int) getResources().getDimension(R.dimen.lrc_time_width); mLrcPaint.setAntiAlias(true); mLrcPaint.setTextSize(lrcTextSize); mLrcPaint.setTextAlign(Paint.Align.LEFT); mTimePaint.setAntiAlias(true); mTimePaint.setTextSize(timeTextSize); mTimePaint.setTextAlign(Paint.Align.CENTER); //noinspection SuspiciousNameCombination mTimePaint.setStrokeWidth(timelineHeight); mTimePaint.setStrokeCap(Paint.Cap.ROUND); mTimeFontMetrics = mTimePaint.getFontMetrics(); mGestureDetector = new GestureDetector(getContext(), mSimpleOnGestureListener); mGestureDetector.setIsLongpressEnabled(false); mScroller = new Scroller(getContext()); } public void setNormalColor(int normalColor) { mNormalTextColor = normalColor; postInvalidate(); } public void setCurrentColor(int currentColor) { mCurrentTextColor = currentColor; postInvalidate(); } public void setTimelineTextColor(int timelineTextColor) { mTimelineTextColor = timelineTextColor; postInvalidate(); } public void setTimelineColor(int timelineColor) { mTimelineColor = timelineColor; postInvalidate(); } public void setTimeTextColor(int timeTextColor) { mTimeTextColor = timeTextColor; postInvalidate(); } /** * 设置播放按钮点击监听器 * * @param onPlayClickListener 如果为非 null ,则**歌词拖动功能,否则将将禁用歌词拖动功能 */ public void setOnPlayClickListener(OnPlayClickListener onPlayClickListener) { mOnPlayClickListener = onPlayClickListener; } /** * 设置歌词为空时屏幕*显示的文字,如“暂无歌词” */ public void setLabel(final String label) { runOnUi(new Runnable() { @Override public void run() { mDefaultLabel = label; invalidate(); } }); } /** * 加载歌词文件 * * @param lrcFile 歌词文件 */ public void loadLrc(final File lrcFile) { runOnUi(new Runnable() { @Override public void run() { reset(); setFlag(lrcFile); new AsyncTask<File, Integer, List<LrcEntry>>() { @Override protected List<LrcEntry> doInBackground(File... params) { return LrcEntry.parseLrc(params[0]); } @Override protected void onPostExecute(List<LrcEntry> lrcEntries) { if (getFlag() == lrcFile) { onLrcLoaded(lrcEntries); setFlag(null); } } }.execute(lrcFile); } }); } /** * 加载歌词文件 * * @param lrcText 歌词文本 */ public void loadLrc(final String lrcText) { runOnUi(new Runnable() { @Override public void run() { reset(); setFlag(lrcText); new AsyncTask<String, Integer, List<LrcEntry>>() { @Override protected List<LrcEntry> doInBackground(String... params) { return LrcEntry.parseLrc(params[0]); } @Override protected void onPostExecute(List<LrcEntry> lrcEntries) { if (getFlag() == lrcText) { onLrcLoaded(lrcEntries); setFlag(null); } } }.execute(lrcText); } }); } /** * 歌词是否有效 * * @return true,如果歌词有效,否则false */ public boolean hasLrc() { return !mLrcEntryList.isEmpty(); } /** * 刷新歌词 * * @param time 当前播放时间 */ public void updateTime(final long time) { runOnUi(new Runnable() { @Override public void run() { if (!hasLrc()) { return; } int line = findShowLine(time); if (line != mCurrentLine) { mCurrentLine = line; if (!isShowTimeline) { scrollTo(line); } else { invalidate(); } } } }); } /** * 将歌词滚动到指定时间 * * @param time 指定的时间 * @deprecated 请使用 {@link #updateTime(long)} 代替 */ @Deprecated public void onDrag(long time) { updateTime(time); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { initEntryList(); int l = (mTimeTextWidth - mDrawableWidth) / 2; int t = getHeight() / 2 - mDrawableWidth / 2; int r = l + mDrawableWidth; int b = t + mDrawableWidth; mPlayDrawable.setBounds(l, t, r, b); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int centerY = getHeight() / 2; // 无歌词文件 if (!hasLrc()) { mLrcPaint.setColor(mCurrentTextColor); @SuppressLint("DrawAllocation") StaticLayout staticLayout = new StaticLayout(mDefaultLabel, mLrcPaint, (int) getLrcWidth(), Layout.Alignment.ALIGN_CENTER, 1f, 0f, false); drawText(canvas, staticLayout, centerY); return; } int centerLine = getCenterLine(); if (isShowTimeline) { mPlayDrawable.draw(canvas); mTimePaint.setColor(mTimelineColor); canvas.drawLine(mTimeTextWidth, centerY, getWidth() - mTimeTextWidth, centerY, mTimePaint); mTimePaint.setColor(mTimeTextColor); String timeText = LrcUtil.formatTime(mLrcEntryList.get(centerLine).getTime()); float timeX = getWidth() - mTimeTextWidth / 2; float timeY = centerY - (mTimeFontMetrics.descent + mTimeFontMetrics.ascent) / 2; canvas.drawText(timeText, timeX, timeY, mTimePaint); } canvas.translate(0, mOffset); float y = 0; for (int i = 0; i < mLrcEntryList.size(); i++) { if (i > 0) { y += (mLrcEntryList.get(i - 1).getHeight() + mLrcEntryList.get(i).getHeight()) / 2 + mDividerHeight; } if (i == mCurrentLine) { mLrcPaint.setColor(mCurrentTextColor); } else if (isShowTimeline && i == centerLine) { mLrcPaint.setColor(mTimelineTextColor); } else { mLrcPaint.setColor(mNormalTextColor); } drawText(canvas, mLrcEntryList.get(i).getStaticLayout(), y); } } /** * 画一行歌词 * * @param y 歌词中心 Y 坐标 */ private void drawText(Canvas canvas, StaticLayout staticLayout, float y) { canvas.save(); canvas.translate(mLrcPadding, y - staticLayout.getHeight() / 2); staticLayout.draw(canvas); canvas.restore(); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { isTouching = false; if (hasLrc() && !isFling) { adjustCenter(); postDelayed(hideTimelineRunnable, TIMELINE_KEEP_TIME); } } return mGestureDetector.onTouchEvent(event); } private GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { if (hasLrc() && mOnPlayClickListener != null) { mScroller.forceFinished(true); removeCallbacks(hideTimelineRunnable); isTouching = true; isShowTimeline = true; invalidate(); return true; } return super.onDown(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (hasLrc()) { mOffset += -distanceY; mOffset = Math.min(mOffset, getOffset(0)); mOffset = Math.max(mOffset, getOffset(mLrcEntryList.size() - 1)); invalidate(); return true; } return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (hasLrc()) { mScroller.fling(0, (int) mOffset, 0, (int) velocityY, 0, 0, (int) getOffset(mLrcEntryList.size() - 1), (int) getOffset(0)); isFling = true; return true; } return super.onFling(e1, e2, velocityX, velocityY); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { if (hasLrc() && isShowTimeline && mPlayDrawable.getBounds().contains((int) e.getX(), (int) e.getY())) { int centerLine = getCenterLine(); long centerLineTime = mLrcEntryList.get(centerLine).getTime(); // onPlayClick 消费了才更新 UI if (mOnPlayClickListener != null && mOnPlayClickListener.onPlayClick(centerLineTime)) { isShowTimeline = false; removeCallbacks(hideTimelineRunnable); mCurrentLine = centerLine; invalidate(); return true; } } return super.onSingleTapConfirmed(e); } }; private Runnable hideTimelineRunnable = new Runnable() { @Override public void run() { if (hasLrc() && isShowTimeline) { isShowTimeline = false; scrollTo(mCurrentLine); } } }; @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { mOffset = mScroller.getCurrY(); invalidate(); } if (isFling && mScroller.isFinished()) { isFling = false; if (hasLrc() && !isTouching) { adjustCenter(); postDelayed(hideTimelineRunnable, TIMELINE_KEEP_TIME); } } } @Override protected void onDetachedFromWindow() { removeCallbacks(hideTimelineRunnable); super.onDetachedFromWindow(); } private void onLrcLoaded(List<LrcEntry> entryList) { if (entryList != null && !entryList.isEmpty()) { mLrcEntryList.addAll(entryList); } initEntryList(); invalidate(); } private void initEntryList() { if (!hasLrc() || getWidth() == 0) { return; } Collections.sort(mLrcEntryList); for (LrcEntry lrcEntry : mLrcEntryList) { lrcEntry.init(mLrcPaint, (int) getLrcWidth()); } mOffset = getHeight() / 2; } private void reset() { endAnimation(); mScroller.forceFinished(true); isShowTimeline = false; isTouching = false; isFling = false; removeCallbacks(hideTimelineRunnable); mLrcEntryList.clear(); mOffset = 0; mCurrentLine = 0; invalidate(); } /** * 滚动到某一行 */ private void scrollTo(int line) { scrollTo(line, mAnimationDuration); } /** * 将中心行微调至正中心 */ private void adjustCenter() { scrollTo(getCenterLine(), ADJUST_DURATION); } private void scrollTo(int line, long duration) { float offset = getOffset(line); endAnimation(); mAnimator = ValueAnimator.ofFloat(mOffset, offset); mAnimator.setDuration(duration); mAnimator.setInterpolator(new LinearInterpolator()); mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mOffset = (float) animation.getAnimatedValue(); invalidate(); } }); mAnimator.start(); } private void endAnimation() { if (mAnimator != null && mAnimator.isRunning()) { mAnimator.end(); } } /** * 二分法查找当前时间应该显示的行数(最后一个 <= time 的行数) */ private int findShowLine(long time) { int left = 0; int right = mLrcEntryList.size(); while (left <= right) { int middle = (left + right) / 2; long middleTime = mLrcEntryList.get(middle).getTime(); if (time < middleTime) { right = middle - 1; } else { if (middle + 1 >= mLrcEntryList.size() || time < mLrcEntryList.get(middle + 1).getTime()) { return middle; } left = middle + 1; } } return 0; } private int getCenterLine() { int centerLine = 0; float minDistance = Float.MAX_VALUE; for (int i = 0; i < mLrcEntryList.size(); i++) { if (Math.abs(mOffset - getOffset(i)) < minDistance) { minDistance = Math.abs(mOffset - getOffset(i)); centerLine = i; } } return centerLine; } private float getOffset(int line) { if (mLrcEntryList.get(line).getOffset() == Float.MIN_VALUE) { float offset = getHeight() / 2; for (int i = 1; i <= line; i++) { offset -= (mLrcEntryList.get(i - 1).getHeight() + mLrcEntryList.get(i).getHeight()) / 2 + mDividerHeight; } mLrcEntryList.get(line).setOffset(offset); } return mLrcEntryList.get(line).getOffset(); } private float getLrcWidth() { return getWidth() - mLrcPadding * 2; } private void runOnUi(Runnable r) { if (Looper.myLooper() == Looper.getMainLooper()) { r.run(); } else { post(r); } } private Object getFlag() { return mFlag; } private void setFlag(Object flag) { this.mFlag = flag; } }
package xiamusic.com.yinyuejie.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; /** * Created by Administrator on 2018/3/13. */ public class Audio_View extends View { int width; int height; Paint p; public Audio_View(Context context) { super(context); } public Audio_View(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initView(); } public void initView(){ p = new Paint(); p.setStyle(Paint.Style.FILL); p.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int left = width/14; int w = 8; int right = left + w; int dx = w + 6; int a = (int)Math.floor(Math.random()*255); int r = (int)Math.floor(Math.random()*255); int g = (int)Math.floor(Math.random()*255); int b = (int)Math.floor(Math.random()*255); int cunt = (width - left*2)/dx; for(int i = 0; i<= cunt; i++) { p.setARGB(a,r,g,b); int bottom = (int)Math.floor(Math.random()*height); canvas.drawRect(left, height, right,bottom, p); left += dx; right += dx; a = (int)Math.floor(Math.random()*255); r = (int)Math.floor(Math.random()*255); g = (int)Math.floor(Math.random()*255); b = (int)Math.floor(Math.random()*255); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w; height = h; super.onSizeChanged(w, h, oldw, oldh); } }
package xiamusic.com.yinyuejie.view; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Typeface; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.TextView; import static xiamusic.com.yinyuejie.adapter.RvAdapterAllMusic.aaa; import static xiamusic.com.yinyuejie.fragment.Fragment_fill.recyclerView; /** * Created by Administrator on 2018/3/20. */ @SuppressLint("AppCompatCustomView") public class Sort_View extends TextView { Paint paint, paint2; Boolean isTouch = false; public static String[] str = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; public Sort_View(Context context) { super(context); init(); } public Sort_View(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public void init() { paint = new Paint(); paint.setAntiAlias(true); paint.setTextSize(40); paint.setARGB(255, 80, 80, 80); paint2 = new Paint(); paint2.setAntiAlias(true); paint2.setTextSize(80); paint2.setTypeface(Typeface.DEFAULT_BOLD); paint2.setARGB(200, 255, 40, 80); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float x, y; canvas.drawARGB(0, 0, 0, 0); float width = getWidth(); float height = getHeight(); for (int i = 0; i < str.length; i++) { x = width / 2 - paint.measureText(str[i]) / 2; y = height / str.length * (i + 0.75f); canvas.drawText(str[i], x, y, paint); } if (isTouch) { canvas.drawARGB(60, 0, 0, 0); float x2 = width / 2 - paint2.measureText(str[position]) / 2; float y2 = height / str.length * (position - 1); canvas.drawText(str[position], x2, y2, paint2); } } /** */ int p; int position; @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: try { // position = (int)(event.getY()/getHeight()*aaa.length); position = (int) ((event.getY() * 2 * aaa.length + 1) / (2 * aaa.length) * aaa.length / getHeight()); p = aaa[position]; recyclerView.scrollToPosition(p); //本来是放在activity中处理的 isTouch = true; invalidate(); } catch (RuntimeException e) { // } break; case MotionEvent.ACTION_MOVE: try { // position = (int)(event.getY()/getHeight()*aaa.length); position = (int) ((event.getY() * 2 * aaa.length + 1) / (2 * aaa.length) * aaa.length / getHeight()); p = aaa[position]; recyclerView.scrollToPosition(p); //本来是放在activity中处理的 isTouch = true; invalidate(); } catch (RuntimeException e) { // } break; case MotionEvent.ACTION_UP: isTouch = false; invalidate(); break; } //listener.viewTouchListener(p); // return super.onTouchEvent(event); return true; //静态放入fragment时,要返回真,不然事件会被认为没处理完,会向上传递,重绘view无法完成。 } } // public interface OnSort_viewTouchListener{ // void viewTouchListener(int position1); // } // public OnSort_viewTouchListener listener; // public void setOnSort_viewTouchListener(OnSort_viewTouchListener listener){ // this.listener = listener; // }
本来写了个内部接口,但是发现直接在此view里处理点击事件也是ok的,而更容易看逻辑。就把接口注掉了。
下面是用到的几个依赖
compile 'com.android.support:recyclerview-v7:26.1.0' compile 'com.android.support:design:26.1.0' compile 'com.jcodecraeer:xrecyclerview:1.5.9' compile 'com.android.support:palette-v7:26.1.0' compile 'com.github.promeg:tinypinyin:2.0.3'
最下面的是github上的一个汉字转拼音的。其它是android的支持包。
布局就不上了,没啥好说的。我看一下能不能上传完整包,可以的话就传上来。。