自定义ViewGroup之TagLayout
来源:互联网 发布:sha-256算法 编辑:程序博客网 时间:2024/05/29 09:55
今天抽空写了一个标签布局,这里为了简单起见,我忽略了onMeasure方法,默认使用屏幕宽度和计算出来的高度作为当前TagLayout的宽度和高度,今天不想写太多话,所以直接上代码了
流式布局简单实现
创建TagLayout
public class TagLayout extends ViewGroup { private int mScreenWidth; public TagLayout(Context context) { this(context, null); } public TagLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TagLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mScreenWidth = wm.getDefaultDisplay().getWidth(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int totalHeight = 0; int totalWidth = 0; View currentChild; int marginLeft = 0; int marginRight = 0; int marginTop = 0; int currentWidth = 0; int currentHeight = 0; int maxHeight = 0; LinearLayout.MarginLayoutParams marginLayoutParams = null; for (int i= 0; i < getChildCount(); i++) { currentChild = getChildAt(i); //记录当前view // 获取当前view的外边距 marginLayoutParams = (MarginLayoutParams) currentChild.getLayoutParams(); marginLeft = marginLayoutParams.leftMargin; marginRight = marginLayoutParams.rightMargin; marginTop = marginLayoutParams.topMargin; // 获取当前view的宽度和高度 currentWidth = currentChild.getMeasuredWidth(); currentHeight = currentChild.getMeasuredHeight(); if (currentHeight > maxHeight) { maxHeight = currentHeight; } // 如果 "当前已有的宽度 + 当前view的宽度 > 屏幕的宽度",则需要重新开启一行 if (currentWidth + marginLeft + marginRight + totalWidth > mScreenWidth) { // a new line totalWidth = 0; totalHeight = totalHeight + maxHeight + marginTop; currentChild.layout(totalWidth + marginLeft,totalHeight + marginTop,totalWidth + marginLeft + currentWidth,totalHeight + marginTop + currentHeight); // 重新为totalWidth赋值,需要新行里绘制的第一个子的宽度计算在里面 totalWidth = totalWidth + currentWidth + marginLeft; } else { currentChild.layout(totalWidth + marginLeft,totalHeight + marginTop,totalWidth + marginLeft + currentWidth,totalHeight + marginTop + currentHeight); // 重新计算当前已有的宽度 totalWidth += currentWidth + marginRight; } } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 测量所有子view measureChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { // 子view使用MarginLayoutParams return new LinearLayout.MarginLayoutParams(getContext(),attrs); }}
布局中使用
<?xml version="1.0" encoding="utf-8"?><com.example.taglayout.TagLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:layout_width="wrap_content" android:layout_height="60dp" android:layout_margin="10dp" android:text="Hello World!" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Hello Worldaaaa!" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Hello World!ddddadfgsadfasd" /> <Button android:layout_width="wrap_content" android:layout_height="60dp" android:layout_margin="10dp" android:text="abcdefghijklmn" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Hello!" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Hel" /></com.example.taglayout.TagLayout>
此时效果如下:
给每一个tag添加背景
这里可以使用shape标签,创建一个圆角矩形
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#99CCFF" /> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp" android:bottomRightRadius="20dp" android:bottomLeftRadius="20dp"/> <stroke android:width="1dp" android:color="#000000" /></shape>
在布局中使用背景
<?xml version="1.0" encoding="utf-8"?><com.example.taglayout.TagLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="Hello World!" android:background="@drawable/tag_background" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="Hello Worldaaaa!" android:background="@drawable/tag_background" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="Hello World!ddddadfgsadfasd" android:background="@drawable/tag_background" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="abcdefghijklmn" android:background="@drawable/tag_background" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="Hello!" android:background="@drawable/tag_background" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="Hel" android:background="@drawable/tag_background" /></com.example.taglayout.TagLayout>
此时效果如下:
动态添加效果
定义一个类似于search的布局,每次搜索,都将该字符串动态添加到TagLayout
SearchLayout
public class SearchLayout extends LinearLayout implements EditInterface, View.OnClickListener { public SearchLayout(Context context) { this(context, null); } public SearchLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } // 文本框 EditText mEditText = null; // 删除提示 TextView mTextView = null; Button mSubmitBtn = null; TagLayout mTagLayout = null; public SearchLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final LayoutInflater layoutInflater = LayoutInflater.from(context); layoutInflater.inflate(R.layout.search_layout, this, true); mEditText = (EditText) findViewById(R.id.edittext); mTextView = (TextView) findViewById(R.id.textview); mSubmitBtn = (Button) findViewById(R.id.id_search); mTagLayout = (TagLayout) findViewById(R.id.id_taglayout); mEditText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int abefore, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { // 根据当前的内容是否==""来决定是否显示删除文字 if (s != null && s.length() == 0) { hiddenCancel(); } else { showCancel(); } } }); mTextView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mEditText.setText(""); } }); // 当点击提交的时候,动态将该搜索的字符添加到该布局中 mSubmitBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { TextView searchText = new TextView(getContext()); searchText.setText(mEditText.getText().toString()); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); searchText.setLayoutParams(params); searchText.setBackground(getContext().getResources().getDrawable(R.drawable.tag_background)); int paddingOrMargin = dp2px(getContext(),10f); params.leftMargin = paddingOrMargin; params.topMargin = paddingOrMargin; params.rightMargin = paddingOrMargin; params.bottomMargin = paddingOrMargin; searchText.setPadding(paddingOrMargin, paddingOrMargin, paddingOrMargin, paddingOrMargin); // 每添加一个view设置其点击事件 searchText.setOnClickListener(SearchLayout.this); mTagLayout.addView(searchText,params); mTagLayout.requestLayout(); } }); // 设置事件监听 int childCount = mTagLayout.getChildCount(); View childTagView = null; for (int i = 0; i < childCount; i ++) { childTagView = mTagLayout.getChildAt(i); childTagView.setOnClickListener(this); } } public static int dp2px(Context context, float dpVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources().getDisplayMetrics()); } @Override public void hiddenCancel() { mTextView.setVisibility(View.GONE); } @Override public void showCancel() { mTextView.setVisibility(View.VISIBLE); } @Override public void onClick(View v) { mEditText.setText(((TextView)v).getText().toString()); }}// 自己定义接口,用来控制显示和隐藏当前删除按钮interface EditInterface { public void hiddenCancel(); public void showCancel();}
创建SearchLayout引用的布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/edittext" android:layout_width="0dp" android:layout_height="100dp" android:layout_weight="4" android:singleLine="true" /> <TextView android:id="@+id/textview" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" android:text="删除" android:textColor="#ff0000" android:visibility="invisible" /> <Button android:id="@+id/id_search" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:text="搜索" /> </LinearLayout> <com.example.taglayout.TagLayout android:id="@+id/id_taglayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="Hello World!" android:background="@drawable/tag_background" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="一个神器的网站" android:background="@drawable/tag_background" /> /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:padding="10dp" android:text="你不是真正的快乐" android:background="@drawable/tag_background" /> </com.example.taglayout.TagLayout></LinearLayout>
在主布局中使用SearchLayout
<?xml version="1.0" encoding="utf-8"?><com.example.taglayout.SearchLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" ></com.example.taglayout.SearchLayout>
此时效果如下:
今天就到这了,不想说太多话,源码下载
0 0
- 自定义ViewGroup之TagLayout
- 自定义一个TagLayout
- android之自定义ViewGroup
- Android之自定义ViewGroup
- Android之自定义ViewGroup
- Android之自定义ViewGroup
- 自定义ViewGroup之别踩白块
- Android 学习之--自定义ViewGroup
- 自定义ViewGroup之卫星菜单
- Android学习之自定义ViewGroup
- 自定义ViewGroup之扩展FloatingActionButton
- 自定义viewgroup实践之仿写LinearLayout
- 自定义ViewGroup之margin和padding
- Android知识梳理之自定义ViewGroup
- android之自定义viewGroup仿scrollView详解
- 自定义View学习笔记之继承ViewGroup
- 安卓学习笔记之自定义ViewGroup
- Android自定义ViewGroup(一)之CustomGridLayout
- (十六)剑指offer之二叉搜索树的后序遍历序列
- OpenCV--滑动条的创建-creatTrackbar() [addWeighted()]
- 应用集成实战系列:服务总线中的异步业务交互模式
- 【数据结构】-线性表-链表-1326:链表的基本操作【好题】
- signal check
- 自定义ViewGroup之TagLayout
- [Java基础] 创建一个对象数组
- 【BZOJ 1299】[LLH邀请赛]巧克力棒 博弈论
- 史上最全的微信小程序代码大全
- 一个基于Python的文本处理程序
- jzoj 4941. 【GDKOI2017模拟1.13】宝石魔术 生成函数
- C++标准模板库基础练习(必会)
- 一天一点android知识(Broadcast)
- test