服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android自定义控件ViewGroup实现标签云

Android自定义控件ViewGroup实现标签云

2022-02-27 16:30Owen-Chan Android

这篇文章主要为大家详细介绍了Android自定义控件ViewGroup实现标签云,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android自定义控件ViewGroup实现标签云的具体代码,供大家参考,具体内容如下

实现的功能:

Android自定义控件ViewGroup实现标签云

基本绘制流程:

构造函数获取自定义属性
onMeasure()方法,测量子控件的大小
onLayout()方法,对子控件进行布局

1、自定义属性

?
1
2
3
4
5
6
7
8
<resources>
 
  <declare-styleable name="TabsViewGroup">
    <attr name="tabVerticalSpace" format="dimension" />
    <attr name="tabHorizontalSpace" format="dimension" />
  </declare-styleable>
 
</resources>

2、构造函数中获取自定义属性值

?
1
2
3
4
5
6
7
8
9
public TabsViewGroup(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray attrArray = context.obtainStyledAttributes(attrs, R.styleable.TabsViewGroup);
    if (attrArray != null) {
      childHorizontalSpace = attrArray.getDimensionPixelSize(R.styleable.TabsViewGroup_tabHorizontalSpace, 0);
      childVerticalSpace = attrArray.getDimensionPixelSize(R.styleable.TabsViewGroup_tabHorizontalSpace, 0);
      attrArray.recycle();
    }
  }

3、onMeasure函数测量子控件大小,然后设置当前控件大小

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
@Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
 
    int widthModel = MeasureSpec.getMode(widthMeasureSpec);
    int heightModel = MeasureSpec.getMode(heightMeasureSpec);
 
    //输出宽度高度以及测量模式
    Log.i(TAG, "sizeWidth :" + widthSize);
    switch (widthModel) {
      case MeasureSpec.AT_MOST:
        Log.i(TAG, "Width model AT_MOST");
        break;
      case MeasureSpec.EXACTLY:
        Log.i(TAG, "Width model EXACTLY");
        break;
      case MeasureSpec.UNSPECIFIED:
        Log.i(TAG, "Width model UNSPECIFIED");
        break;
    }
 
    Log.i(TAG, "sizeHeight :" + heightSize);
    switch (heightModel) {
      case MeasureSpec.AT_MOST:
        Log.i(TAG, "Height model AT_MOST");
        break;
      case MeasureSpec.EXACTLY:
        Log.i(TAG, "Height model EXACTLY");
        break;
      case MeasureSpec.UNSPECIFIED:
        Log.i(TAG, "Height model UNSPECIFIED");
        break;
    }
    //左右边距
    int left = getPaddingLeft();
    int top = getPaddingTop();
    //记录每一行的宽度和高度
    int lineWidth = 0;
    int lineHeight = 0;
    // 如果是warp_content情况下,记录宽和高
    int containerWidth = 0;
    int containerHeight = 0;
    // 遍历每个子元素
    for (int index = 0; index < getChildCount(); index++) {
      View child = getChildAt(index);
      if (child.getVisibility() == GONE) {
        continue;
      }
      measureChild(child, widthMeasureSpec, heightMeasureSpec);
      MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
 
      int childWidth = child.getMeasuredWidth() + params.leftMargin + params.rightMargin + childHorizontalSpace;
      int childHeight = child.getMeasuredHeight() + params.topMargin + params.bottomMargin + childVerticalSpace;
 
      if (lineWidth + childWidth > widthSize - getPaddingRight() - getPaddingLeft()) {
        containerWidth = Math.max(lineWidth, childWidth);
        lineWidth = childWidth;
        containerHeight += lineHeight;
        lineHeight = childHeight;
        Rect rect = new Rect(left,
            containerHeight + top,
            left + childWidth - childHorizontalSpace,
            containerHeight + top + child.getMeasuredHeight());
        child.setTag(rect);
      } else {
        Rect rect = new Rect(lineWidth + left,
            containerHeight + top,
            lineWidth + left + childWidth - childHorizontalSpace,
            containerHeight + top + child.getMeasuredHeight());
        child.setTag(rect);
        lineWidth += childWidth;
        lineHeight = Math.max(lineHeight, childHeight);
      }
    }
 
    containerWidth = Math.max(containerWidth, lineWidth) + getPaddingLeft() + getPaddingRight();
    containerHeight += lineHeight + getPaddingTop() + getPaddingBottom();
    containerHeight -= childVerticalSpace;
    setMeasuredDimension(widthModel == MeasureSpec.EXACTLY ? widthSize : containerWidth,
        heightModel == MeasureSpec.EXACTLY ? heightSize : containerHeight);
}

