fragment+viewPager实现底部导航栏(一)

底部导航栏的实现有很多种方法,我这里采用的是最简单的LinearLayout+TextView布局,没有使用RadioGroup做布局,主要是为了兼容底部出现新消息小圆点的这种情况,本篇文章参考以下链接:
Fragment实例精讲——底部导航栏的实现

提前声明,本篇文章的讲解可能有些长,大家不妨先泡杯维维豆奶再来看戏。

先上一张效果图吧:

3.gif
提前准备

由于我项目中用到ButterKnife初始化控件,所以app gradle中需要引入ButterKnife的依赖:

    //butterKnife
    compile 'com.jakewharton:butterknife:8.5.1'
    //这条千万不能忘记!!
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'

ButterKnife的使用大家可以参考我的另一篇文章
butterknife的使用

首先说是设置底部导航栏中一个上面加有图片的textView和每个小方格中右上角显示小圆点的textView

1.先给出底部显示图片的TextView和显示小圆点的TextView的样式xml

在value文件夹下的stytel.xml中添加两个stytel

    

    
2.在drawable下写一个shape_round_textview.xml文件,用于实现小圆点TextView的圆形背景


    
    

在drawable下写上点击底部文字颜色切换的tab_menu_text.xml



    
    

在drawable下写上点击底部图片切换的tab_menu_chat.xml



    
    

其它三个tab_menu_find.xml,tab_menu_user.xml,tab_menu_me.xml图片的切换与此类似,copy一下改改就行

3.写一个BaseFragment用于所有Fragment去继承它,记住,此处用的所有与fragment相关的都是用的v4包下的,别导错包了
package com.test.ui.fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

import com.test.util.StringUtil;
import com.test.util.ToastUtil;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * Created by Admin on 2017/6/7.
 */

public abstract class BaseFragment extends Fragment {

    protected View mLayoutView;
    protected Context mContext;
    private Unbinder mUnbinder;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext = context;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mLayoutView = inflater.inflate(getLayoutId(), container, false);
        mUnbinder=ButterKnife.bind(this,mLayoutView);//绑定framgent
        onCreateFragmentView(inflater, container, savedInstanceState);


        return mLayoutView;
    }

    protected void onCreateFragmentView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        initData();
        setListener();
    }

    @Override
    public void onDestroy() {
        if(mUnbinder!=null){
            mUnbinder.unbind();
        }
        super.onDestroy();
    }

    protected abstract int getLayoutId();
    protected abstract void initData();
    protected abstract void setListener();

    /**
     * 获取editText的值
     *
     * @param et
     * @return
     */
    protected String getTextOfEditText(EditText et){
        if (et == null) {
            return null;
        }
        if (et.getText() == null) {
            return null;
        }
        if (StringUtil.isEmpty(et.getText().toString())) {
            return "";
        }
        return et.getText().toString().trim();
    }

    protected void showToast(String msg) {
        if (StringUtil.isNotEmpty(msg)) {
            ToastUtil.show(msg);
        }
    }

    protected void showShortToast(String msg){
        if (StringUtil.isNotEmpty(msg)) {
            ToastUtil.shortShow(msg);
        }
    }
}
4.给出第一个fragment的代码:
package com.test.ui.fragment;

import android.view.View;
import android.widget.TextView;

import com.test.R;

import butterknife.BindView;

/**
 * Created by Admin on 2017/6/7.
 */

public class Fragment1 extends BaseFragment implements View.OnClickListener{


    @BindView(R.id.txt_content)
    TextView mTvContext;

    @Override
    protected int getLayoutId() {
        return R.layout.one_fragment;
    }

    @Override
    protected void initData() {

    }

    @Override
    protected void setListener() {
        mTvContext.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.txt_content:
                TextView tab_menu_channel_num = (TextView)((MenuActivity)mContext).findViewById(R.id.tab_menu_channel_num);
                tab_menu_channel_num.setText("11");
                tab_menu_channel_num.setVisibility(View.VISIBLE);
                break;
        }
    }
}

下面是Fragment1的layout文件one_fragment.xml




    


Fragment2,Fragment3,Fragment4的代码和Fragment1类似,copy一下改改即可

5.然后是给出activity代码
package com.test.ui.fragment;

import android.content.Context;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.test.R;
import com.test.app.AppActivity;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;

/**
 * Created by Admin on 2017/6/7.
 */

public class MenuActivity extends AppActivity implements View.OnClickListener,TabOnPageChangeListener.OnSelectedFragmentListener {

    public static Intent newIndexIntent(Context context) {
        Intent newIntent = new Intent(context, MenuActivity.class);
        return newIntent;
    }

    @BindView(R.id.ly_tab_menu_channel)
    LinearLayout ly_tab_menu_channel;
    @BindView(R.id.tab_menu_channel)
    TextView tab_menu_channel;
    @BindView(R.id.tab_menu_channel_num)
    TextView tab_menu_channel_num;

    @BindView(R.id.ly_tab_menu_message)
    LinearLayout ly_tab_menu_message;
    @BindView(R.id.tab_menu_message)
    TextView tab_menu_message;
    @BindView(R.id.tab_menu_message_num)
    TextView tab_menu_message_num;

