1.定义流式布局属性
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();
}
});