美文网首页
Android Fragment工程学习笔记

Android Fragment工程学习笔记

作者: 新地球说着一口陌生腔调 | 来源:发表于2020-03-12 17:00 被阅读0次

    首先工程来自github上的Android工程 FragmentNavigator,新手有兴趣可以去下载运行。


    看了工程所有的代码,我来总结一下主要的实现步骤:

    主要使用以下两个类 FragmentNavigator、BottomNavigatorView来实现下方tabBar控制器切换(Android通常叫做Fragment,因本人做iOS的)

    private FragmentNavigator mNavigator;

    private BottomNavigatorView bottomNavigatorView;//底部tab区域视图

    1、其中FragmentNavigator是封装的类,定义了showFragment

    方法  ,BottomNavigatorView继承于LinearLayoutCompat(其中LinearLayoutCompat是对LinearLayout扩展和兼容

    2、MainActivity实现了BottomNavigatorView

    类的OnBottomNavigatorViewItemClickListener

    接口,BottomNavigatorView

    类实现了如下构造方法

    public BottomNavigatorView(Context context, AttributeSet attrs,int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        setOrientation(HORIZONTAL);

        inflate(context, R.layout.layout_bottom_navigator,this);

        for (int i =0; i < getChildCount(); i++) {

            View view = getChildAt(i);

            final int finalI = i;

            view.setOnClickListener(new OnClickListener() {

                @Override //点击tab会调用

                public void onClick(View v) {//tab事件首先在这里触发的!!!!

                    System.out.println("setOnClickListener1");

                    //调用了接口方法,onBottomNavigatorViewItemClick方法在MainActivity类中实现

                    mOnBottomNavigatorViewItemClickListener.onBottomNavigatorViewItemClick(finalI, v);

                }

            });

        }

    }

    MainActivity类中

    @Override  //实现了接口方法

    public void onBottomNavigatorViewItemClick(int position, View view) {

        System.out.println("我响应了接口方法");

        setCurrentTab(position);

    }

    private void setCurrentTab(int position) {

        mNavigator.showFragment(position);//用来实现切换动画

        bottomNavigatorView.select(position);//用来选中tab位置,改变tab文字与图标颜色

    }

    其中showFragment方法是FragmentNavigator

    类封装的,select方法是BottomNavigatorView

    类封装的

    public void showFragment(int position,boolean reset,boolean allowingStateLoss) {

        this.mCurrentPosition = position;

        FragmentTransaction transaction =mFragmentManager.beginTransaction();

        int count =mAdapter.getCount();

        for (int i =0; i < count; i++) {

            if (position == i) {

                if (reset) {

                    remove(position, transaction);

                    add(position, transaction);

                }else {

                    show(i, transaction);

                }

            }else {

                hide(i, transaction);

            }

        }

        if (allowingStateLoss) {

            transaction.commitAllowingStateLoss();

        }else {

            transaction.commit();

        }

    }

    //点击tab会调用

        public void select(int position) {

            System.out.println("position:"+position);

            for (int i =0; i < getChildCount(); i++) {

                View child = getChildAt(i);

                if (i == position) {

                    selectChild(child,true);

                }else {

                    selectChild(child,false);

                }

            }

        }

    3、在MainActivity类中构造方法中

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mNavigator =new FragmentNavigator(getSupportFragmentManager(),new FragmentAdapter(), R.id.container);

        mNavigator.setDefaultPosition(DEFAULT_POSITION);//设置tab的默认位置

        mNavigator.onCreate(savedInstanceState);

        bottomNavigatorView = (BottomNavigatorView) findViewById(R.id.bottomNavigatorView);

        if (bottomNavigatorView != null) {

            bottomNavigatorView.setOnBottomNavigatorViewItemClickListener(this);//把实例对象传给了BottomNavigatorView

    类中的接口OnBottomNavigatorViewItemClickListener

        }

        setCurrentTab(mNavigator.getCurrentPosition());

       //注册广播

        BroadcastManager.register(this,mLoginStatusChangeReceiver, Action.LOGIN, Action.LOGOUT);

    }

    其中做了三件很重要的事情:

    1、设置tab的默认位置

    2、创建BottomNavigatorView类,并把当前实例传给BottomNavigatorView的接口OnBottomNavigatorViewItemClickListener,

    3、注册广播(类似iOS开发中的NSNotificationCenter),register可以传字符串数组,用于登录后页面的切换跳转,数据的存储。

    接口interface定义onBottomNavigatorViewItemClick方法:

    public interface OnBottomNavigatorViewItemClickListener {

        void onBottomNavigatorViewItemClick(int position, View view);

    }

    其中Java的interface类似iOS中的协议Protocol(代理Delegete)

    4、广播的创建与接收,BroadcastReceiver是一个abstract

    抽象类

    private BroadcastReceivermLoginStatusChangeReceiver =new BroadcastReceiver() {

        @Override//接受广播回调

        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            if (!TextUtils.isEmpty(action)) {

                int position = intent.getIntExtra("EXTRA_POSITION", -1);

                if (action.equals(Action.LOGIN)) {

                    onUserLogin(position);

                }else if (action.equals(Action.LOGOUT)) {

                    onUserLogout(position);

                }

            }

        }

    };

    控制器销毁时要移除广播的注册unregister

    @Override

    protected void onDestroy() {

        BroadcastManager.unregister(this,mLoginStatusChangeReceiver);

        super.onDestroy();

    }

    如何在XML文件中引入Java类名 <com.aspsine.fragmentnavigator.demo.ui.widget.BottomNavigatorView

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

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        xmlns:tools="http://schemas.android.com/tools"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical"

        tools:context=".ui.activity.MainActivity">

        <FrameLayout

            android:id="@+id/container"

            android:layout_width="match_parent"

            android:layout_height="0dp"

            android:layout_weight="1" />

        <com.aspsine.fragmentnavigator.demo.ui.widget.BottomNavigatorView

            android:id="@+id/bottomNavigatorView"

            android:layout_width="match_parent"

            android:layout_height="56dp"

            android:clipToPadding="false"

            android:background="@android:color/white"

            android:elevation="8dp" />

    </LinearLayout>



    另外提醒:作者封装了两个类在library文件夹中:FragmentNavigator、接口 FragmentNavigatorAdapter

    相关文章

      网友评论

          本文标题:Android Fragment工程学习笔记

          本文链接:https://www.haomeiwen.com/subject/jvrmjhtx.html