RTFSC (Read the fucking source code )才是生活中最重要的。
一、音乐播放器—listview
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
readStatus();//mloopway,mshuffle的值
View barView = findViewById(R.id.bar);
mBarTitle = (TextView) barView.findViewById(R.id.title);
mBarArtist = (TextView) barView.findViewById(R.id.artist);
mBarAlbum = (ImageView) barView.findViewById(R.id.album);
mBarPauseButton = (ImageButton) barView.findViewById(R.id.home_pauseButton);
mBarNextButton = (ImageButton) barView.findViewById(R.id.home_nextButton);
mBarPauseBackground = barView.findViewById(R.id.homebar_background);
mPaperTitleStrip = (PagerTitleStrip) findViewById(R.id.title_strip);
//设置tab栏字体
mPaperTitleStrip.setTextColor(Color.rgb(255, 255, 255));
mBarTitle.setHorizontallyScrolling(true);//走马灯
mBarTitle.setSelected(true);//切换背景显示
mBarArtist.setHorizontallyScrolling(true);
mBarArtist.setSelected(true);
enableButton(false, true);
// 弹出播放器界面
barView.setOnClickListener(this);
// 播放条暂停按钮事件监听器
mBarPauseButton.setOnClickListener(this);
// 播放条暂停按钮背景事件监听器
mBarPauseBackground.setOnClickListener(this);
// 播放条下一首事件监听器
mBarNextButton.setOnClickListener(this);
// 事件广播接受器
LocalBroadcastManager.getInstance(this).registerReceiver(mEventReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String event = intent.getStringExtra(AudioPlayService.EVENT_KEY);
if (event == null) {
return;
}
switch (event) {
case AudioPlayService.FINISHED_EVENT:
musicChange(true, false);
if (mPlayingIndex >= 0 && mPlayingIndex < mAdapterList.size()) {//size表示的应该是有多少首歌,mPlayingIndex表示的是当前播放到第多少首
mAdapterList.get(mPlayingIndex).notifyDataSetChanged();//用于增添减删后的更新
}
break;
case AudioPlayService.NEXT_EVENT:
musicChange(true, true);
if (mPlayingIndex >= 0 && mPlayingIndex < mAdapterList.size()) {
mAdapterList.get(mPlayingIndex).notifyDataSetChanged();
}
break;
case AudioPlayService.PREVIOUS_EVENT:
musicChange(false, true);
if (mPlayingIndex >= 0 && mPlayingIndex < mAdapterList.size()) {
mAdapterList.get(mPlayingIndex).notifyDataSetChanged();
}
break;
case AudioPlayService.PLAY_EVENT:
boolean isPlay = intent.getBooleanExtra(AudioPlayService.AUDIO_PLAY_NOW_BOOL, false);
if (isPlay) {
mBarPauseButton.setImageResource(R.drawable.pause_light);
mIsPlaying = true;
} else {
mBarPauseButton.setImageResource(R.drawable.play_light);
mIsPlaying = false;
}
enableButton(true);
break;
case AudioPlayService.PAUSE_EVENT:
mBarPauseButton.setImageResource(R.drawable.play_light);
mIsPlaying = false;
enableButton(true);
break;
case AudioPlayService.REPLAY_EVENT:
mBarPauseButton.setImageResource(R.drawable.pause_light);
mIsPlaying = true;
enableButton(true);
break;
case AudioPlayService.LIST_ORDER_EVENT:
mIsShuffle = intent.getBooleanExtra(AudioPlayService.LIST_SHUFFLE_BOOL, true);
if (mIsShuffle) {
shuffleAudioIndex(mListOfAudioItemList.get(mPlayingIndex), mLastPlay);
mLastIndex = 0;
}
saveStatus();
break;
case AudioPlayService.CHANGE_LOOP_EVENT:
mLoopWay = intent.getIntExtra(
AudioPlayService.LOOP_WAY_INT, AudioPlayService.LIST_NOT_LOOP);
saveStatus();
break;
}
}
}, new IntentFilter(AudioPlayService.BROADCAST_EVENT_FILTER));//?
// 权限分配
List<String> requestList = new ArrayList<>();
for (String permission : permissionArray) {//?
if (ActivityCompat.checkSelfPermission(this, permission)
!= PermissionChecker.PERMISSION_GRANTED) {
requestList.add(permission);
}
}
if (requestList.size() > 0) {
ActivityCompat.requestPermissions(this, requestList.toArray(new String[] {}),
PERMISSION_REQUEST_CODE);
} else {
init();
}
}
思路:1.首先使用readStatus()方法:sharedpreferences是android中最容易理解的数据存储技术,通过key-value存储轻量级的数据,这里用于读出mloopway,mshuffle的值。(mloopway用于判断循环方式,mshuffle用于判断是否歌单顺序被打乱)
2.将各个组件数据注册
3.设置一些样式,如走马灯,字体等,然后将bar中的title,artist设为可点击
4.调用enableButton(false,true)方法,将bar中播放暂停,下一首以及播放键的背景设为不可点击(setEnabled为false,该控件将不再响应点击、触摸以及键盘事件等,处于完全被禁用的状态,并且该控件会被重绘。)。同时若颜色是灰色且无法点击,将播放键的背景该为灰色,不满足条件改为红色。
5.将barview,播放条暂停按钮及背景,nextbutton设置监听器
6.用匿名类的方式设置广播监听接受器:所接受的intent,来源于AudioPlayerService的String:event。当传入时event为finished_evrnt时,调用musicChange()方法,如果符合条件,则通过list.get(int).notifyDataSetChanged();来更新歌单。若event传过来时为next_event,previous_event,则重复上述相同步骤。
若event传来时为play_event,接受boolean isPlay为String playNow代表的布尔值。如果为真,就改变bar的播放暂停键,再将表示正在播放的值mIsPlaying改为true。如果为假,同样改变图片,再把mIsPlaying改为false。调用enableButton(true),将刚刚设置为无法点击的各个组件设置为可以点击。
若event传来时的值为pause_event将bar的播放键图片改变,mIsPlaying改为false,调用enableButton(true)方法。
若event传来的值为pause_event将bar的播放键图片改变,mIsPlaying改为false,调用enableButton(true)方法。
若event传来的值为replay_event将bar的播放键图片改变,mIsPlaying改为true,调用enableButton(true)方法。
若event传来的值为list_order_event,将决定是否打乱顺序的mIsShuffle接受从AudioPlayerService的值,如果mIsShuffle为真那么就调用shuffleAudioIndex()方法,把indexList乱序后,再将值=playIndex的项交换到开头。令mLastIndex=0.调用saveStatus()方法。
若event传来的是change_loop_event,将决定循环方式的mLoopWay接受从AudioPlayerService的数据。调用saveStatu()方法。
7.原文中},IntentFilter(AudioPlayerService.BROADCAST_EVENTFILTER));的作用不是很明白。
8.接下来是权限分配:
List<String> requestList = new ArrayList<>();
将requestList设置为权限的List,然后遍历permissionArray数组中的权限,检查是否授权。((ActivityCompat.checkSelfPermission(this, permission):在运行时检查权限。)(PERMISSION_GRANTED
: 已授权),如果未授权则往requestList添加权限(String)。
若requestList的权限大于0,向系统请求权限,反之则初始化列表。
9.init():
初始化titles数组,添加"Audio","Artist","Album"。
启动排序比较器:Comparator<Audio>,然后进行拼音排序。(研究)
10.转换:定义接口AudioToAudioItem[] trans,重定义接口中的apply方法。
11.定义viewList,titleList,mAdapter,mListOfAudioItemList.
12.用排序比较器得来的数据cmps[i],初始化list,再用接口转换中apply的方法,得到加入作者等数据的itemlist,再把itemList的数据加入mListOfAudioItemList中。
13.引入自定义的适配器AudioListAdapter,new adapter对象,将数据绑定list_music的布局中
mAdapterList.add(adapter).。
14.定义listView对象,listView.setAdapter(adapter);
:把数据映射到界面里边。
15.设置listView的点击事件:mPlayingIndex=index;调用playAudio()方法,再用notifyDataSetChanged()刷新。
16.viewList.add(listView); titleList.add(titles[i]);
17.viewPager.setOffscreenPageLimit():限定预加载的页面个数.,仔设置适配器实现页面和数据的绑定
18.其中pause()、playaudio()等功能需要通过AudioPlayService实现