前言,最近在做一個需求,要求實現一個標籤的位置在屏幕的中間,固定標籤爲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,則這麼判斷是不準確的。到時候會再更新文章。