生活随笔
收集整理的這篇文章主要介紹了
【android】音乐播放器之UI设计的点点滴滴
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
? ? ? ?學(xué)習(xí)Android有一個(gè)多月,看完了《第一行代碼》以及mars老師的第一期視頻通過(guò)音樂(lè)播放器小項(xiàng)目加深對(duì)知識(shí)點(diǎn)的理解。從本文開始,將詳細(xì)的介紹簡(jiǎn)單仿多米音樂(lè)播放器的實(shí)現(xiàn),以及網(wǎng)絡(luò)解析數(shù)據(jù)獲取百度音樂(lè)最新排行音樂(lè)以及下載功能。
? ? ? ??功能介紹如下:?? ?
? ? ? ??1、獲取本地歌曲列表,實(shí)現(xiàn)歌曲播放功能。?
? ? ? ? 2、利用jsoup解析網(wǎng)頁(yè)數(shù)據(jù),從網(wǎng)絡(luò)獲取歌曲列表,同時(shí)實(shí)現(xiàn)歌曲和歌詞下載到手機(jī)本地的功能。?
? ? ? ? 3、通知欄提醒,實(shí)現(xiàn)仿QQ音樂(lè)播放器的通知欄功能.?? ? ?
? ? ???涉及的技術(shù)有:?
? ? ? ?1、jsoup解析網(wǎng)絡(luò)網(wǎng)頁(yè),從而獲取需要的數(shù)據(jù)?
? ? ? ?2、android中訪問(wèn)網(wǎng)絡(luò),獲取文件到本地的網(wǎng)絡(luò)請(qǐng)求技術(shù),以及下載文件到本地實(shí)現(xiàn)斷點(diǎn)下載?
? ? ? ?3、線程池?
? ? ? ?4、圖片緩存?
? ? ? ?5、service一直在后臺(tái)運(yùn)行?
? ? ? ?6、Activity與Fragment間的切換以及通信?
? ? ? ?7、notification通知欄設(shè)計(jì)?
? ? ? ?8、自定義廣播?
? ? ? ?9、android系統(tǒng)文件管
? ? ?音樂(lè)播放器思路及源碼下載見:【android】音樂(lè)播放器之設(shè)計(jì)思路
? ? ? ?Ui界面的最終顯示效果如下:
? ??
? ? ? ?馬上來(lái)看看UI界面是如何實(shí)現(xiàn)的,不過(guò)先得做些準(zhǔn)備工作~~啟動(dòng)界面的設(shè)計(jì)。細(xì)心的朋友肯定注意到目前一些主流app登陸時(shí)候都有封面展示的效果,啟動(dòng)界面的制作就是為了實(shí)現(xiàn)這個(gè)效果:加載一個(gè)布局全屏展示一張封面,并2s跳轉(zhuǎn)到主布局MainActivity.
public class SplashActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// no titlerequestWindowFeature(Window.FEATURE_NO_TITLE);// 全屏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.splash_layout);// 2s跳轉(zhuǎn)到主界面new Handler().postDelayed(new Runnable() {@Overridepublic void run() {startActivity(new Intent(SplashActivity.this, MainActivity.class));finish();}}, 2000);}
}
? ? ? ?有了上面的準(zhǔn)備工作,可以設(shè)計(jì)主界面以及主界面中的5個(gè)Fragment(不是4個(gè)嘛!!!!~!~我這邊直接將本地音樂(lè)列表這個(gè)Fragment直接放到MainActivity中)。目前,主流的app主界面實(shí)現(xiàn)由四種方式:
? ? ? ??(1)ViewPager實(shí)現(xiàn)
? ? ? ? (2)Fragment實(shí)現(xiàn)
? ? ? ? (3)FragmentPagerAdapter+ViewPager實(shí)現(xiàn)
? ? ? ? (4)ViewPagerIndicator+ViewPager實(shí)現(xiàn)
? ? ? 就挑個(gè)最熟練的實(shí)現(xiàn)方式:Fragment實(shí)現(xiàn)。(哈哈,目前水平比較低。。。ViewPager后文有使用分析,其余還是想每一種都有機(jī)會(huì)去嘗試用到代碼中去。) 小編這邊的都是使用動(dòng)態(tài)Fragment
[html]?view plaincopy
<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"?? ????xmlns:tools="http://schemas.android.com/tools"?? ????android:layout_width="match_parent"?? ????android:layout_height="match_parent"?? ????android:orientation="vertical"?>?? ????<include?layout="@layout/top"?/>?? ?????? ????<FrameLayout??? ????????android:id="@+id/id_content"?? ????????android:layout_width="fill_parent"?? ????????android:layout_height="0dp"?? ????????android:layout_weight="1">?? ????????? ????</FrameLayout>?? ?? ????<include?layout="@layout/bottom"?/>?? ?? </LinearLayout>??
? ? ? ??
頂部和底部的布局就補(bǔ)貼出來(lái)了,到時(shí)直接看源碼就明白了。在MainActivity中通過(guò)監(jiān)聽底部的按鈕獲取FragmentManager方式開啟一個(gè)事務(wù)添加一個(gè)Fragment或者去隱藏一個(gè)Fragment。當(dāng)然這邊也可以直接調(diào)用事務(wù)的raplace方法替代原布局中的Fragment
(~·~
后文將介紹相關(guān)的Api以及總結(jié)Fragment和Activity的通信
),主要代碼段如下:
[html]?view plaincopy
public?void?setSelect(int?i)?? ????{?? ????????FragmentManager?fm?=?getSupportFragmentManager();?? ????????FragmentTransaction?transaction?=?fm.beginTransaction();?? ????????hideFragment(transaction);?? ????????//?把圖片設(shè)置為亮的?? ????????//?設(shè)置內(nèi)容區(qū)域?? ????????switch?(i)?? ????????{?? ????????case?TAB_USER:?? ????????????if?(mTab01?==?null)?? ????????????{?? ????????????????mTab01?=?new?UserFragment();?? ????????????????transaction.add(R.id.id_content,?mTab01);?? ????????????}?else?? ????????????{?? ????????????????transaction.show(mTab01);?? ????????????}?? ????????????mImguser.setImageResource(R.drawable.icon_user_selected);?? ????????????mTitle.setText("我的音樂(lè)");?? ?????????????? ????????????break;?? ????????case?TAB_CD:?? ????????????if?(mTab02?==?null)?? ????????????{?? ????????????????mTab02?=?new?CdFragment();?? ????????????????transaction.add(R.id.id_content,?mTab02);?? ????????????}?else?? ????????????{?? ????????????????transaction.show(mTab02);?? ?????????????????? ????????????}?? ????????????mImgcd.setImageResource(R.drawable.icon_cd_selected);?? ????????????mTitle.setText("音樂(lè)架");?? ????????????break;?? ????????case?TAB_SEARCH:?? ????????????if?(mTab03?==?null)?? ????????????{?? ????????????????mTab03?=?new?SearchFragment();?? ????????????????transaction.add(R.id.id_content,?mTab03);?? ????????????}?else?? ????????????{?? ????????????????transaction.show(mTab03);?? ????????????}?? ????????????mImgsearch.setImageResource(R.drawable.icon_search_selected);?? ????????????mTitle.setText("搜索");?? ????????????break;?? ????????case?TAB_COMPASS:?? ????????????if?(mTab04?==?null)?? ????????????{?? ????????????????mTab04?=?new?CompassFragment();?? ????????????????transaction.add(R.id.id_content,?mTab04);?? ????????????}?else?? ????????????{?? ????????????????transaction.show(mTab04);?? ????????????}?? ????????????mImgcompass.setImageResource(R.drawable.icon_compass_selected);?? ????????????mTitle.setText("發(fā)現(xiàn)");?? ????????????break;?? ????????case?TAB_SONGLIST:?? ????????????if?(mTab05?==?null)?? ????????????{?? ????????????????mTab05?=?new?LocalFragment();?? ????????????????transaction.add(R.id.id_content,?mTab05);?? ????????????}?else?? ????????????{?? ????????????????transaction.show(mTab05);?? ????????????}?? ????????????resetImgs();?? ????????????setVisibility(TOP_MENU);?? ????????????mTitle.setText("本地音樂(lè)");?? ????????????break;?? ?????????????? ????????default:?? ????????????break;?? ????????}?? ?? ????????transaction.commit();?? ????}??
? ? ? ?
[html]?view plaincopy
private?void?hideFragment(FragmentTransaction?transaction)?? ????{?? ????????setVisibility(TOP_JUMP);?? ????????if?(mTab01?!=?null)?? ????????{?? ????????????transaction.hide(mTab01);?? ????????}?? ????????if?(mTab02?!=?null)?? ????????{?? ????????????transaction.hide(mTab02);?? ????????}?? ????????if?(mTab03?!=?null)?? ????????{?? ????????????transaction.hide(mTab03);?? ????????}?? ????????if?(mTab04?!=?null)?? ????????{?? ????????????transaction.hide(mTab04);?? ????????}?? ????????if?(mTab05?!=?null)?? ????????{?? ????????????transaction.hide(mTab05);?? ?????????????? ????????}?? ????}??
? ? ? ??
? ? ? ? ?每個(gè)Fragment中的控件也都是最最常用的控件,這邊就不一一介紹。。。其余除Ui之外更詳細(xì)的分析可以看看小編其他相關(guān)的博客。其中,應(yīng)該注意的是:在本地音樂(lè)這個(gè)Fragment中通過(guò)短點(diǎn)擊ListView歌曲Items跳轉(zhuǎn)啟動(dòng)PlayAcyivity加載播放界面。也終于到了講ViewPager這塊了!!!~!~
? ? ???ViewPager添加一個(gè)VIew或者刪除一個(gè)View是通過(guò)我們自定義的PagerAdapter控制的,于是我們可以在View中維系一個(gè)ArrayList<view>。然后滑動(dòng)的時(shí)候通過(guò)get(position)取出對(duì)應(yīng)的view:
? ? ? ?ViewPager添加一個(gè)VIew或者刪除一個(gè)View是通過(guò)我們自定義的PagerAdapter控制的,于是我們可以在View中維系一個(gè)ArrayList<view>。然后滑動(dòng)的時(shí)候通過(guò)get(position)取出對(duì)應(yīng)的view:
[html]?view plaincopy
/**?? ?????*?初始化viewpager的內(nèi)容?? ?????*/?? ????private?void?initViewPagerContent()?{?? ????????View?cd?=?View.inflate(this,?R.layout.play_pager_item_1,?null);?? ????????mCdView?=?(CDView)?cd.findViewById(R.id.play_cdview);?? ????????mTextArtistTitle?=?(TextView)?cd.findViewById(R.id.play_singer);?? ????????mLrcViewOnFirstPage?=?(LrcView)?cd.findViewById(R.id.play_first_lrc);?? ?????????? ????????View?lrcView?=?View.inflate(this,?R.layout.play_pager_item_2,?null);?? ????????mLrcViewOnSecondPage?=?(LrcView)?lrcView.findViewById(R.id.play_first_lrc_2);?? ?????????? ????????mViewPagerContent.add(cd);?? ????????mViewPagerContent.add(lrcView);?? ????}??
[html]?view plaincopy
private?PagerAdapter?mPagerAdapter?=?new?PagerAdapter()?{?? ????????@Override?? ????????public?int?getCount()?{?? ????????????return?mViewPagerContent.size();?? ????????}?? ?? ????????@Override?? ????????public?boolean?isViewFromObject(View?view,?Object?obj)?{?? ????????????return?view?==?obj;?? ????????}?? ?????????? ????????@Override?? ????????public?Object?instantiateItem(ViewGroup?container,?int?position)?{?? ????????????container.addView(mViewPagerContent.get(position));?? ????????????return?mViewPagerContent.get(position);?? ????????}?? ?????????? ????????@Override?? ????????public?void?destroyItem(ViewGroup?container,?int?position,?Object?object)?{?? ????????????((ViewPager)?container).removeView((View)?object);?? ????????}?? ????};??
? ? ? ? ?內(nèi)容太多了,只能講主要的Ui布局實(shí)現(xiàn)。其他細(xì)節(jié)可以參考我其他博文或者源代碼。
? ? ??? ?下面我想共享下下面的一些關(guān)于Fragment的小總結(jié)!
? ? ? ? Fragment家族常用的API
? ? ? ? ??Fragment常用的三個(gè)類:(1)android.app.Fragment 主要用于定義Fragment;(2)android.app.FragmentManager 主要用于在Activity中操作Fragment;(3)android.app.FragmentTransaction 保證一些列Fragment操作的原子性,熟悉事務(wù)這個(gè)詞,一定能明白~
? ? ? ? ?a、獲取FragmentManage的方式:getFragmentManager() // v4中,getSupportFragmentManager
? ? ? ? ?b、主要的操作都是FragmentTransaction的方法:1)FragmentTransaction transaction = fm.benginTransatcion();//開啟一個(gè)事務(wù);2)transaction.add()?往Activity中添加一個(gè)Fragment;3)transaction.remove()從Activity中移除一個(gè)Fragment,如果被移除的Fragment沒(méi)有添加到回退棧(回退棧后面會(huì)詳細(xì)說(shuō)),這個(gè)Fragment實(shí)例將會(huì)被銷毀;4)transaction.replace():使用另一個(gè)Fragment替換當(dāng)前的,實(shí)際上就是remove()然后add()的合體~;5)transaction.hide():隱藏當(dāng)前的Fragment,僅僅是設(shè)為不可見,并不會(huì)銷毀;6)transaction.show():顯示之前隱藏的Fragment
7)detach()會(huì)將view從UI中移除,和remove()不同,此時(shí)fragment的狀態(tài)依然由FragmentManager維護(hù);8)attach()重建view視圖,附加到UI上并顯示。
transatcion.commit()//提交一個(gè)事務(wù)
? ? ? ? 注意:常用Fragment的哥們,可能會(huì)經(jīng)常遇到這樣Activity狀態(tài)不一致:State loss這樣的錯(cuò)誤。主要是因?yàn)?#xff1a;commit方法一定要在Activity.onSaveInstance()之前調(diào)用。
? ? ? ? ?上述,基本是操作Fragment的所有的方式了,在一個(gè)事務(wù)開啟到提交可以進(jìn)行多個(gè)的添加、移除、替換等操作。值得注意的是:如果你喜歡使用Fragment,一定要清楚這些方法,哪個(gè)會(huì)銷毀視圖,哪個(gè)會(huì)銷毀實(shí)例,哪個(gè)僅僅只是隱藏,這樣才能更好的使用它們。
總結(jié)
以上是生活随笔為你收集整理的【android】音乐播放器之UI设计的点点滴滴的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。