前言
在项目中,经常会使用到空布局,但网上普遍的方法需要侵入到布局中,代码耦合太严重,不同界面需要重复引入布局,或者使用自定义viewgroup,并且对于老项目的使用、修改的工作量非常大;参考badgeview的实现方式,本文将逐步介绍:
内容
核心代码如下
/**
* 仅将布局添加到targetview
*/
public void partial() {
if (targetView == null) return;
ViewGroup parent = (ViewGroup) targetView.getParent();
//内容view的位置
int index = parent.indexOfChild(targetView);
ViewGroup.LayoutParams targetParams = targetView.getLayoutParams();
parent.removeView(targetView);
ViewGroup emptyContainer;
if (targetParams instanceof ViewGroup.MarginLayoutParams) {//父容器是ConstraintLayout、RelativeLayout
emptyContainer = new ConstraintLayout(mContext);
emptyContainer.setId(targetView.getId());
targetView.setId(-1);
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) targetParams;
emptyContainer.setLayoutParams(layoutParams);
parent.addView(emptyContainer, index, layoutParams);
} else {
emptyContainer = new FrameLayout(mContext);
emptyContainer.setLayoutParams(targetParams);
parent.addView(emptyContainer, index, targetParams);
}
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(
ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT);
emptyContainer.addView(targetView, params);
emptyContainer.addView(mEmptyView, params);
emptyContainer.addView(mErrorView, params);
emptyContainer.addView(mLoadView, params);
showContent();
}
原理分析:通过targetview获取到父容器parent,并获取targetview于父容器的位置index,创建一个viewgroup的新容器container,使用container在parent中替换掉targetveiw,然后将targetview、emptyview、errorview添加到container;需要注意的是parent为ConstraintLayout、RelativeLayout时,其LayoutParams未MarginLayoutParams,需要特殊处理。
在项目使用中,当加载到emptyview或者errorview时,有点击重新请求数据的需求,修改代码为emptyview、errorview添加点击事件:
private void initListener() {
mEmptyView.setTag(LoadType.EMPTY);
mErrorView.setTag(LoadType.ERROR);
mEmptyView.setOnClickListener(this);
mErrorView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
ViewUtils.setDelayedClickable(v, 500);
Object object = v.getTag();
if (null != object) {
LoadType ta