編輯:關於Android編程
在做移動開發過程中底部導航欄是十分常見的功能,且市面上見到的做法也有很多種,這篇博文記錄一下使用Fragment實現底部導航欄的功能,算是對這幾天學習Android做的Demo的一個總結吧。
好久不敲代碼,確實生疏不少。現在發現使用博客記錄自己平時的學習資料,節省了很多搜集資料的時間,是一個很好的學習方法。
為了講明白這個實現過程,我們貼出來的代碼多一寫,這樣更方便理解 [最後還會放出完整的代碼實現] 。看上圖的界面做的比較粗糙,但實現過程的骨架都具有了,想要更完美的設計,之後自行完善吧 ^0^。
通過觀察上述效果圖,發現任意一個選項頁面都有三部分組成:
頂部去除ActionBar後的標題欄;中間一個FragmentLayout用來放相應的Fragment;底部一個大的LinearLayout放著四個樣式一樣的(ImagView + TextView)的小Item。(1) 完整具體的代碼,詳見:show_main_lay.xml
,通過注釋可以看到該布局的三部分組成。
<framelayout android:background="@color/whitesmoke" android:id="@+id/content" android:layout_height="0dp" android:layout_weight="1" android:layout_width="match_parent"></framelayout>
附上源碼截圖吧:
(2) 對於布局的第一部分的頂部標題欄,代碼請見:title_layout.xml
:
見下截圖:
(3) 布局中間的第二部分我們再分別建立4個.xml布局文件,分別命名為:fg1.xml、fg2.xml、fg3.xml、fg4.xml
,內容上只更改一下TextView中的文字說明,如第一個頁面,改為第二個頁面。下面只給出其中一個fg1.xml
:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
如圖:
(4) 這裡也給出Values
目錄下的colors.xml
內容吧,顏色還是比較完整的但是名字不好記:
#3F51B5
#303F9F
#FF4081
#EDEDED
#ff000000
#ffffffff
#ffcccccc
#ff404040
#c0ffff00
#ffffffff
#ffc0c0c0
#c000ff00
#ffffffff
#b0000000
#ff808080
#ffffffff
#fffff0e0
#ffffffff
#ff000000
#ff4b4b4b
#ff000000
#ffffffff
#50000000
#ffffffff
#00000000
#ffffffff
#ffff0000
#60000000
#58567D
#686868
#FFFFFF
#FFFFF0
#FFFFE0
#FFFF00
#FFFAFA
#FFFAF0
#FFFACD
#FFF8DC
#FFF5EE
#FFF0F5
#FFEFD5
#FFEBCD
#FFE4E1
#FFE4C4
#FFE4B5
#FFDEAD
#FFDAB9
#FFD700
#FFC0CB
#FFB6C1
#FFA500
#FFA07A
#FF8C00
#FF7F50
#FF69B4
#FF6347
#FF4500
#FF1493
#FF00FF
#FF00FF
#FF0000
#FDF5E6
#FAFAD2
#FAF0E6
#FAEBD7
#FA8072
#F8F8FF
#F5FFFA
#F5F5F5
#F5F5DC
#F5DEB3
#F4A460
#F0FFFF
#F0FFF0
#F0F8FF
#F0E68C
#F08080
#EEE8AA
#EE82EE
#E9967A
#E6E6FA
#E0FFFF
#DEB887
#DDA0DD
#DCDCDC
#DC143C
#DB7093
#DAA520
#DA70D6
#D8BFD8
#D3D3D3
#D3D3D3
#D2B48C
#D2691E
#CD853F
#CD5C5C
#C71585
#C0C0C0
#BDB76B
#BC8F8F
#BA55D3
#B8860B
#B22222
#B0E0E6
#B0C4DE
#AFEEEE
#ADFF2F
#ADD8E6
#A9A9A9
#A9A9A9
#A52A2A
#A0522D
#9932CC
#98FB98
#9400D3
#9370DB
#90EE90
#8FBC8F
#8B4513
#8B008B
#8B0000
#8A2BE2
#87CEFA
#87CEEB
#808080
#808080
#808000
#800080
#800000
#7FFFD4
#7FFF00
#7CFC00
#7B68EE
#778899
#778899
#708090
#708090
#6B8E23
#6A5ACD
#696969
#696969
#66CDAA
#6495ED
#5F9EA0
#556B2F
#4B0082
#48D1CC
#483D8B
#4682B4
#4169E1
#40E0D0
#3CB371
#32CD32
#2F4F4F
#2F4F4F
#2E8B57
#228B22
#20B2AA
#1E90FF
#191970
#00FFFF
#00FFFF
#00FF7F
#00FF00
#00FA9A
#00CED1
#00BFFF
#008B8B
#008080
#008000
#006400
#0000FF
#0000CD
#00008B
#000080
#000000
如圖:
那麼到這裡我們的界面布局就基本完成了!
接下來我們需要寫四個相應的Fragment
的實現類,同樣拷貝4份,改用inflate
加載Fragment即可。即,包含四個差不多一樣的Fragment,分別起名為:FirstFragment.java、SecondFragment.java、ThirdFragment.java、FourthFragment.java
。下面主要展示一下FirstFragment.java
的具體代碼:
package com.example.dm.myapplication;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by dm on 16-3-29.
* 第一個頁面
*/
public class FirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fg1, container, false);
return view;
}
}
如圖:
各個七零八落的小部件都已經准備到序了,現在只剩下這個主界面實現類把他們融合在一起,實現相應的效果了。MainActivity.java 的編寫也很簡單,直接看代碼和注釋就可以了,不多解釋額:主要包含幾個初始化方法、選中處理、隱藏所有Fragment的方法。詳見MainActivity.java:
package com.example.dm.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity; // 注意這裡我們導入的V4的包,不要導成app的包了
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* 主頁面內容
* Created by dm on 16-1-19.
*/
public class MainActivity extends FragmentActivity implements View.OnClickListener {
// 初始化頂部欄顯示
private ImageView titleLeftImv;
private TextView titleTv;
// 定義4個Fragment對象
private FirstFragment fg1;
private SecondFragment fg2;
private ThirdFragment fg3;
private FourthFragment fg4;
// 幀布局對象,用來存放Fragment對象
private FrameLayout frameLayout;
// 定義每個選項中的相關控件
private RelativeLayout firstLayout;
private RelativeLayout secondLayout;
private RelativeLayout thirdLayout;
private RelativeLayout fourthLayout;
private ImageView firstImage;
private ImageView secondImage;
private ImageView thirdImage;
private ImageView fourthImage;
private TextView firstText;
private TextView secondText;
private TextView thirdText;
private TextView fourthText;
// 定義幾個顏色
private int whirt = 0xFFFFFFFF;
private int gray = 0xFF7597B3;
private int dark = 0xff000000;
// 定義FragmentManager對象管理器
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_main_lay);
fragmentManager = getSupportFragmentManager();
initView(); // 初始化界面控件
setChioceItem(0); // 初始化頁面加載時顯示第一個選項卡
}
/**
* 初始化頁面
*/
private void initView() {
// 初始化頁面標題欄
titleLeftImv = (ImageView) findViewById(R.id.title_imv);
titleLeftImv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, LoginActivity.class));
}
});
titleTv = (TextView) findViewById(R.id.title_text_tv);
titleTv.setText("首 頁");
// 初始化底部導航欄的控件
firstImage = (ImageView) findViewById(R.id.first_image);
secondImage = (ImageView) findViewById(R.id.second_image);
thirdImage = (ImageView) findViewById(R.id.third_image);
fourthImage = (ImageView) findViewById(R.id.fourth_image);
firstText = (TextView) findViewById(R.id.first_text);
secondText = (TextView) findViewById(R.id.second_text);
thirdText = (TextView) findViewById(R.id.third_text);
fourthText = (TextView) findViewById(R.id.fourth_text);
firstLayout = (RelativeLayout) findViewById(R.id.first_layout);
secondLayout = (RelativeLayout) findViewById(R.id.second_layout);
thirdLayout = (RelativeLayout) findViewById(R.id.third_layout);
fourthLayout = (RelativeLayout) findViewById(R.id.fourth_layout);
firstLayout.setOnClickListener(MainActivity.this);
secondLayout.setOnClickListener(MainActivity.this);
thirdLayout.setOnClickListener(MainActivity.this);
fourthLayout.setOnClickListener(MainActivity.this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.first_layout:
setChioceItem(0);
break;
case R.id.second_layout:
setChioceItem(1);
break;
case R.id.third_layout:
setChioceItem(2);
break;
case R.id.fourth_layout:
setChioceItem(3);
break;
default:
break;
}
}
/**
* 設置點擊選項卡的事件處理
*
* @param index 選項卡的標號:0, 1, 2, 3
*/
private void setChioceItem(int index) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
clearChioce(); // 清空, 重置選項, 隱藏所有Fragment
hideFragments(fragmentTransaction);
switch (index) {
case 0:
// firstImage.setImageResource(R.drawable.XXXX); 需要的話自行修改
firstText.setTextColor(dark);
firstLayout.setBackgroundColor(gray);
// 如果fg1為空,則創建一個並添加到界面上
if (fg1 == null) {
fg1 = new FirstFragment();
fragmentTransaction.add(R.id.content, fg1);
} else {
// 如果不為空,則直接將它顯示出來
fragmentTransaction.show(fg1);
}
break;
case 1:
// secondImage.setImageResource(R.drawable.XXXX);
secondText.setTextColor(dark);
secondLayout.setBackgroundColor(gray);
if (fg2 == null) {
fg2 = new SecondFragment();
fragmentTransaction.add(R.id.content, fg2);
} else {
fragmentTransaction.show(fg2);
}
break;
case 2:
// thirdImage.setImageResource(R.drawable.XXXX);
thirdText.setTextColor(dark);
thirdLayout.setBackgroundColor(gray);
if (fg3 == null) {
fg3 = new ThirdFragment();
fragmentTransaction.add(R.id.content, fg3);
} else {
fragmentTransaction.show(fg3);
}
break;
case 3:
// fourthImage.setImageResource(R.drawable.XXXX);
fourthText.setTextColor(dark);
fourthLayout.setBackgroundColor(gray);
if (fg4 == null) {
fg4 = new FourthFragment();
fragmentTransaction.add(R.id.content, fg4);
} else {
fragmentTransaction.show(fg4);
}
break;
}
fragmentTransaction.commit(); // 提交
}
/**
* 當選中其中一個選項卡時,其他選項卡重置為默認
*/
private void clearChioce() {
// firstImage.setImageResource(R.drawable.XXX);
firstText.setTextColor(gray);
firstLayout.setBackgroundColor(whirt);
// secondImage.setImageResource(R.drawable.XXX);
secondText.setTextColor(gray);
secondLayout.setBackgroundColor(whirt);
// thirdImage.setImageResource(R.drawable.XXX);
thirdText.setTextColor(gray);
thirdLayout.setBackgroundColor(whirt);
// fourthImage.setImageResource(R.drawable.XXX);
fourthText.setTextColor(gray);
fourthLayout.setBackgroundColor(whirt);
}
/**
* 隱藏Fragment
*
* @param fragmentTransaction
*/
private void hideFragments(FragmentTransaction fragmentTransaction) {
if (fg1 != null) {
fragmentTransaction.hide(fg1);
}
if (fg2 != null) {
fragmentTransaction.hide(fg2);
}
if (fg3 != null) {
fragmentTransaction.hide(fg3);
}
if (fg4 != null) {
fragmentTransaction.hide(fg4);
}
}
}
見圖:
到這裡我們的功能就基本實現了,是不是還挺簡單的。
Fragment相關類導入的時候是v4包還是app包!我們這裡導入的是V4的包,在代碼的注釋部分,已經給出說明; 在完整的代碼包中,我們還添加了App啟動界面及動畫、登錄界面,這兩部分的內容,這裡不做具體的說明,之後繼續完善。
完整Demo下載地址:https://yunpan.cn/cqwG4iK7pNtn3 訪問密碼 39b5
Android中的Intent是一個非常重要且常用的類,可以用來在一個組件中啟動App中的另一個組件或者是啟動另一個App的組件,這裡所說的組件指的是Activity、S
一、 先看效果二、設置 File->Settings 或Ctrl + Alt +S 找到 Editor -> Colors &Fonts ->
我們都知道Android缺省的ExpandableListView的group header無法固定在界面上,當向下滾動後,不能對當前顯示的那些child 指示出它們歸屬
使用PopupWindow來實現彈出框,並且帶有動畫效果首先自定義PopupWindowpublic class LostPopupWindow extends Popu