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布局文件

<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>

三、在启动的Acitvity界面中使用自定义的Tab类

<?xml version="1.0" encoding="utf-8"?>

<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" />

四、自定义类处理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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值