    @BindView(R.id.ly_tab_menu_better)
    LinearLayout ly_tab_menu_better;
    @BindView(R.id.tab_menu_better)
    TextView tab_menu_better;
    @BindView(R.id.tab_menu_better_num)
    TextView tab_menu_better_num;

    @BindView(R.id.ly_tab_menu_setting)
    LinearLayout ly_tab_menu_setting;
    @BindView(R.id.tab_menu_setting)
    TextView tab_menu_setting;
    @BindView(R.id.tab_menu_setting_partner)
    ImageView tab_menu_setting_partner;

    @BindView(R.id.vpager)
    ViewPager mViewPager;

    private ListmFragmentList;
    private MainPagerAdapter mainPagerAdapter;
    private TabOnPageChangeListener mTabOnPageChangeListener;


    @Override
    protected int getContentViewId() {
        return R.layout.activity_menu;
    }

    @Override
    protected void initData() {
        mFragmentList=new ArrayList<>();
        mFragmentList.add(0, new Fragment1());
        mFragmentList.add(1, new Fragment2());
        mFragmentList.add(2, new Fragment3());
        mFragmentList.add(3, new Fragment4());

        mTabOnPageChangeListener=new TabOnPageChangeListener(mViewPager);
        mainPagerAdapter = new MainPagerAdapter(getSupportFragmentManager(), mFragmentList);
        mViewPager.setOffscreenPageLimit(4);// 设置预加载Fragment个数
        mViewPager.setAdapter(mainPagerAdapter);
        mViewPager.setCurrentItem(0);// 设置当前显示标签页为第一页
    }

    @Override
    protected void setListener() {
        ly_tab_menu_channel.setOnClickListener(this);
        ly_tab_menu_message.setOnClickListener(this);
        ly_tab_menu_better.setOnClickListener(this);
        ly_tab_menu_setting.setOnClickListener(this);
        mViewPager.addOnPageChangeListener(mTabOnPageChangeListener);
        mTabOnPageChangeListener.setOnSelectedFragmentListener(this);
        //默认显示第一个fragment, 必须在ly_tab_menu_channel.setOnClickListener(this);之后执行
        ly_tab_menu_channel.performClick();
    }

    @Override
    public void onClick(View v){
        switch (v.getId()) {
            case R.id.ly_tab_menu_channel:
                clickFragment1();
                break;
            case R.id.ly_tab_menu_message:
                clickFragment2();
                break;
            case R.id.ly_tab_menu_better:
                clickFragment3();
                break;
            case R.id.ly_tab_menu_setting:
                clickFragment4();
                break;
        }
    }

    //重置所有文本的选中状态
    private void setSelected() {
        tab_menu_channel.setSelected(false);
        tab_menu_message.setSelected(false);
        tab_menu_better.setSelected(false);
        tab_menu_setting.setSelected(false);
    }

    private void clickFragment1(){
        setSelected();
        tab_menu_channel.setSelected(true);
        tab_menu_channel_num.setVisibility(View.INVISIBLE);
        mViewPager.setCurrentItem(0);
    }

    private void clickFragment2(){
        setSelected();
        tab_menu_message.setSelected(true);
        tab_menu_message_num.setVisibility(View.INVISIBLE);
        mViewPager.setCurrentItem(1);
    }

    private void clickFragment3(){
        setSelected();
        tab_menu_better.setSelected(true);
        tab_menu_better_num.setVisibility(View.INVISIBLE);
        mViewPager.setCurrentItem(2);
    }

    private void clickFragment4(){
        setSelected();
        tab_menu_setting.setSelected(true);
        tab_menu_setting_partner.setVisibility(View.INVISIBLE);
        mViewPager.setCurrentItem(3);
    }

    @Override
    public void selectedFragment(int index) {
        switch (index) {
            case 0:
                clickFragment1();
                break;
            case 1:
                clickFragment2();
                break;
            case 2:
                clickFragment3();
                break;
            case 3:
                clickFragment4();
                break;
        }
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
    }
}

需要注意的是:

  • 我的MenuActivity 继承的是AppActivity,而AppActivity 是我自己写的一个类似BaseActivity的类,大家也可直接 MenuActivity 继承 AppCompatActivity 即可。
  • setListener()方法中ly_tab_menu_channel.performClick();是为了默认显示第一个fragment,必须在ly_tab_menu_channel.setOnClickListener(this);之后执行

然后贴出 activity_menu.xml的代码



    

        
        
    





    

        

            

                

                
            
        

        

            

                

                
            
        


        

            

                

                
            
        


        

            

                

                

            
        
    



    

    



6.MenuActivity中用到viewPager,肯定少不了适配器 MainPagerAdapter 了
package com.test.ui.fragment;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.View;

import java.util.List;

/***
 * 标签主页适配器
 *
 * @author pei
 * @version 1.0
 * @create 2016-6-21
 */
public class MainPagerAdapter extends FragmentPagerAdapter {