4、onLayout函数对所有子控件重新布局

?
1
2
3
4
5
6
7
8
9
10
11
12
@Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
      View child = getChildAt(i);
      if (child.getVisibility() == GONE) {
        continue;
      }
      Rect location = (Rect) child.getTag();
      child.layout(location.left, location.top, location.right, location.bottom);
    }
}

使用方法

1、布局问自己中直接引用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:owen="http://schemas.android.com/apk/res-auto"
  android:id="@+id/activity_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#ffffff"
  android:orientation="vertical">
 
  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="16sp"
    android:text="国际足球"/>
 
  <View
    android:layout_width="wrap_content"
    android:layout_height="0.1dp"
    android:background="#e0e0e0"/>
 
  <com.ownchan.tabviewgroup.view.TabsViewGroup
    android:id="@+id/tabs_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dip"
    owen:tabHorizontalSpace="10dp"
    owen:tabVerticalSpace="10dp" />
 
</LinearLayout>

2、代码添加标签

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
  }
 
  private void initView() {
    TabsViewGroup tabsViewGroup = (TabsViewGroup) findViewById(R.id.tabs_view);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
        ViewGroup.LayoutParams.WRAP_CONTENT);
    String[] tabs = new String[]{"世预赛欧洲区",
        "世预赛南美区", "五人世界杯", "意甲", "美国大联盟", "乌超", "英冠", "国际冠军杯", "巴西圣保罗州杯", "巴西杯"};
    for (int i = 0; i < tabs.length; i++) {
      TextView textView = new TextView(this);
      textView.setText(tabs[i]);
      textView.setTextColor(Color.WHITE);
      textView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tabs_bg));
      textView.setGravity(Gravity.CENTER);
      textView.setPadding(10, 0, 10, 0);
      textView.setTextSize(16);
      tabsViewGroup.addView(textView, params);
    }
}

效果图:

Android自定义控件ViewGroup实现标签云

项目Github地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/owenchan1987/article/details/59480006

延伸 · 阅读

精彩推荐
  • AndroidAndroid中AsyncTask详细介绍

    Android中AsyncTask详细介绍

    这篇文章主要介绍了Android中AsyncTask详细介绍,AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合,需要的朋友可以参考下...

    Android开发网7452021-03-11
  • AndroidAndroid编程解析XML方法详解(SAX,DOM与PULL)

    Android编程解析XML方法详解(SAX,DOM与PULL)

    这篇文章主要介绍了Android编程解析XML方法,结合实例形式详细分析了Android解析XML文件的常用方法与相关实现技巧,需要的朋友可以参考下...

    liuhe68810052021-05-03
  • AndroidAndroid实现Service获取当前位置(GPS+基站)的方法

    Android实现Service获取当前位置(GPS+基站)的方法

    这篇文章主要介绍了Android实现Service获取当前位置(GPS+基站)的方法,较为详细的分析了Service基于GPS位置的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    Ruthless8342021-03-31
  • AndroidAndroid界面效果UI开发资料汇总(附资料包)

    Android界面效果UI开发资料汇总(附资料包)

    android ui界面设计,友好的界面会提高用户体验度;同时也增强了android ui界面设计的难度,本文提供了一些常用开发资料(有下载哦)感兴趣的朋友可以了解下...

    Android开发网4672021-01-03
  • AndroidAndroid CardView+ViewPager实现ViewPager翻页动画的方法

    Android CardView+ViewPager实现ViewPager翻页动画的方法

    本篇文章主要介绍了Android CardView+ViewPager实现ViewPager翻页动画的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Abby代黎明9602022-03-02
  • AndroidAndroid实现固定屏幕显示的方法

    Android实现固定屏幕显示的方法

    这篇文章主要介绍了Android实现固定屏幕显示的方法,实例分析了Android屏幕固定显示所涉及的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    鉴客6192021-03-27
  • Android汇总Android视频录制中常见问题

    汇总Android视频录制中常见问题

    这篇文章主要汇总了Android视频录制中常见问题,帮助大家更好地解决Android视频录制中常见的问题,需要的朋友可以参考下...

    yh_thu5192021-04-28
  • AndroidAndroid程序设计之AIDL实例详解

    Android程序设计之AIDL实例详解

    这篇文章主要介绍了Android程序设计的AIDL,以一个完整实例的形式较为详细的讲述了AIDL的原理及实现方法,需要的朋友可以参考下...

    Android开发网4642021-03-09