Android自定义标签流式布局

2018-10-15  本文已影响0人  程序猿峰岑

1.定义流式布局属性

<declare-styleable name="TagCloudView">

    <attr name="tcvBackground" format="reference" />

    <attr name="tcvTextColor" format="color" />

    <attr name="tcvBorder" format="dimension" />

    <attr name="tcvTextSize" format="dimension" />

    <attr name="tcvBorderItem" format="dimension" />

    <attr name="tcvItemBorderVertical" format="dimension" />

    <attr name="tcvItemBorderHorizontal" format="dimension" />

    <attr name="tcvSingleLine" format="boolean" />

    <attr name="tcvShowEndText" format="boolean" />

    <attr name="tcvShowRightImg" format="boolean" />

    <attr name="tcvEndText" format="string" />

    <attr name="tcvRightResId" format="reference" />

    <attr name="tcvCanTagClick" format="boolean" />

    <attr name="tcvTagResId" format="reference" />

</declare-styleable>

2.自定义View
public class TagCloudViewextends ViewGroup{

private static final StringTAG = TagCloudView.class.getSimpleName();

    private static final int TYPE_TEXT_NORMAL =1;

    private Listtags;

    private LayoutInflatermInflater;

    private OnTagClickListeneronTagClickListener;

    private int sizeWidth;

    private int sizeHeight;

    private float mTagSize;

    private int mTagColor;

    private int mBackground;

    private int mViewBorder;

    private int mTagBorderHor;

    private int mTagBorderVer;

    private int mTagResId;

    private int mRightImageResId;

    private boolean mSingleLine;

    private boolean mShowRightImage;

    private boolean mShowEndText;

    private boolean mCanTagClick;

    private StringendTextString;

    private int imageWidth;

    private int imageHeight;

    private ImageViewimageView =null;

    private int endTextWidth =0;

    private int endTextHeight =0;

    private TextViewendText =null;

    private static final int DEFAULT_TEXT_COLOR = Color.WHITE;

    private static final int DEFAULT_TEXT_SIZE =14;

    private static final int DEFAULT_TEXT_BACKGROUND = R.drawable.tag_background;

    private static final int DEFAULT_VIEW_BORDER =6;

    private static final int DEFAULT_TEXT_BORDER_HORIZONTAL =8;

    private static final int DEFAULT_TEXT_BORDER_VERTICAL =5;

    private static final int DEFAULT_TAG_RESID = R.layout.item_tag;

    private static final int DEFAULT_RIGHT_IMAGE = R.drawable.arrow_right;

    private static final boolean DEFAULT_SINGLE_LINE =false;

    private static final boolean DEFAULT_SHOW_RIGHT_IMAGE =true;

    private static final boolean DEFAULT_SHOW_END_TEXT =true;

    private static final StringDEFAULT_END_TEXT_STRING =" 鈥� ";

    private static final boolean DEFAULT_CAN_TAG_CLICK =true;

    public TagCloudView(Context context) {

this(context, null);

    }

public TagCloudView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

    }

public TagCloudView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

        mInflater = LayoutInflater.from(context);

        TypedArray a = context.getTheme().obtainStyledAttributes(

attrs,

                R.styleable.TagCloudView,

                defStyleAttr,

                defStyleAttr

);

        mTagSize = a.getDimension(R.styleable.TagCloudView_tcvTextSize, DEFAULT_TEXT_SIZE);

        mTagColor = a.getColor(R.styleable.TagCloudView_tcvTextColor, DEFAULT_TEXT_COLOR);

        mBackground = a.getResourceId(R.styleable.TagCloudView_tcvBackground, DEFAULT_TEXT_BACKGROUND);

        mViewBorder = a.getDimensionPixelSize(R.styleable.TagCloudView_tcvBorder, DEFAULT_VIEW_BORDER);

        mTagBorderHor = a.getDimensionPixelSize(

R.styleable.TagCloudView_tcvItemBorderHorizontal, DEFAULT_TEXT_BORDER_HORIZONTAL);

        mTagBorderVer = a.getDimensionPixelSize(

R.styleable.TagCloudView_tcvItemBorderVertical, DEFAULT_TEXT_BORDER_VERTICAL);

        mCanTagClick = a.getBoolean(R.styleable.TagCloudView_tcvCanTagClick, DEFAULT_CAN_TAG_CLICK);

        mRightImageResId = a.getResourceId(R.styleable.TagCloudView_tcvRightResId, DEFAULT_RIGHT_IMAGE);

        mSingleLine = a.getBoolean(R.styleable.TagCloudView_tcvSingleLine, DEFAULT_SINGLE_LINE);

        mShowRightImage = a.getBoolean(R.styleable.TagCloudView_tcvShowRightImg, DEFAULT_SHOW_RIGHT_IMAGE);

        mShowEndText = a.getBoolean(R.styleable.TagCloudView_tcvShowEndText, DEFAULT_SHOW_END_TEXT);

        endTextString = a.getString(R.styleable.TagCloudView_tcvEndText);

        mTagResId = a.getResourceId(R.styleable.TagCloudView_tcvTagResId, DEFAULT_TAG_RESID);

        a.recycle();

    }

