您的位置:首页 > 游戏 > 游戏 > 淘宝的seo是什么意思_合肥大型互联网公司_希爱力的功效及副作用_线上运营推广

淘宝的seo是什么意思_合肥大型互联网公司_希爱力的功效及副作用_线上运营推广

2025/9/7 20:55:12 来源:https://blog.csdn.net/weixin_63357306/article/details/143367208  浏览:    关键词:淘宝的seo是什么意思_合肥大型互联网公司_希爱力的功效及副作用_线上运营推广
淘宝的seo是什么意思_合肥大型互联网公司_希爱力的功效及副作用_线上运营推广

在 Android 开发中,流式布局是一种常见的 UI 设计模式,尤其适用于展示动态内容,如标签、历史记录等。本文将介绍如何通过自定义 View 来实现一个历史记录的流式布局。

使用自定义view实现历史记录流式布局的运行结果图: 

1. 创建自定义 ViewGroup

首先,我们需要创建一个名为 FlowLayout 的类,继承自 ViewGroup。在构造函数中,我们可以初始化一些必要的属性。

public class FlowLayout extends ViewGroup {private List<List<View>> allListView = new ArrayList<>(); // 所有View的二维数组private List<Integer> allListHeight = new ArrayList<>(); // 每一行的高度private int mywidthspacing = 16; // 宽间距private int myheightspacing = 8; // 高间距public FlowLayout(Context context) {super(context);} // newpublic FlowLayout(Context context, AttributeSet attrs) {super(context, attrs);} // 反射public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}// xmlpublic FlowLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}

2. 重写 onMeasure 方法

在 onMeasure 方法中,我们需要测量每个子视图的大小,并计算出 FlowLayout 的最终宽高。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 调用父类的 onMeasure 方法,确保父类的测量逻辑被执行super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 初始化存储所有行的视图和高度的列表,防止 onMeasure 被多次调用时出现数据错误allListView = new ArrayList<>();allListHeight = new ArrayList<>();// 获取父视图的宽度和高度int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);// 初始化总高度和总宽度int allheight = 0;int allwidth = 0; // 获取子视图的数量int count = getChildCount();// 初始化当前行的宽度和高度int linewidthuser = 0; int lineHeight = 0;// 用于存储当前行的视图List<View> listview = new ArrayList<>();// 遍历所有子视图for (int i = 0; i < count; i++) {View childView = getChildAt(i); // 获取当前子视图LayoutParams childLP = childView.getLayoutParams(); // 获取子视图的布局参数// 如果子视图可见if (childView.getVisibility() != GONE) {// 计算子视图的测量规格int childwidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingRight(), childLP.width);int childheightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom(), childLP.height);// 测量子视图的宽高childView.measure(childwidthMeasureSpec, childheightMeasureSpec);int childMeasuredWidth = childView.getMeasuredWidth(); // 获取测量后的宽度int childMeasuredHeight = childView.getMeasuredHeight(); // 获取测量后的高度// 判断当前行是否能放下下一个子视图,特别需要注意加入当前view的Padding的距离if (linewidthuser + childMeasuredWidth + mywidthspacing > widthSize - getPaddingLeft() - getPaddingRight()) {// 如果放不下,保存当前行的视图和高度allListView.add(listview);allListHeight.add(lineHeight);// 更新总宽度和总高度allwidth = Math.max(allwidth, linewidthuser + mywidthspacing);allheight = allheight + lineHeight + myheightspacing;// 换行,重置当前行的宽高linewidthuser = 0;lineHeight = 0;listview = new ArrayList<>();// 将当前子视图作为新行的第一个视图listview.add(childView);linewidthuser += childMeasuredWidth + mywidthspacing; // 更新当前行宽度lineHeight = Math.max(childMeasuredHeight, lineHeight); // 更新当前行高度} else {// 如果可以放下,继续添加到当前行listview.add(childView);linewidthuser += childMeasuredWidth + mywidthspacing; // 更新当前行宽度lineHeight = Math.max(childMeasuredHeight, lineHeight); // 更新当前行高度// 如果是第一行,更新总宽度和高度if (allListView.size() < 1) {allheight = Math.max(childMeasuredHeight, allheight);allwidth = linewidthuser;}}// 如果是最后一个子视图,保存当前行的视图和高度if (i == count - 1) {allListView.add(listview);allListHeight.add(childMeasuredHeight);}}}// 获取测量模式int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);// 根据测量模式来获取需要的宽度和高度int realWidthSize = (widthMode == MeasureSpec.EXACTLY) ? widthSize : allwidth + getPaddingLeft() + getPaddingRight();int realHeightSize = (heightMode == MeasureSpec.EXACTLY) ? heightSize : allheight + getPaddingBottom() + getPaddingTop();// 设置测量后的宽高setMeasuredDimension(realWidthSize, realHeightSize);
}

3. 重写 onLayout 方法

在 onLayout 方法中,我们需要根据测量的结果来布局每个子视图的位置。

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {// 获取当前视图的左、上、右、下边距int curLeft = getPaddingLeft(); // 当前行的起始左边距int curTop = getPaddingTop(); // 当前行的起始上边距// 遍历所有行for (int i = 0; i < allListView.size(); i++) { // 遍历每一行curLeft = getPaddingLeft(); // 每行开始时重置左边距// 遍历当前行的所有视图for (int j = 0; j < allListView.get(i).size(); j++) { // 遍历当前行的每个视图View view = allListView.get(i).get(j); // 获取当前视图// 定义视图的布局边界int left, top, right, bottom;left = curLeft; // 当前视图的左边界top = curTop; // 当前视图的上边界right = left + view.getMeasuredWidth(); // 当前视图的右边界bottom = top + view.getMeasuredHeight(); // 当前视图的下边界// 布局当前视图view.layout(left, top, right, bottom);// 更新当前行的左边距,为下一个视图留出空间curLeft = right + mywidthspacing; // 加上视图的宽度和水平间距}// 更新当前行的顶部边距,为下一行留出空间curTop = curTop + allListHeight.get(i) + myheightspacing; // 加上当前行的高度和垂直间距// 重置左边距,以便下一行的布局curLeft = getPaddingLeft(); // 每行开始时重置左边距}
}

4.使用

在布局文件中,注意把com.example.note换成自己的包名:

<com.example.note.FlowLayoutandroid:id="@+id/flowLayout"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="16dp" />

这里就自己加的几个数据在Activity中运行测试:

public class TestActivity extends AppCompatActivity {private FlowLayout flowLayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);flowLayout = findViewById(R.id.flowLayout);ArrayList<String> list = new ArrayList<>();list.add("你好");list.add("我是谁");list.add("历史记录");list.add("搜索我的物品A");list.add("搜索我的物品B");list.add("搜索我的物品C");list.add("搜索我的物品D");list.add("你好呀");list.add("自定义View");list.add("流式布局实现啦");// 添加文字到 FlowLayoutfor (int i = 0; i < list.size(); i++) {final TextView textView = new TextView(this);textView.setText(list.get(i));GradientDrawable drawable = new GradientDrawable();drawable.setShape(GradientDrawable.RECTANGLE);drawable.setColor(Color.GRAY); // 设置背景颜色为灰色drawable.setCornerRadius(26f); // 设置圆角半径textView.setBackground(drawable);textView.setTextSize(20f);textView.setTextColor(Color.WHITE); // 设置字体颜色为白色textView.setPadding(16, 8, 16, 8); // 设置内边距textView.setOnClickListener(v -> {// 处理按钮点击事件});flowLayout.addView(textView);}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com