点击查看上一篇文章:手把手教你如何搭建一个自己的安卓快速开发框架之带你做自己的APP(二)
继上一篇我们的进一步封装,包含
那么,这一篇,我准备加入:
继续来完善我们的快速开发框架。
1、开门见山,看下BaseFragment都做了些什么?
/**
* Created by QHT on 2017-04-08.
*/
public abstract class BaseFragment extends Fragment
{
/**
* 依附的activity
*/
protected FragmentActivity mActivity;
/**
* 根view
*/
protected View mRootView;
@Override
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
if (getContentViewId() != 0) {
mRootView= inflater.inflate(getContentViewId(), null);
} else {
mRootView= super.onCreateView(inflater, container, savedInstanceState);
}
ButterKnife.bind(this, mRootView);
LogUtil.e(this.getClass().getName()+"--->onCreateView");
initData(getArguments());
return mRootView;
}
@Override
public void onAttach(Context context)
{
super.onAttach(context);
mActivity = getActivity();
}
/**
* 设置根布局资源id
* @return
*/
public abstract int getContentViewId();
/**
* 初始化数据
* @param arguments 接收到的从其他地方传递过来的参数
*/
protected void initData(Bundle arguments)
{
}
@Override
public void onResume() {
super.onResume();
LogUtil.e(this.getClass().getName()+"--->onResume");
}
@Override
public void onStop() {
super.onStop();
LogUtil.e(this.getClass().getName()+"--->onStop");
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.e(this.getClass().getName()+"--->onDestroy");
}
}
很简单,做了一些初始化操作。我们的子Fragment只需要继承并重写2个方法即可。
public class FragmentSecond extends BaseFragment {
@Override
public int getContentViewId() {
return R.layout.fragment_second;
}
@Override
protected void initData(Bundle arguments) {
super.initData(arguments);
}
}
因为暂时我们没有用到viewpage,所以不需要懒加载,等下面用到了的时候再加进去。
2、接下来看看我们的仿微信底部菜单栏是怎么做的?
MainActivity的布局呢,就是上面一个toolbar,中间一个Linearlayout用来显示Fragment,下面一个Ralativelayout容纳4个按钮
首先,初始化我们的Fragment状态,第一个fragment为默认加载的Fragment
/**
* 初始化底部标签
*/
private void initTab() {
if (oneFragment == null) {
/** 默认加载第一个Fragment*/
oneFragment = new FragmentFrist();
}
if (!oneFragment.isAdded()) {
/** 如果第一个未被添加,则添加到管理器中*/
getSupportFragmentManager().beginTransaction()
.add(R.id.content_layout, oneFragment).commit();
/** 记录当前Fragment*/
currentFragment = oneFragment;
/** 设置图片文本的变化*/
llBottomIvOne.setImageResource(R.mipmap.bottom_home_click);
llBottomTvOne.setTextColor(getResources()
.getColor(R.color.bottom_click));
llBottomIvTwo.setImageResource(R.mipmap.bottom_notice_normal);
llbottomTvTwo.setTextColor(getResources().getColor(
R.color.bottom_normal));
llBottomIvThree.setImageResource(R.mipmap.bottom_bill_normal);
llBottomTvThree.setTextColor(getResources().getColor(
R.color.bottom_normal));
llBottomIvFour.setImageResource(R.mipmap.bottom_me_normal);
llBottomTvFour.setTextColor(getResources().getColor(
R.color.bottom_normal));
}
}
接下来,当我们点击底部每个按钮时:
/**
* 点击第一个tab
*/
private void clickTab1Layout() {
if (oneFragment == null) {
oneFragment = new FragmentFrist();
}
addOrShowFragment(getSupportFragmentManager().beginTransaction(), oneFragment);
llBottomIvOne.setImageResource(R.mipmap.bottom_home_click);
llBottomTvOne.setTextColor(getResources()
.getColor(R.color.bottom_click));
llBottomIvTwo.setImageResource(R.mipmap.bottom_notice_normal);
llbottomTvTwo.setTextColor(getResources().getColor(
R.color.bottom_normal));
llBottomIvThree.setImageResource(R.mipmap.bottom_bill_normal);
llBottomTvThree.setTextColor(getResources().getColor(
R.color.bottom_normal));
llBottomIvFour.setImageResource(R.mipmap.bottom_me_normal);
llBottomTvFour.setTextColor(getResources().getColor(
R.color.bottom_normal));
}
这个方法用来判断到底是add还是show/hide 我们的Fragment
/**
* 添加或者显示碎片
*
* @param transaction
* @param fragment
*/
private void addOrShowFragment(FragmentTransaction transaction,
Fragment fragment) {
if (currentFragment == fragment)
return;
if (!fragment.isAdded()) {
// 如果当前fragment未被添加,则添加到Fragment管理器中
transaction.hide(currentFragment)
.add(R.id.content_layout,
fragment).commit();
} else {
// 如果当前fragment已被添加,则显示即可
transaction.hide(currentFragment).show(fragment).commit();
}
currentFragment = fragment;
}
3、再来看看我们的空View是怎么实现的呢?
在使用listview时我们见过 setEmptyView() 方法(内部实现原理也是通过 Visible 去控制显示的),但是其他的 view 却没有吧,因此我们实现一个自己的空 View,在什么时候都可以使用。
public class EmptyViewLayout extends RelativeLayout {
private ImageView failure;//加载失败的图片
private View bindView;// 绑定的View,即要显示的View
private Button loading_btn;//重试按钮
public EmptyViewLayout(Context context) {
super(context);
initView(context);
}
public EmptyViewLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private void initView(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.empty_view,null);
failure = (ImageView)view.findViewById(R.id.loading_failure);
loading_btn= (Button) view.findViewById(R.id.loading_btn);
//设置View参数
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
//最后添加进ViewGroup
addView(view, param);
}
/**
*正在加载中
*/
public void Loading() {
setVisibility(View.VISIBLE);
if (bindView != null) {
failure.setVisibility(View.GONE);
loading_btn.setVisibility(View.GONE);
}
}
/**
*加载成功
*/
public void succees() {
setVisibility(View.GONE);
if (bindView != null) {
bindView.setVisibility(View.VISIBLE);
}
}
/**
*加载失败
*/
public void failure() {
setVisibility(View.VISIBLE);
if (bindView != null) {
failure.setVisibility(View.VISIBLE);
bindView.setVisibility(View.GONE);
loading_btn.setVisibility(View.VISIBLE);
}
}
// 绑定加载 的view
public void bindView(View view) {
this.bindView = view;
}
/*
* 利用反射机制,响应对方需要响应的方法
*/
public void buttonClick(final Object base, final String method) {
loading_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
Method m=base.getClass().getDeclaredMethod(method);
m.setAccessible(true);
m.invoke(base, null);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
在布局和Activity中我们这样使用:
/**
*布局中
*/
"@+id/emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar"/>
/**
*Activity中
*/
// 绑定要显示的View
emptyView.bindView(content);
// 注册点击事件,加载失败后点击重试执行onload方法
emptyView.buttonClick(this, "onClick");
在我们的onResponse中执行 emptyView.succees();方法
在我们的onError中执行 emptyView.succees();方法
在我们的onBefore中执行 emptyView.Loading();方法
原理就是利用View的Visible和Gone去控制显示哪个View。
下一篇,我准备开始实现功能了:
(因为我们刚开始选用的接口为快递100的,所以功能上考虑为一款快递查询APP)
我的QQ: 1003077897
我的csdn:http://blog.csdn.net/u012534831
我的github:https://github.com/qht1003077897/AppFrame
我的个人博客:https://qht1003077897.github.io