@Override

    public boolean onInterceptTouchEvent(MotionEvent ev) {

return (!mCanTagClick &&mSingleLine) ||super.onInterceptTouchEvent(ev);

    }

@Override

    protected void onLayout(boolean changed, int l, int t, int r, int b) {

}

/**

    * 璁$畻 ChildView 瀹介珮

    * @param widthMeasureSpec

    * @param heightMeasureSpec

    */

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

/**

        * 璁$畻 ViewGroup 涓婄骇瀹瑰櫒涓哄叾鎺ㄨ崘鐨勫楂�

        */

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        sizeWidth = MeasureSpec.getSize(widthMeasureSpec);

        sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

        //璁$畻 childView 瀹介珮

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        initSingleLineView(widthMeasureSpec, heightMeasureSpec);

        int totalWidth =0;

        int totalHeight =mTagBorderVer;

        if (mSingleLine) {

totalHeight = getSingleTotalHeight(totalWidth, totalHeight);

        }else {

totalHeight = getMultiTotalHeight(totalWidth, totalHeight);

        }

/**

        * 楂樺害鏍规嵁璁剧疆鏀瑰彉

        * 濡傛灉涓� MATCH_PARENT 鍒欏厖婊$埗绐椾綋锛屽惁鍒欐牴鎹唴瀹硅嚜瀹氫箟楂樺害

        */

        setMeasuredDimension(

sizeWidth,

                (heightMode == MeasureSpec.EXACTLY ?sizeHeight : totalHeight));

    }

/**

    * 鍒濆鍖� singleLine 妯″紡闇�瑕佺殑瑙嗗浘

    * @param widthMeasureSpec

    * @param heightMeasureSpec

    */

    private void initSingleLineView(int widthMeasureSpec, int heightMeasureSpec) {

if (!mSingleLine) {

return;

        }

if (mShowRightImage) {

imageView =new ImageView(getContext());

            imageView.setImageResource(mRightImageResId);

            imageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

            imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

            measureChild(imageView, widthMeasureSpec, heightMeasureSpec);

            imageWidth =imageView.getMeasuredWidth();

            imageHeight =imageView.getMeasuredHeight();

            addView(imageView);

        }

if (mShowEndText) {

endText = (TextView)mInflater.inflate(mTagResId, null);

            if (mTagResId ==DEFAULT_TAG_RESID) {

endText.setBackgroundResource(mBackground);

                endText.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTagSize);

                endText.setTextColor(mTagColor);

            }

LayoutParams layoutParams =new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

            endText.setLayoutParams(layoutParams);

            endText.setText(endTextString ==null ||endTextString.equals("") ?DEFAULT_END_TEXT_STRING :endTextString);

            measureChild(endText, widthMeasureSpec, heightMeasureSpec);

            endTextHeight =endText.getMeasuredHeight();

            endTextWidth =endText.getMeasuredWidth();

            addView(endText);

            endText.setOnClickListener(new OnClickListener() {

@Override

                public void onClick(View view) {

if (onTagClickListener !=null) {

onTagClickListener.onTagClick(-1);

                    }

}

});

        }

}

/**

    * 涓� singleLine 妯″紡甯冨眬锛屽苟璁$畻瑙嗗浘楂樺害

    * @param totalWidth

    * @param totalHeight

    * @return

    */

    private int getSingleTotalHeight(int totalWidth, int totalHeight) {

int childWidth;

        int childHeight;

        totalWidth +=mViewBorder;

        int textTotalWidth = getTextTotalWidth();

        if (textTotalWidth

endText =null;

            endTextWidth =0;

        }

for (int i =0; i < getChildCount(); i++) {

View child = getChildAt(i);

            childWidth = child.getMeasuredWidth();

            childHeight = child.getMeasuredHeight();

            if (i ==0) {

totalWidth += childWidth;

                totalHeight = childHeight +mViewBorder;

            }else {

totalWidth += childWidth +mTagBorderHor;

            }

if (child.getTag() !=null && (Integer)child.getTag() ==TYPE_TEXT_NORMAL) {

if (totalWidth +mTagBorderHor +mViewBorder +mViewBorder +endTextWidth +imageWidth

child.layout(

totalWidth - childWidth +mTagBorderVer,

                            totalHeight - childHeight,

                            totalWidth +mTagBorderVer,

                            totalHeight);

                }else {

totalWidth -= childWidth +mViewBorder;

break;

                }

}

}

if (endText !=null) {

endText.layout(

totalWidth +mViewBorder +mTagBorderVer,

                    totalHeight -endTextHeight,

                    totalWidth +mViewBorder +mTagBorderVer +endTextWidth,

                    totalHeight);

        }

totalHeight +=mViewBorder;

        if (imageView !=null) {

imageView.layout(

sizeWidth -imageWidth -mViewBorder,

                    (totalHeight -imageHeight) /2,

                    sizeWidth -mViewBorder,

                    (totalHeight -imageHeight) /2 +imageHeight);

        }

return totalHeight;

    }

