Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Fragment應用實戰(音樂播放器界面)

Android Fragment應用實戰(音樂播放器界面)

編輯:關於Android編程

當下很多手機應用都會有一個非常類似的功能,即屏幕的下方顯示一行Tab標簽選項,點擊不同的標簽就可以切換到不同的界面,如以下幾個應用所示:

\\\\

以上底部這四個標簽,每一個分別對應一個Fragment,這種底部標簽式的布局策略真的非常常見,那麼話說回來,這種效果到底是如何的呢?熟悉Android的朋友一定都會知道,很簡單嘛,使用TabHost就OK了!但是殊不知,TabHost並非是那麼的簡單,它的可擴展性非常的差,不能隨意地定制Tab項顯示的內容,而且運行還要依賴於ActivityGroup。ActivityGroup原本主要是用於為每一個TabHost的子項管理一個單獨的Activity,但目前已經被廢棄了。為什麼呢?當然就是因為Fragment的出現了!

下面就開始真正的編程吧!

打開或者新建一個xml文件作為程序的主布局文件,這裡直接采用activity_main.xml作為程序的主布局文件,在裡面加入如下代碼:

 



    <framelayout android:id="@+id/Content" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent">

        

            
            
        
    </framelayout>

    

        
        

            
            

                

                
            
        

        

            

                

                
            
        

        

            

                

                
            
        

        

            

                

                
            
        
    


大家看這代碼比較難以理解,但其實主要就分為兩部分。第一個部分就是FrameLayout,這裡只是給FrameLayout的id設置為Content,並沒有在裡面添加任何具體的內容,因為具體的內容是要在後面動態進行添加的。第二個部分就是FrameLayout下面的LinearLayout,這個LinearLayout中包含的就是整個類似於TabHost的布局。可以看到,我們將這個LinearLayout又等分成了四份,每一份中都會顯示一個ImageView和一個TextView。ImageView用於顯示當前Tab的圖標,TextView用於顯示當前Tab的標題,這個效果就會和QQ非常得類似。

 

\

那麼接下來我們要開始實現Fragment和它們的布局了,新建一個discover_music_fragment.xml作為第一個“發現音樂”的界面,代碼如下所示:

 




    

        

        
    

 

這個布局就是在屏幕的正中央顯示一個消息圖標以及一段文字。

\

然後,我們要去創建對應這個布局的Fragment,新建一個DiscoverMusicFragment繼承自Fragment,代碼如下所示

 

public class DiscoverMusicFragment extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View discover_music_fragment = inflater.inflate(
				R.layout.discover_music_fragment, container, false);
		return discover_music_fragment;
	}

}

後面的都和這個一樣,就不一一展示。

這樣我們把每一個Fragment以及它們對應的布局文件都創建好了,接下來我們開始寫MainActivity裡面的內容,代碼如下所示:

 

 

public class MainActivity extends Activity implements OnClickListener {
	/**
	 * 用於展示‘發現音樂’的Fragment
	 */
	private DiscoverMusicFragment discoverMusicFragment;
	/**
	 * 用於展示‘我的音樂’的Fragment
	 */
	private MyMusicFragment myMusicFragment;
	/**
	 * 用於展示‘朋友’的Fragment
	 */
	private FriendsFragment friendsFragment;
	/**
	 * 用於展示‘賬號’的Fragment
	 */
	private AccountFragment accountFragment;
	/**
	 * ‘發現音樂’布局
	 */
	private View discover_music_layout;
	/**
	 * ‘我的音樂’布局
	 */
	private View my_music_layout;
	/**
	 * ‘朋友’布局
	 */
	private View friends_layout;
	/**
	 * ‘賬號’布局
	 */
	private View account_layout;
	/**
	 * 在Tab布局上顯示‘發現音樂’圖標的控件
	 */
	private ImageView discover_music_image;
	/**
	 * 在Tab布局上顯示‘我的音樂’圖標的控件
	 */
	private ImageView my_music_image;
	/**
	 * 在Tab布局上顯示‘朋友’圖標的控件
	 */
	private ImageView friends_image;
	/**
	 * 在Tab布局上顯示‘賬號’圖標的控件
	 */
	private ImageView account_image;
	/**
	 * 在Tab布局上顯示‘發現音樂’標題的控件
	 */
	private TextView discover_music_text;
	/**
	 * 在Tab布局上顯示‘我的音樂’標題的控件
	 */
	private TextView my_music_text;
	/**
	 * 在Tab布局上顯示‘朋友’標題的控件
	 */
	private TextView friends_text;
	/**
	 * 在Tab布局上顯示‘賬號’標題的控件
	 */
	private TextView account_text;
	/**
	 * 用於對Fragment進行管理
	 */
	private FragmentManager fragmentManager;

