android自定义底部Tab,项目整体界面框架
共享一个自己在开发过程中搭建的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;
- }
- }
源码连接地址:http://download.csdn.net/detail/gao_chun/7645909
五、自定义控件系列
Android项目中使用自定义进度加载Dialog:http://blog.csdn.net/gao_chun/article/details/45270031
ListView中按钮监听器 设置 及 优化:http://blog.csdn.net/gao_chun/article/details/41249131
Android项目中自定义顶部标题栏:http://blog.csdn.net/gao_chun/article/details/45255929
Android自定义设置圆形图片控件:http://blog.csdn.net/gao_chun/article/details/39207557
自定义AlertDialog提示框:http://blog.csdn.net/gao_chun/article/details/37757571