...">
美文网首页
Android自定义标签流式布局

Android自定义标签流式布局

作者: 程序猿峰岑 | 来源:发表于2018-10-15 10:23 被阅读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();

      }

    });

    相关文章

      网友评论

          本文标题:Android自定义标签流式布局

          本文链接:https://www.haomeiwen.com/subject/dxoxzftx.html