前言
底部切換效果已經很常見了,本文介紹其中的一種實現方法:FrameLayout+Fragment
本案例已上傳至Github,你可以查看完整源碼,也可以下載demo apk體驗一下
實現效果如下:
Tab切換
Step1:創建Fragment
創建四個頁卡所表示的Fragment以及其佈局文件,圖中每個頁卡都是一個Fragment(碎片)
先創建第一個頁卡的Fragment以及佈局文件
fragment_tab1.xml
<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"
tools:context="com.zhuangfei.fragment.TabFragment1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第一個頁卡" />
<Button
android:id="@+id/tab1_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Fragment交互"/>
</LinearLayout>
TabFragment1.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
/**
*第一個頁卡
* A simple {@link Fragment} subclass.
*/
public class TabFragment1 extends Fragment {
View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_tab1, container, false);
Button button=view.findViewById(R.id.tab1_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(),"findViewById()時不要忘了前邊的view."
,Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
以下copy
3份,並簡單的修改一下顯示的文字
fragment_tab2.xml
<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"
tools:context="com.zhuangfei.fragment.TabFragment1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="第二個頁卡" />
</LinearLayout>
TabFragment2.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
*第二個頁卡
* A simple {@link Fragment} subclass.
*/
public class TabFragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab2, container, false);
}
}
fragment_tab3.xml
<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"
tools:context="com.zhuangfei.fragment.TabFragment1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="第三個頁卡" />
</LinearLayout>
TabFragment3.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
*第三個頁卡
* A simple {@link Fragment} subclass.
*/
public class TabFragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab3, container, false);
}
}
fragment_tab4.xml
<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"
tools:context="com.zhuangfei.fragment.TabFragment1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="第四個頁卡" />
</LinearLayout>
TabFragment4.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
*第四個頁卡
* A simple {@link Fragment} subclass.
*/
public class TabFragment4 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab4, container, false);
}
}
創建主頁面
四個Fragment應該怎麼顯示在主頁面上呢,這裏用到了幀佈局,主頁面的底部是底部導航的佈局,中間是一個幀佈局
activity_main.xml
<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" >
<!--幀佈局,承載四個TAB的Fragment-->
<FrameLayout
android:id="@+id/id_framelayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/app_white" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/app_line"/>
<include layout="@layout/view_bottom" />
</LinearLayout>
view_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottomLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/app_white"
android:orientation="horizontal">
<!-- 主界面底部4個TAB -->
<LinearLayout
android:id="@+id/id_tab1_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/id_tab1_imageview"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_tab1" />
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab2_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/id_tab2_imageview"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_tab2" />
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab3_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/id_tab3_imageview"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_tab3" />
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab4_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/id_tab4_imageview"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="@drawable/ic_tab4" />
</LinearLayout>
</LinearLayout>
MainActivity.java
package com.zhuangfei.fragment;
import android.media.Image;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* 主頁面,顯示多個Fragment
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
// 創建Fragment對象
private TabFragment1 tabFragment1;
private TabFragment2 tabFragment2;
private TabFragment3 tabFragment3;
private TabFragment4 tabFragment4;
private ImageView tabImageView1;
private ImageView tabImageView2;
private ImageView tabImageView3;
private ImageView tabImageView4;
private LinearLayout tabLayout1;
private LinearLayout tabLayout2;
private LinearLayout tabLayout3;
private LinearLayout tabLayout4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
select(0);
}
private void initView() {
tabImageView1=findViewById(R.id.id_tab1_imageview);
tabImageView2=findViewById(R.id.id_tab2_imageview);
tabImageView3=findViewById(R.id.id_tab3_imageview);
tabImageView4=findViewById(R.id.id_tab4_imageview);
tabLayout1=findViewById(R.id.id_tab1_layout);
tabLayout2=findViewById(R.id.id_tab2_layout);
tabLayout3=findViewById(R.id.id_tab3_layout);
tabLayout4=findViewById(R.id.id_tab4_layout);
tabLayout1.setOnClickListener(this);
tabLayout2.setOnClickListener(this);
tabLayout3.setOnClickListener(this);
tabLayout4.setOnClickListener(this);
}
/**
* 初始化Tab的狀態
*/
public void initTab() {
int color = getResources().getColor(R.color.app_gray);
// 更改圖片顏色爲暗色
tabImageView1.setColorFilter(color);
tabImageView2.setColorFilter(color);
tabImageView3.setColorFilter(color);
tabImageView4.setColorFilter(color);
}
/**
* 選中第i個Tab時的處理
*
* @param i
*/
public void select(int i) {
// 得到Fragment管理器以及事務
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
initTab();
int color = getResources().getColor(R.color.app_orange);
switch (i) {
case 0:
tabImageView1.setColorFilter(color);
if (tabFragment1 == null) {
tabFragment1 = new TabFragment1();
}
transaction.replace(R.id.id_framelayout, tabFragment1);
break;
case 1:
tabImageView2.setColorFilter(color);
if (tabFragment2 == null) {
tabFragment2 = new TabFragment2();
}
transaction.replace(R.id.id_framelayout, tabFragment2);
break;
case 2:
tabImageView3.setColorFilter(color);
if (tabFragment3 == null) {
tabFragment3 = new TabFragment3();
}
transaction.replace(R.id.id_framelayout, tabFragment3);
break;
case 3:
tabImageView4.setColorFilter(color);
if (tabFragment4 == null) {
tabFragment4 = new TabFragment4();
}
transaction.replace(R.id.id_framelayout, tabFragment4);
break;
default:
break;
}
transaction.commit();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.id_tab1_layout:
select(0);
break;
case R.id.id_tab2_layout:
select(1);
break;
case R.id.id_tab3_layout:
select(2);
break;
case R.id.id_tab4_layout:
select(3);
break;
}
}
}
本文用的是replace()
方法來替換顯示的Fargment
,這種方法的優缺點:
優點:使用簡單
缺點:會導致Fargment
在每次切換時都實例化一個對象,性能有影響,並且Fargment有嵌套時會出現內部數據消失的問題
還可以使用add()、show()、hide()
實現Fragment
切換,該方法的優缺點:
優點:提升性能
缺點:可能會出現重影問題
當然,上面提到的兩個問題都是有解決方法的,後續的文章中將使用add()、show()、hide()
實現Fragment
切換,敬請期待…