現在的APP首頁大部分屏幕的下方顯示一行Tab標簽選項,點擊不同的標簽就可以切換到不同的界面。如下圖:
我們之前都是用TabHost來實現,但是殊不知,TabHost并非是那么的簡單,它的可擴展性非常的差,不能隨意地定制Tab項顯示的內容,而且運行還要依賴于ActivityGroup。ActivityGroup原本主要是用于為每一個TabHost的子項管理一個單獨的Activity,但目前已經被廢棄了。下面就借助Fragment來完成類似于TabHost一般的效果。
先實現主界面布局main_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" > <FrameLayoutandroid:id="@+id/content"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" ></FrameLayout> <Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:background="#000000" /> <LinearLayoutandroid:layout_width="match_parent"android:layout_height="60dp"android:background="#ffffff"android:orientation="horizontal" > <RelativeLayoutandroid:id="@+id/message_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" > <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerVertical="true"android:orientation="vertical" > <ImageViewandroid:id="@+id/message_image"android:layout_width="20dp"android:layout_height="20dp"android:layout_gravity="center_horizontal"android:src="@drawable/ic_launcher" /> <TextViewandroid:id="@+id/message_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="消息"android:textColor="#82858b" /></LinearLayout></RelativeLayout> <Viewandroid:layout_width="0.5dp"android:layout_height="match_parent"android:background="#000000" /> <RelativeLayoutandroid:id="@+id/contacts_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" > <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerVertical="true"android:orientation="vertical" > <ImageViewandroid:id="@+id/contacts_image"android:layout_width="20dp"android:layout_height="20dp"android:layout_gravity="center_horizontal"android:src="@drawable/ic_launcher" /> <TextViewandroid:id="@+id/contacts_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="聯系人"android:textColor="#82858b" /></LinearLayout></RelativeLayout> <Viewandroid:layout_width="0.5dp"android:layout_height="match_parent"android:background="#000000" /> <RelativeLayoutandroid:id="@+id/news_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" > <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerVertical="true"android:orientation="vertical" > <ImageViewandroid:id="@+id/news_image"android:layout_width="20dp"android:layout_height="20dp"android:layout_gravity="center_horizontal"android:src="@drawable/ic_launcher" /> <TextViewandroid:id="@+id/news_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="動態"android:textColor="#82858b" /></LinearLayout></RelativeLayout> <Viewandroid:layout_width="0.5dp"android:layout_height="match_parent"android:background="#000000" /> <RelativeLayoutandroid:id="@+id/setting_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" > <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerVertical="true"android:orientation="vertical" > <ImageViewandroid:id="@+id/setting_image"android:layout_width="20dp"android:layout_height="20dp"android:layout_gravity="center_horizontal"android:src="@drawable/ic_launcher" /> <TextViewandroid:id="@+id/setting_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="設置"android:textColor="#82858b" /></LinearLayout></RelativeLayout></LinearLayout> </LinearLayout>
這段布局代碼雖然有點長,但其實主要就分為兩部分。第一個部分就是FrameLayout,這里只是給FrameLayout的id設置成content,并沒有在里面添加任何具體的內容,因為具體的內容是要在后面動態進行添加的。第二個部分就是FrameLayout下面的LinearLayout,這個LinearLayout中包含的就是整個類似于TabHost的布局。可以看到,我們將這個LinearLayout又等分成了四份,每一份中都會顯示一個ImageView和一個TextView。ImageView用于顯示當前Tab的圖標,TextView用于顯示當前Tab的標題。
既然是等分成了四分,那接下來我們自然要去分別實現四個Fragment和它們的布局了。新建一個message_layout.xml作為消息界面的布局,代碼如下所示:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" > <LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical" > <ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:src="@drawable/ic_launcher" /> <TextViewandroid:id="@+id/message"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:padding="10dp"android:text="這是消息界面"android:textSize="20sp" /></LinearLayout> </RelativeLayout>
其他三個界面類似就不一 一列出。然后要去創建對應這個布局的Fragment。新建MessageFragment繼承自Fragment,代碼如下所示:
public class MessageFragment extends Fragment{ private TextView tv; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View messageLayout = inflater.inflate(R.layout.message, container, false); tv=(TextView) messageLayout.findViewById(R.id.message); tv.setText("哈哈哈哈哈哈"); return messageLayout; } }
我們也依次創建其他三個布局的Fragment。最后是MainActivity,代碼如下:
public class MainActivity extends Activity implements OnClickListener {/*** 用于展示消息的Fragment*/private MessageFragment messageFragment; /*** 用于展示聯系人的Fragment*/private ContactsFragment contactsFragment; /*** 用于展示動態的Fragment*/private NewsFragment newsFragment; /*** 用于展示設置的Fragment*/private SettingFragment settingFragment; /*** 消息界面布局*/private View messageLayout; /*** 聯系人界面布局*/private View contactsLayout; /*** 動態界面布局*/private View newsLayout; /*** 設置界面布局*/private View settingLayout;/*** 用于對Fragment進行管理*/private FragmentManager fragmentManager; @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); fragmentManager = getFragmentManager(); // 第一次啟動時選中第0個tab setTabSelection(0);} /*** 在這里獲取到每個需要用到的控件的實例,并給它們設置好必要的點擊事件。*/ private void initViews() { messageLayout = findViewById(R.id.message_layout); contactsLayout = findViewById(R.id.contacts_layout); newsLayout = findViewById(R.id.news_layout); settingLayout = findViewById(R.id.setting_layout); messageLayout.setOnClickListener(this); contactsLayout.setOnClickListener(this); newsLayout.setOnClickListener(this); settingLayout.setOnClickListener(this);} @Overridepublic void onClick(View v) { switch (v.getId()) { case R.id.message_layout: // 當點擊了消息tab時,選中第1個tab setTabSelection(0); break; case R.id.contacts_layout: // 當點擊了聯系人tab時,選中第2個tab setTabSelection(1); break; case R.id.news_layout: // 當點擊了動態tab時,選中第3個tab setTabSelection(2); break; case R.id.setting_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 transaction = fragmentManager.beginTransaction(); // 先隱藏掉所有的Fragment,以防止有多個Fragment顯示在界面上的情況 hideFragments(transaction); switch (index) { case 0: messageLayout.setBackgroundColor(0xff0000ff); if (messageFragment == null) { // 如果MessageFragment為空,則創建一個并添加到界面上 messageFragment = new MessageFragment(); transaction.add(R.id.content, messageFragment); } else { // 如果MessageFragment不為空,則直接將它顯示出來 transaction.show(messageFragment); } break; case 1: // 當點擊了聯系人tab時,改變控件的圖片和文字顏色 contactsLayout.setBackgroundColor(0xff0000ff); if (contactsFragment == null) { // 如果ContactsFragment為空,則創建一個并添加到界面上 contactsFragment = new ContactsFragment(); transaction.add(R.id.content, contactsFragment); } else { // 如果ContactsFragment不為空,則直接將它顯示出來 transaction.show(contactsFragment); } break; case 2: // 當點擊了動態tab時,改變控件的圖片和文字顏色 newsLayout.setBackgroundColor(0xff0000ff); if (newsFragment == null) { // 如果NewsFragment為空,則創建一個并添加到界面上 newsFragment = new NewsFragment(); transaction.add(R.id.content, newsFragment); } else { // 如果NewsFragment不為空,則直接將它顯示出來 transaction.show(newsFragment); } break; case 3: default: // 當點擊了設置tab時,改變控件的圖片和文字顏色 settingLayout.setBackgroundColor(0xff0000ff); if (settingFragment == null) { // 如果SettingFragment為空,則創建一個并添加到界面上 settingFragment = new SettingFragment(); transaction.add(R.id.content, settingFragment); } else { // 如果SettingFragment不為空,則直接將它顯示出來 transaction.show(settingFragment); } break; } transaction.commit();} /*** 將所有的Fragment都置為隱藏狀態。** @param transaction* 用于對Fragment執行操作的事務*/private void hideFragments(FragmentTransaction transaction) { if (messageFragment != null) { transaction.hide(messageFragment); } if (contactsFragment != null) { transaction.hide(contactsFragment); } if (newsFragment != null) { transaction.hide(newsFragment); } if (settingFragment != null) { transaction.hide(settingFragment); }} /*** 清除掉所有的選中狀態。*/private void clearSelection() { messageLayout.setBackgroundColor(0xffffffff); contactsLayout.setBackgroundColor(0xffffffff); newsLayout.setBackgroundColor(0xffffffff); settingLayout.setBackgroundColor(0xffffffff); }}
這樣就實現了上面圖中的效果了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答