前言,最近在做一个需求,要求实现一个标签的位置在屏幕的中间,固定标签为3,当屏幕显示不下时则移除不能显示的子控件,最终研究来是用自定义控件来实现,即方便自己也方便大家。
下面是给出的原型图,红色的就是标签,如果屏幕显示不下,可能显示为2个,1个。下面我们开始研究。
一、首先我们需要实现对控件的添加,代码如下,在代码中我们可以看到 ,我们在初始化控件时就要先移除所有的标签 ,然后再去循环添加标签 。
public void init(Activity activity, List<String> stringList) {
//移除所有控件
removeAllViews();
ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
for (int i = 0; i < stringList.size(); i++) {
TextView tv = new TextView(getContext());
tv.setText(stringList.get(0));
tv.setTextColor(getResources().getColor(R.color.color_F18d00));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
tv.setMaxLines(1);
tv.setBackgroundResource(R.drawable.icon_coupon_frame);
lp.leftMargin = DensityUtils.dp2px(5);
addView(tv, lp);
}
}
二、这时我们就要去计算控件的宽度,是不是超过了父控件的宽度,我们这里是根据getLeft()和getRight()来实现的,我以前的文章有分析getLeft和getRight的关系,这里就是根据这个来计算的,可以看下图,可以看到第三个是超过父控件的范围了,我们就判断父控件的getLeft+第三个的getRight大于父控件的宽度的,所以我们就要把第三个移除出去。代码如下:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
//如果超过父控件的宽度则移除子控件,并保留一个
for (int i = 0; i < getChildCount(); i++) {
int right = getChildAt(i).getRight() + getLeft();
if (right > getRight() && getChildCount() > 1) {
if (i == 0) {
remove(1, getChildCount() - 1);
} else {
remove(i, getChildCount() - i - 1);
}
break;
}
}
}
/**
* 延迟移除控件,否则会不能及时刷新
*
* @param start
* @param count
*/
private void remove(int start, int count) {
postDelayed(new Runnable() {
@Override
public void run() {
removeViews(start, count);
}
}, 100);
}
到此就完成了所有的操作。以后会在github上放上源码,先写篇文章。不过如果是父控件的的父控件是HorizontalScrollView,则这么判断是不准确的。到时候会再更新文章。