您的位置:首页 > 移动开发

手把手教你如何搭建一个自己的安卓快速开发框架之带你做自己的APP(三)

2017-04-10 23:40 1416 查看
点击查看上一篇文章:手把手教你如何搭建一个自己的安卓快速开发框架之带你做自己的APP(二)

继上一篇我们的进一步封装,包含

OkhttpRequest

EventBus

Json解析,基类数据封装

ButterKnife

那么,这一篇,我准备加入:

BaseFragment

精美的仿微信底部菜单栏

网络请求失败时如何显示空View

继续来完善我们的快速开发框架。

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中我们这样使用:

/**
*布局中
*/
<com.qht.blog2.View.EmptyViewLayout
android:id="@+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)

Fragment 和 ViewPage 结合实现顶部标签切换

RecycleView 实现精美的订单追踪页面

我的QQ: 1003077897

我的csdn:http://blog.csdn.net/u012534831

我的github:https://github.com/qht1003077897/AppFrame

我的个人博客:https://qht1003077897.github.io
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  开发框架 android app