1,网络监听 并及时通知观察者 优势,一个广播接收者,可以搞定整个应用中需要监听网络的地方。集中处理一件事
注册 一个 广播接收者,用来监听网络的变化,并做为被观察者当前 网络的状态
当 activity 或 其他组件需要 监听网络变化时,注册观察者,当 不需要时,取消注册
2,snackbar 代替 toast ,弹出方式更先进,可以接收点击事件,可操作更多。 需要判断虚拟键挡住 snackbar 的 问题
3,Activity 工具类,在oncreate中加入 工具类中,ondestory时 从 工具类中删除 activity, 便于管理activity ,便于 销毁指定的activity ,退出程序时销毁所有的activity.
4,Application 中,exitApp()方法,当两次点击需要退出程序时调用:主要api : android.os.Process.killProcess(android.os.Process.myPid()); 及System.exit(0)
5,MVP模式:该项目中 activity 或 fragment 作为 实现view 接口 , presenter 相当于个装饰者,将 view 和 model联系人一块。 在activity 或 fragment中,或取 persenter 对象,并渲染 view 。 注:从activity中的代码中看,个人感觉优化不是特别明显,是否应该会有更好的方式呢?
6,baseActivity:项目中,基类 activity 中,把生命周期中的方法,尽可能的用抽象方法实现,然后子类去实现抽象方法,这样,子类尽可能的屏蔽了生命周期相关的处理。感觉这种处理方式很好,特别是涉及到共性的修改时,可以在基类中统一处理
7,Fragment 在 baseFragment中,同 baseActivity中一样,用抽象方法去实现 然后子类实现抽象方法。
public abstract class BaseLazyFragment extends Fragment {
/**
* Log tag
*/
protected static String TAG_LOG = null;
/**
* Screen information
*/
protected int mScreenWidth = 0;
protected int mScreenHeight = 0;
protected float mScreenDensity = 0.0f;
/**
* context
*/
protected Context mContext = null;
private boolean isFirstResume = true;
private boolean isFirstVisible = true;
private boolean isFirstInvisible = true;
private boolean isPrepared;
private VaryViewHelperController mVaryViewHelperController = null;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO something like EventBus register
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (getContentViewLayoutID() != 0) {
return inflater.inflate(getContentViewLayoutID(), null);
} else {
return super.onCreateView(inflater, container, savedInstanceState);
}
// TODO return view
}
// TODO onViewCreated() after onCreateView
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// TODO findView,initView
ButterKnife.inject(this, view);
if (null != getLoadingTargetView()) {
mVaryViewHelperController = new VaryViewHelperController(getLoadingTargetView());
}
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mScreenDensity = displayMetrics.density;
mScreenHeight = displayMetrics.heightPixels;
mScreenWidth = displayMetrics.widthPixels;
initViewsAndEvents();
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.reset(this);
}
@Override
public void onDestroy() {
super.onDestroy();
if (isBindEventBusHere()) {
EventBus.getDefault().unregister(this);
}
}
@Override
public void onDetach() {
super.onDetach();
// for bug ---> java.lang.IllegalStateException: Activity has been destroyed
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// after onViewCreated()
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// TODO IDentify this fragment first visible
initPrepare();
}
@Override
public void onResume() {
super.onResume();
if (isFirstResume) {
isFirstResume = false;
return;
}
if (getUserVisibleHint()) {
onUserVisible();
}
}
@Override
public void onPause() {
super.onPause();
if (getUserVisibleHint()) {
onUserInvisible();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
if (isFirstVisible) {
isFirstVisible = false;
initPrepare();
} else {
onUserVisible();
}
} else {
if (isFirstInvisible) {
isFirstInvisible = false;
onFirstUserInvisible();
} else {
onUserInvisible();
}
}
}
private synchronized void initPrepare() {
if (isPrepared) {
onFirstUserVisible();
} else {
isPrepared = true;
}
}
/**
* when fragment is visible for the first time, here we can do some initialized work or refresh data only once
*/
protected abstract void onFirstUserVisible();
/**
* this method like the fragment's lifecycle method onResume()
*/
protected abstract void onUserVisible();
/**
* when fragment is invisible for the first time
*/
private void onFirstUserInvisible() {
// here we do not recommend do something
}
/**
* this method like the fragment's lifecycle method onPause()
*/
protected abstract void onUserInvisible();
/**
* get loading target view
*/
protected abstract View getLoadingTargetView();
/**
* init all views and add events
*/
protected abstract void initViewsAndEvents();
/**
* bind layout resource file
*
* @return id of layout resource
*/
protected abstract int getContentViewLayoutID();
}