首先工程来自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
网友评论