/**

    * 涓� multiLine 妯″紡甯冨眬锛屽苟璁$畻瑙嗗浘楂樺害

    * @param totalWidth

    * @param totalHeight

    * @return

    */

    private int getMultiTotalHeight(int totalWidth, int totalHeight) {

int childWidth;

        int childHeight;

        for (int i =0; i < getChildCount(); i++) {

View child = getChildAt(i);

            childWidth = child.getMeasuredWidth();

            childHeight = child.getMeasuredHeight();

            totalWidth += childWidth +mViewBorder;

            if (i ==0) {

totalHeight = childHeight +mViewBorder;

            }

// + marginLeft 淇濊瘉鏈�鍙充晶涓� ViewGroup 鍙宠竟璺濇湁杈圭晫

            if (totalWidth +mTagBorderHor +mViewBorder>sizeWidth) {

totalWidth =mViewBorder;

                totalHeight += childHeight +mTagBorderVer;

                child.layout(

totalWidth +mTagBorderHor,

                        totalHeight - childHeight,

                        totalWidth + childWidth +mTagBorderHor,

                        totalHeight);

                totalWidth += childWidth;

            }else {

child.layout(

totalWidth - childWidth +mTagBorderHor,

                        totalHeight - childHeight,

                        totalWidth +mTagBorderHor,

                        totalHeight);

            }

}

return totalHeight +mViewBorder;

    }

private int getTextTotalWidth() {

if (getChildCount() ==0) {

return 0;

        }

int totalChildWidth =0;

        for (int i =0; i < getChildCount(); i++) {

View child = getChildAt(i);

            if (child.getTag() !=null && (Integer)child.getTag() ==TYPE_TEXT_NORMAL) {

totalChildWidth += child.getMeasuredWidth() +mViewBorder;

            }

}

return totalChildWidth +mTagBorderHor *2;

    }

@Override

    public LayoutParamsgenerateLayoutParams(AttributeSet attrs) {

return super.generateLayoutParams(attrs);

    }

public void setTags(List tagList) {

this.tags = tagList;

        if (tags !=null &&tags.size() >0) {

for (int i =0; i

TextView tagView = (TextView)mInflater.inflate(mTagResId, null);

                if (mTagResId ==DEFAULT_TAG_RESID) {

tagView.setBackgroundResource(mBackground);

                    tagView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTagSize);

                    tagView.setTextColor(mTagColor);

                }

LayoutParams layoutParams =new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

                tagView.setLayoutParams(layoutParams);

                tagView.setText(tags.get(i));

                tagView.setTag(TYPE_TEXT_NORMAL);

                final int finalI = i;

                tagView.setOnClickListener(new OnClickListener() {

@Override

                    public void onClick(View v) {

if (onTagClickListener !=null) {

onTagClickListener.onTagClick(finalI);

                        }

}

});

                addView(tagView);

            }

}

postInvalidate();

    }

public void setOnTagClickListener(OnTagClickListener onTagClickListener) {

this.onTagClickListener = onTagClickListener;

    }

public interface OnTagClickListener{

void onTagClick(int position);

    }

}

3.xml布局文件设置标签流式布局

android:id="@+id/chooseTypePop"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    app:tcvBackground="@drawable/background_tag_selector"

    app:tcvBorder="8dp"

    app:tcvCanTagClick="false"

    app:tcvItemBorderHorizontal="8dp"

    app:tcvItemBorderVertical="6dp"

    app:tcvSingleLine="false"

    app:tcvTagResId="@layout/item_tag_style"

    app:tcvTextColor="@color/compnay_show_type_tag_text_bg"

    android:background="@color/white"/>

4.结合popupwindow使用

if (popupWindow ==null) {

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  view = layoutInflater.inflate(R.layout.choose_type_pop, null);

  chooseTypePopView = (TagCloudView)view.findViewById(R.id.chooseTypePop);

  chooseTypePopView.setTags(tags);

  chooseTypePopView.setOnTagClickListener(onTagClickListener);

  // 创建一个PopuWidow对象

  popupWindow =new PopupWindow(view, displayWidth, displayHeight);

  popupWindow.setAnimationStyle(R.style.PopupWindowAnimation);

}

// 使其聚集

popupWindow.setFocusable(true);

// 设置允许在外点击消失

popupWindow.setOutsideTouchable(true);

// 这个是为了点击“返回Back”也能使其消失,并且并不会影响你的背景

popupWindow.setBackgroundDrawable(new BitmapDrawable());

// WindowManager windowManager = (WindowManager) context

// .getSystemService(Context.WINDOW_SERVICE);

popupWindow.showAsDropDown(parent, 0, dip2px(10));

popupWindow.setOnDismissListener(new OnDismissListener() {

@Override

  public void onDismiss() {

arrowImg.setSelected(false);

  }

});

typeLy.setOnClickListener(new View.OnClickListener() {

@Override

  public void onClick(View view) {

arrowImg.setSelected(false);

      popupWindow.dismiss();

  }

});

上一篇下一篇

猜你喜欢

热点阅读