	/**
	 * ‘我的音樂’界面‘下載音樂’
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		// 初始化布局元素
		initViews();
		fragmentManager = getFragmentManager();
		// 第一次啟動時選中第0個tab
		setTabSelection(0);
	}


	private void initViews() {
		// 四個布局
		discover_music_layout = findViewById(R.id.discover_layout);
		my_music_layout = findViewById(R.id.my_layout);
		friends_layout = findViewById(R.id.friends_layout);
		account_layout = findViewById(R.id.account_layout);

		// 四個圖片
		discover_music_image = (ImageView) findViewById(R.id.discover_image);
		my_music_image = (ImageView) findViewById(R.id.my_image);
		friends_image = (ImageView) findViewById(R.id.friends_image);
		account_image = (ImageView) findViewById(R.id.account_image);

		// 四個標題
		discover_music_text = (TextView) findViewById(R.id.discover_text);
		my_music_text = (TextView) findViewById(R.id.my_text);
		friends_text = (TextView) findViewById(R.id.friends_text);
		account_text = (TextView) findViewById(R.id.account_text);
		// 設置監聽事件
		discover_music_layout.setOnClickListener(this);
		my_music_layout.setOnClickListener(this);
		friends_layout.setOnClickListener(this);
		account_layout.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.discover_layout:
			// 當點擊了‘發現音樂’tab時,選中第1個tab
			setTabSelection(0);
			break;
		case R.id.my_layout:
			// 當點擊了‘我的音樂’tab時,選中第2個tab
			setTabSelection(1);
			break;
		case R.id.friends_layout:
			// 當點擊了‘朋友’tab時,選中第3個tab
			setTabSelection(2);
			break;
		case R.id.account_layout:
			// 當點擊了‘賬號’tab時,選中第4個tab
			setTabSelection(3);
			break;
		default:
			break;
			
		}

	}
	

	/**
	 * 根據傳入的index參數來設置選中的tab頁。
	 * 
	 * @param index
	 *            每個tab頁對應的下標。0表示發現音樂,1表示我的音樂,2表示朋友,3表示賬號。
	 */
	private void setTabSelection(int index) {
		// 每次選中之前要清除掉上次選中的狀態
		clearSelection();
		// 開啟一個Fragment事務
		FragmentTransaction fragmentTransaction = fragmentManager
				.beginTransaction();
		// 先隱藏掉所有的Fragment,以防止有多個Fragment顯示在界面上的情況
		HideFragments(fragmentTransaction);
		switch (index) {
		case 0:// 當點擊了‘發現音樂’時,改變文字的顏色
			discover_music_text.setTextColor(Color.BLUE);
			if (discoverMusicFragment == null) {
				// 如果discoverMusicFragment為空,則創建一個並添加到界面上
				discoverMusicFragment = new DiscoverMusicFragment();
				fragmentTransaction.add(R.id.Content, discoverMusicFragment);
			} else {
				// 如果discoverMusicFragment不為空,則將其顯示出來
				fragmentTransaction.show(discoverMusicFragment);
			}
			break;
		case 1:// 當點擊了‘我的音樂’時,改變文字的顏色
			my_music_text.setTextColor(Color.BLUE);
			if (myMusicFragment == null) {
				// 如果myMusicFragment為空,則創建一個並添加到界面上
				myMusicFragment = new MyMusicFragment();
				fragmentTransaction.add(R.id.Content, myMusicFragment);
			} else {
				// 如果myMusicFragment不為空,則將其顯示出來
				fragmentTransaction.show(myMusicFragment);
			}
			break;
		case 2:// 當點擊了‘朋友’時,改變文字的顏色
			friends_text.setTextColor(Color.BLUE);
			if (friendsFragment == null) {
				// 如果friendsFragment為空,則創建一個並添加到界面上
				friendsFragment = new FriendsFragment();
				fragmentTransaction.add(R.id.Content, friendsFragment);
			} else {
				// 如果friendsFragment不為空,則將其顯示出來
				fragmentTransaction.show(friendsFragment);
			}
			break;
		case 3:// 當點擊了‘賬號’時,改變文字的顏色
			account_text.setTextColor(Color.BLUE);
			if (accountFragment == null) {
				// 如果accountFragment為空,則創建一個並添加到界面上
				accountFragment = new AccountFragment();
				fragmentTransaction.add(R.id.Content, accountFragment);
			} else {
				// 如果accountFragment不為空,則將其顯示出來
				fragmentTransaction.show(accountFragment);
			}
			break;
		default:
			break;
		}
		fragmentTransaction.commit();
	}

