android自定义底部Tab,项目整体界面框架

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



转载请注明出处.

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值