android自定義底部Tab導航UI,專案整體介面框架
android自定義底部Tab導航UI,專案整體介面框架
共享一個自己在開發過程中搭建的android專案介面框架,便於提高開發效率。
主要功能
1.使用Button自定義底部Tab和Title
2.點選底部Tab後使用Fragment切換頁面
3.主頁使用ViewPager滾動顯示新聞圖片
4.自定義類處理Fragment重疊回退問題
一、自定義底部Tab類
/*******************************************************************************
*
* Copyright (c) Weaver Info Tech Co. Ltd
*
* TabView
*
* app.ui.widget.TabView.java
* TODO: File description or class description.
*
* @author: Administrator
* @changeLogs:
* 1.0.0: First created this class.
*
******************************************************************************/
package app.ui.widget;
import mobi.kuaidian.qunakao.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
/**
* @author Administrator
*
*/
public class TabView extends LinearLayout implements OnClickListener {
private OnTabChangeListener mOnTabChangedListener;
private int mState = 0;
private final Button mStateButton1;
private final Button mStateButton2;
private final Button mStateButton3;
private final Button mStateButton4;
public TabView(Context context) {
this(context, null);
}
public TabView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public TabView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.view_tab, this);
mStateButton1 = (Button) findViewById(R.id.button_state1);
mStateButton2 = (Button) findViewById(R.id.button_state2);
mStateButton3 = (Button) findViewById(R.id.button_state3);
mStateButton4 = (Button) findViewById(R.id.button_state4);
mStateButton1.setOnClickListener(this);
mStateButton2.setOnClickListener(this);
mStateButton3.setOnClickListener(this);
mStateButton4.setOnClickListener(this);
}
public void setOnTabChangeListener(OnTabChangeListener listener) {
mOnTabChangedListener = listener;
}
public void setCurrentTab(int index) {
switchState(index);
}
private void switchState(int state) {
if (mState == state) {
return;
} // else continue
mState = state;
mStateButton1.setSelected(false);
mStateButton2.setSelected(false);
mStateButton3.setSelected(false);
mStateButton4.setSelected(false);
Object tag = null;
switch (mState) {
case 0:
mStateButton1.setSelected(true);
tag = mStateButton1.getTag();
break;
case 1:
mStateButton2.setSelected(true);
tag = mStateButton2.getTag();
break;
case 2:
mStateButton3.setSelected(true);
tag = mStateButton3.getTag();
break;
case 3:
mStateButton4.setSelected(true);
tag = mStateButton4.getTag();
break;
default:
break;
}
if (mOnTabChangedListener != null) {
if (tag != null && mOnTabChangedListener != null) {
mOnTabChangedListener.onTabChange(tag.toString());
} else {
mOnTabChangedListener.onTabChange(null);
}
} // else ignored
}
/* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button_state1:
switchState(0);
break;
case R.id.button_state2:
switchState(1);
break;
case R.id.button_state3:
switchState(2);
break;
case R.id.button_state4:
switchState(3);
break;
default:
break;
}
}
public static interface OnTabChangeListener {
public void onTabChange(String tag);
}
}
二、對應底部Tab的XML佈局檔案
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0" >
<Button
android:id="@+id/button_state1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/ic_message_selector"
android:gravity="center"
android:singleLine="true"
android:tag="message"
android:text="@string/text_tab_message"
android:textColor="@color/text_service_color"
android:textSize="14dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0" >
<Button
android:id="@+id/button_state2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/ic_service_selector"
android:gravity="center"
android:singleLine="true"
android:tag="service"
android:text="@string/text_tab_service"
android:textColor="@color/text_service_color"
android:textSize="14dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0" >
<Button
android:id="@+id/button_state3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/ic_profile_selector"
android:gravity="center"
android:singleLine="true"
android:tag="personal"
android:text="@string/text_tab_profile"
android:textColor="@color/text_service_color"
android:textSize="14dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0" >
<Button
android:id="@+id/button_state4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/ic_setting_selector"
android:gravity="center"
android:singleLine="true"
android:tag="settings"
android:text="@string/text_tab_setting"
android:textColor="@color/text_service_color"
android:textSize="14dp" />
</FrameLayout>
</merge>
三、在啟動的Acitvity介面中使用自定義的Tab類
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include layout="@layout/layout_titlebar" />
<FrameLayout
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0" />
<app.ui.widget.TabView
android:id="@+id/view_tab"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height"
android:background="@color/tab_main_color" />
</LinearLayout>
四、自定義類處理Fragment返回重疊的問題
/*******************************************************************************
*
* Copyright (c) Baina Info Tech Co. Ltd
*
* FragmentUtils
*
* app.util.FragmentUtils.java
* TODO: File description or class description.
*
* @changeLogs:
* 1.0.0: First created this class.
*
******************************************************************************/
package app.util;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
/**
* FragmentUtils of MyHealth
*
* @author qixiao
*/
public class FragmentUtils {
private FragmentUtils() {
}
public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
Class<? extends Fragment> newFragment, Bundle args) {
return replaceFragment(fragmentManager, container, newFragment, args, false);
}
public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
Fragment newFragment) {
return replaceFragment(fragmentManager, container, newFragment, false);
}
public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
Class<? extends Fragment> newFragment, Bundle args, boolean addToBackStack) {
Fragment fragment = null;
// 構造新的Fragment
try {
fragment = newFragment.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (fragment != null) {
// 設定引數
if (args != null && !args.isEmpty()) {
final Bundle bundle = fragment.getArguments();
if (bundle != null) {
bundle.putAll(args);
} else {
fragment.setArguments(args);
}
}
// 替換
return replaceFragment(fragmentManager, container, fragment, addToBackStack);
} else {
return null;
}
}
public static Fragment replaceFragment(FragmentManager fragmentManager, int container,
Fragment newFragment, boolean addToBackStack) {
final FragmentTransaction transaction = fragmentManager.beginTransaction();
final String tag = newFragment.getClass().getSimpleName();
if (newFragment != null) {
transaction.replace(container, newFragment, tag);
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commitAllowingStateLoss();
return newFragment;
}
public static Fragment switchFragment(FragmentManager fragmentManager, int container,
Fragment currentFragment, Class<? extends Fragment> newFragment, Bundle args) {
return switchFragment(fragmentManager, container, currentFragment, newFragment, args, false);
}
/**
*
* @param fragmentManager
* @param container
* @param currentFragment
* @param newFragment
* @param args 新Fragment的引數
* @param addToBackStack 這個操作是否加入棧中,如果要實現類似返回效果,則需要。
* @return 新顯示的Fragment
*/
public static Fragment switchFragment(FragmentManager fragmentManager, int container,
Fragment currentFragment, Class<? extends Fragment> newFragment, Bundle args,
boolean addToBackStack) {
final FragmentTransaction transaction = fragmentManager.beginTransaction();
final String tag = newFragment.getSimpleName();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
// 如果在棧中找到相應的Fragment,則顯示,否則重新生成一個
if (fragment != null) {
if (fragment != currentFragment) {
if (currentFragment != null) {
transaction.hide(currentFragment);
}
transaction.show(fragment);
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commitAllowingStateLoss();
} else {
fragment.getArguments().putAll(args);
}
return fragment;
} else {
try {
fragment = newFragment.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
// 為新的Fragment新增引數
if (fragment != null) {
if (args != null && !args.isEmpty()) {
final Bundle bundle = fragment.getArguments();
if (bundle != null) {
bundle.putAll(args);
} else {
fragment.setArguments(args);
}
}
}
// 顯示新的Fragment
if (currentFragment != null) {
transaction.hide(currentFragment);
}
transaction.add(container, fragment, tag);
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commitAllowingStateLoss();
return fragment;
}
}
原始碼下載地址:https://download.csdn.net/download/wo0123456789wo/10847244