    private List mFragmentList;

    public MainPagerAdapter(FragmentManager fm, List mFragmentList) {
        super(fm);
        this.mFragmentList = mFragmentList;
    }

    @Override
    public Fragment getItem(int position) {
        // TODO Auto-generated method stub
        return mFragmentList == null ? null : mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mFragmentList == null ? 0 : mFragmentList.size();
    }

    @Override
    public void destroyItem(View container, int position, Object object) {
        //      super.destroyItem(container, position, object);
    }
}

7.MenuActivity中的viewPager本来是可以直接
    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

来监听滑动的,但是我为了去掉滑动到两端的时候出现阴影,所以用
TabOnPageChangeListener重新实现了下ViewPager.OnPageChangeListener()接口,下面贴出 TabOnPageChangeListener代码:

package com.test.ui.fragment;

import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.EdgeEffectCompat;

import java.lang.reflect.Field;

/***
 * TabMenuFragmentActivity  viewpager滑动监听(禁用滑到边界显示黑边)
 *
 * @author pei
 * @version 1.0
 * @create 2016-6-21
 */
public class TabOnPageChangeListener implements OnPageChangeListener {

    private ViewPager mViewPager;
    private OnSelectedFragmentListener mOnSelectedFragmentListener;

    private EdgeEffectCompat leftEdge;//去除viewpager滑到边界的黑边
    private EdgeEffectCompat rightEdge;//去除viewpager滑到边界的黑边

    public TabOnPageChangeListener(ViewPager viewPager) {
        this.mViewPager = viewPager;
        init();
    }

    public void setOnSelectedFragmentListener(OnSelectedFragmentListener onSelectedFragmentListener) {
        this.mOnSelectedFragmentListener = onSelectedFragmentListener;
    }

    private void init() {
        try {
            Field leftEdgeField = mViewPager.getClass().getDeclaredField("mLeftEdge");
            Field rightEdgeField = mViewPager.getClass().getDeclaredField("mRightEdge");
            if (leftEdgeField != null && rightEdgeField != null) {
                leftEdgeField.setAccessible(true);
                rightEdgeField.setAccessible(true);
                leftEdge = (EdgeEffectCompat) leftEdgeField.get(mViewPager);
                rightEdge = (EdgeEffectCompat) rightEdgeField.get(mViewPager);
            }
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        // 禁用滑到边界显示黑边
        if (leftEdge != null && rightEdge != null) {
            leftEdge.finish();
            rightEdge.finish();
            leftEdge.setSize(0, 0);
            rightEdge.setSize(0, 0);
        }
    }


    @Override
    public void onPageScrollStateChanged(int state) {
        //state的状态有三个,0表示什么都没做,1正在滑动,2滑动完毕
    }

    @Override
    public void onPageSelected(int position) {
        if (mOnSelectedFragmentListener != null) {
            mOnSelectedFragmentListener.selectedFragment(position);
        }
    }

    public interface OnSelectedFragmentListener {

        void selectedFragment(int index);
    }
}

8.可能有的同学对我MenuActivity所继承的AppActivity有疑问,那我就贴出来大家随便看看就好

package com.test.app;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;

import com.test.util.StringUtil;
import com.test.util.ToastUtil;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**

  • Created by Admin on 2017/5/16.
    */

public abstract class AppActivity extends AppCompatActivity{

protected View mLayoutView;//总布局
protected Activity mContext;
private Unbinder mUnbinder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //赋值context
    mContext=this;
    //activity管理
    AppActivityManager.getInstance().addActivity(this);
    if (getContentViewId() != 0) {
        mLayoutView = LayoutInflater.from(mContext).inflate(getContentViewId(), null);
        setContentView(mLayoutView);
        //控件绑定
        mUnbinder= ButterKnife.bind(this);
    }
    initData();
    setListener();
}

/**设置布局**/
protected abstract int getContentViewId();

protected abstract void initData();

protected abstract void setListener();

@Override
protected void onDestroy() {
    if(mUnbinder!=null){
        mUnbinder.unbind();
    }
    super.onDestroy();
}

/**获取editText的值**/
protected String getTextOfEditText(EditText et) {
    if(et!=null&&et.getText()!=null){
        if(StringUtil.isEmpty(et.getText().toString())){
            return "";
        }else{
            return et.getText().toString().trim();
        }
    }
    return null;
}

protected void showShortToast(String msg) {
    if (StringUtil.isNotEmpty(msg)) {
        ToastUtil.shortShow(msg);
    }
}

protected void showLongToast(String msg) {
    if (StringUtil.isNotEmpty(msg)) {
        ToastUtil.show(msg);
    }
}

/** 用于初始化控件的 **/
protected  T getView(int rId) {
    View view = this.findViewById(rId);
    return (T) view;
}

}

9.我在Fragment1 中模拟了一个点击TextView显示消息小圆点,大家在用的时候,自己根据实际情况改改就成

ok,今天fragment+viewPager 实现底部导航栏的功能就基本实现了。谢谢诶。

你可能感兴趣的:(fragment+viewPager实现底部导航栏(一))