自定义布局子流布局实现标签功能
来源:互联网 发布:阿里云 免费开通码 编辑:程序博客网 时间:2024/05/26 20:22
在这里我先简单的对我自己在写自定义布局之流布局的一个总结
1.流布局我个人认为就是当前子View的宽度大于当前行剩余宽度时当前子View就自动换到下一行进行显示
所以在写该功能最大的挑战就是算出什么时候当前子View需要进行换行
2.在写该布局的时候一定要对当前布局和子View进行测量不然我们会获取不到当前子View和布局的宽度和高度
3.因为是初学者可能有些地方不规范请各位大神指导
这里我直接贴出代码 自定义View类的代码
public class FlowLayout extends ViewGroup { private static final String TAG ="test" ; //子Viwe之间的间隔 private int childSpace; //用户设置子View的高度 private int userSetChildHight; public FlowLayout(Context context) { this(context, null); } public FlowLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FlowLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout); //自定义属性获取每个孩子之间的宽度 childSpace =typedArray.getDimensionPixelSize(R.styleable.FlowLayout_childSpace,10); //每个孩子的宽度 userSetChildHight = typedArray.getDimensionPixelSize(R.styleable.FlowLayout_childHight,35); } /** * 进行添加view * @param view */ public void addView(List<View> view){ for (View v:view) { //使用该方法将自己的子view添加到ViewGroup中如果没有布局将是空白 this.addView(v,new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //子View的行数 int row =1; int left =0; int right =0; int top =0; int bottom =0; int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int lastWidth =0; int width =getWidth(); for(int i =0;i<getChildCount();i++) { //获取除过当前子View前面所有子View的宽度 if (i != 0) { lastWidth += getChildAt(i - 1).getWidth(); } else { lastWidth = 0; } View view = getChildAt(i); //进行判断是否需要换行 // 换行条件判断当前子View的宽度是否小于或者等于最大宽度减去获取除过当前子View前面所有子View的宽度再减去所有子View之间的距离 if (view.getMeasuredWidth() <= width - lastWidth - childSpace * (i)) { left = paddingLeft + right + childSpace; right = left+view.getMeasuredWidth()+childSpace; top = paddingTop * row + userSetChildHight * (row - 1); bottom = top + userSetChildHight; view.layout(left, top, right, bottom); } else { row++; right = 0; left = paddingLeft + right + childSpace; right =left+view.getMeasuredWidth()+childSpace; top = paddingTop * row + userSetChildHight * (row - 1); bottom = top + userSetChildHight; view.layout(left, top, right, bottom); } Log.d(TAG,view.getMeasuredWidth()+"width"+width+"lastWidth"+lastWidth+"childSpace * (i - 1)"+childSpace * (i - 1)); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获得它的父容器为它设置的测量模式和大小 int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); // 如果是warp_content情况下,记录宽和高 int width = 0; int height = 0; int cCount = getChildCount(); // 遍历每个子元素测量子View的宽和高是非常重要的不然在onLayout中view.getMeasuredWidth()会一直为0 for (int i = 0; i < cCount; i++) { View child = getChildAt(i); // 测量每一个child的宽和高 measureChild(child, widthMeasureSpec, heightMeasureSpec); } setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth : width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight : height); }}
布局中使用
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.as.myapplication.MainActivity"> <com.example.as.myapplication.FlowLayout android:id="@+id/myView" android:layout_width="match_parent" android:layout_height="match_parent" app:childHight="35dp" app:childWidth="150dp" app:childSpace="10dp" android:padding="20dp" /> </RelativeLayout>
这里xmlns:app=”http://schemas.android.com/apk/res-auto”该代码是进行使用自己自定义属性的
自定义属性
路径res/values/文件名.xml
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="FlowLayout"> <attr name="childSpace" format="dimension"/> <attr name="childWidth" format="dimension"/> <attr name="childHight" format="dimension"/> </declare-styleable></resources>
这里dimension表示尺寸
activity中的使用
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FlowLayout myview = (FlowLayout) findViewById(R.id.myView); List<View> textView =new ArrayList<>(); TextView textView1 = new TextView(this); textView1.setText("aaaaaa000a1"); textView.add(textView1); TextView textView2 = new TextView(this); textView2.setText("aaaaa00aa2"); textView.add(textView2); TextView textView3 = new TextView(this); textView3.setText("aaaaaa0000000000a3"); textView.add(textView3); TextView textView4 = new TextView(this); textView4.setText("aaa00000000000000000000000000000000aaaa4"); textView.add(textView4); TextView textView5 = new TextView(this); textView5.setText("aaaa0000000000000000000aaa5"); textView.add(textView5); myview.addView(textView); }
在Activity中就是手动穿件几个TextVIew然后通过我们自定义View类中的addVIew进行添加View addView中需要一个List泛型为VIew的集合
这里我的自定义View就算完了 这里也会有一些问题如Merage属性不支持后续会加上
0 0
- 自定义布局子流布局实现标签功能
- 自定义标签布局(流布局)
- 自定义Android流布局实现推荐标签功能
- 自定义Android流布局实现推荐标签功能
- 自定义标签布局(流布局)
- Android 自定义控件:打造流布局实现热门搜索标签
- Android 自定义控件:打造流布局实现热门搜索标签
- 自定义实现瀑布流布局
- 带有标签的流布局,,,实现标签的选中,添加和删除功能....
- Android 自定义View实现文本流布局
- 标签流布局
- 自定义流布局FlowLayout
- Android 自定义流布局
- 自定义流布局FlowGroup
- 瀑布流布局(基于多栏列表流体布局实现)
- 使用流布局实现热门标签和多选
- Unity-UGUI根据标签宽度实现瀑布流布局--FlowLayoutGroup
- iOS开发进阶 - 自定义UICollectionViewLayout实现瀑布流布局
- “三天打鱼两天晒网”一只小小喵的尝试
- JS提取字符串方法:substring、substr、slice的区别
- qscoj:喵哈哈村的卢西奥
- 【模拟】[NOIP2011]铺地毯[c++]
- 二进制流
- 自定义布局子流布局实现标签功能
- centos6.5下Samba服务器搭建
- C++中虚析构函数的作用及其原理分析
- PHP-SEESSION购物车类
- 线程通信
- HDU2896 病毒侵袭(ac自动机)
- Centos下用twemproxy搭建ssdb伪集群
- Nginx+Ftp+Fileinput做图片上传显示服务器(一)
- 7.2.1 MySQL提供的权限