【android】音樂播放器之UI設計的點點滴滴
學習Android有一個多月,看完了《第一行程式碼》以及mars老師的第一期視訊通過音樂播放器小專案加深對知識點的理解。從本文開始,將詳細的介紹簡單仿多米音樂播放器的實現,以及網路解析資料獲取百度音樂最新排行音樂以及下載功能。
功能介紹如下:
1、獲取本地歌曲列表,實現歌曲播放功能。
2、利用jsoup解析網頁資料,從網路獲取歌曲列表,同時實現歌曲和歌詞下載到手機本地的功能。
3、通知欄提醒,實現仿QQ音樂播放器的通知欄功能.
涉及的技術有:
1、jsoup解析網路網頁,從而獲取需要的資料
2、android中訪問網路,獲取檔案到本地的網路請求技術,以及下載檔案到本地實現斷點下載
3、執行緒池
4、圖片快取
5、service一直在後臺執行
6、Activity與Fragment間的切換以及通訊
7、notification通知欄設計
8、自定義廣播
9、android系統檔案管
Ui介面的最終顯示效果如下:
馬上來看看UI介面是如何實現的,不過先得做些準備工作~~啟動介面的設計。細心的朋友肯定注意到目前一些主流app登陸時候都有封面展示的效果,啟動介面的製作就是為了實現這個效果:載入一個佈局全屏展示一張封面,並2s跳轉到主佈局MainActivity.
public class SplashActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // no title requestWindowFeature(Window.FEATURE_NO_TITLE); // 全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.splash_layout); // 2s跳轉到主介面 new Handler().postDelayed(new Runnable() { @Override public void run() { startActivity(new Intent(SplashActivity.this, MainActivity.class)); finish(); } }, 2000); } }
有了上面的準備工作,可以設計主介面以及主介面中的5個Fragment(不是4個嘛!!!!~!~我這邊直接將本地音樂列表這個Fragment直接放到MainActivity中)。目前,主流的app主介面實現由四種方式:
(1)ViewPager實現
(2)Fragment實現
(3)FragmentPagerAdapter+ViewPager實現
(4)ViewPagerIndicator+ViewPager實現
就挑個最熟練的實現方式:Fragment實現。(哈哈,目前水平比較低。。。ViewPager後文有使用分析,其餘還是想每一種都有機會去嘗試用到程式碼中去。) 小編這邊的都是使用動態Fragment
- <LinearLayoutxmlns: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">
- <includelayout="@layout/top"/>
- <FrameLayout
- android:id="@+id/id_content"
- android:layout_width="fill_parent"
- android:layout_height="0dp"
- android:layout_weight="1">
- </FrameLayout>
- <includelayout="@layout/bottom"/>
- </LinearLayout>
- public void setSelect(int i)
- {
- FragmentManager fm = getSupportFragmentManager();
- FragmentTransaction transaction = fm.beginTransaction();
- hideFragment(transaction);
- // 把圖片設定為亮的
- // 設定內容區域
- 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("我的音樂");
- 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("音樂架");
- 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("發現");
- 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("本地音樂");
- break;
- default:
- break;
- }
- transaction.commit();
- }
- 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);
- }
- }
每個Fragment中的控制元件也都是最最常用的控制元件,這邊就不一一介紹。。。其餘除Ui之外更詳細的分析可以看看小編其他相關的部落格。其中,應該注意的是:在本地音樂這個Fragment中通過短點選ListView歌曲Items跳轉啟動PlayAcyivity載入播放介面。也終於到了講ViewPager這塊了!!!~!~
ViewPager新增一個VIew或者刪除一個View是通過我們自定義的PagerAdapter控制的,於是我們可以在View中維繫一個ArrayList<view>。然後滑動的時候通過get(position)取出對應的view:
- /**
- * 初始化viewpager的內容
- */
- 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);
- }
- 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);
- }
- };
下面我想共享下下面的一些關於Fragment的小總結!
Fragment家族常用的API
Fragment常用的三個類:(1)android.app.Fragment 主要用於定義Fragment;(2)android.app.FragmentManager 主要用於在Activity中操作Fragment;(3)android.app.FragmentTransaction 保證一些列Fragment操作的原子性,熟悉事務這個詞,一定能明白~
a、獲取FragmentManage的方式:getFragmentManager() // v4中,getSupportFragmentManager
b、主要的操作都是FragmentTransaction的方法:1)FragmentTransaction transaction = fm.benginTransatcion();//開啟一個事務;2)transaction.add() 往Activity中新增一個Fragment;3)transaction.remove()從Activity中移除一個Fragment,如果被移除的Fragment沒有新增到回退棧(回退棧後面會詳細說),這個Fragment例項將會被銷燬;4)transaction.replace():使用另一個Fragment替換當前的,實際上就是remove()然後add()的合體~;5)transaction.hide():隱藏當前的Fragment,僅僅是設為不可見,並不會銷燬;6)transaction.show():顯示之前隱藏的Fragment
7)detach()會將view從UI中移除,和remove()不同,此時fragment的狀態依然由FragmentManager維護;8)attach()重建view檢視,附加到UI上並顯示。
transatcion.commit()//提交一個事務
注意:常用Fragment的哥們,可能會經常遇到這樣Activity狀態不一致:State loss這樣的錯誤。主要是因為:commit方法一定要在Activity.onSaveInstance()之前呼叫。
上述,基本是操作Fragment的所有的方式了,在一個事務開啟到提交可以進行多個的新增、移除、替換等操作。值得注意的是:如果你喜歡使用Fragment,一定要清楚這些方法,哪個會銷燬檢視,哪個會銷燬例項,