	/**
	 * 將所有的Fragment都設置為隱藏狀態
	 * 
	 * @param fragmentTransaction
	 *            用於對Fragment執行操作的事務
	 */
	private void HideFragments(FragmentTransaction fragmentTransaction) {
		if (discoverMusicFragment != null) {
			fragmentTransaction.hide(discoverMusicFragment);
		}
		if (myMusicFragment != null) {
			fragmentTransaction.hide(myMusicFragment);
		}
		if (friendsFragment != null) {
			fragmentTransaction.hide(friendsFragment);
		}
		if (accountFragment != null) {
			fragmentTransaction.hide(accountFragment);
		}
	}

	/**
	 * 清除掉所有選中狀態
	 */
	private void clearSelection() {
		discover_music_text.setTextColor(Color.parseColor("#82858b"));
		my_music_text.setTextColor(Color.parseColor("#82858b"));
		friends_text.setTextColor(Color.parseColor("#82858b"));
		account_text.setTextColor(Color.parseColor("#82858b"));
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

代碼看不懂的大家可以參照上面的注釋。

 

 

下面我再帶大家簡單梳理一遍。在onCreate()方法中先是調用了initViews()來獲取每個控件的實例,並給相應的控件設置好點擊事件,然後調用setTabSelection()方法設置默認的選中項,這裡傳入的0說明默認選中第1個Tab項。

那麼setTabSelection()方法中又是如何處理的呢?可以看到,首先第一步是調用clearSelection()方法來清理掉之前的選中狀態,然後開啟一個Fragment事務,並隱藏掉所有的Fragment,以防止有多個Fragment顯示在界面上。接下來根據傳入的index參數判斷出選中的是哪一個Tab項,並改變該Tab項的圖標和文字顏色,然後將相應的Fragment添加到界面上。這裡注意一個細節,我們添加Fragment的時候並沒有使用replace()方法,而是會先判斷一下該Fragment是否為空,如果是空的則調用add()方法添加一個進來,如果不是空的則直接調用show()方法顯示出來即可。那麼為什麼沒有使用replace()方法呢?這是因為replace()方法會將被替換掉的那個Fragment徹底地移除掉,該Fragment的生命周期就結束了。當再次點擊剛才那個Tab項的時候,就會讓該Fragment的生命周期重新開始,onCreate()、onCreateView()等方法都會重新執行一遍。這顯然不是我們想要的,也和ActivityGroup的工作原理不符,因此最好的解決方案就是使用hide()和show()方法來隱藏和顯示Fragment,這就不會讓Fragment的生命周期重走一遍了。

設置完默認選中項後,我們當然還可以通過點擊Tab項來自由地切換界面,這就會進入到onClick()方法中。onClick()方法中的邏輯判斷非常簡單,當點擊了消息標簽時就會選中第1個tab項,點擊聯系人標簽時就會選中第2個tab項,點擊動態標簽時就會選中第3個tab項,點擊設置標簽時就會選中第4個tab項。都是通過調用setTabSelection()方法來完成的,只是傳入了不同的參數。

好了,這樣我們就將全部的代碼都編寫完成了。

大家趕緊去試一下吧!

還有一點,這個效果在橫屏的時候也可以的哦!

好了,今天的講解到此結束,有疑問的朋友請在下面留言!謝謝!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved