流式布局的使用——使用固定布局

news/2024/7/7 7:10:21

首先可以看下效果图


简单布局使用:

<com.hbwj.p2pinvest.ui.FlowLayout
    android:id="@+id/flow_hot"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/holo_blue_light">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="你是我心内的一首歌"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="涛声依旧"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="夜夜"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="月落乌啼霜满天"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="哇塞"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="word天哪"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="你咋不上天呢"
        android:layout_margin="10dp"
        android:textSize="20sp" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="你想怎样"
        android:layout_margin="10dp"
        android:textSize="20sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="夜曲"
        android:layout_margin="10dp"
        android:textSize="20sp" />


</com.hbwj.p2pinvest.ui.FlowLayout>
自定义flowLayout

public class FlowLayout extends ViewGroup {
    public FlowLayout(Context context) {
        this(context, null);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取设置的宽高的模式和具体的值(屏幕的宽高)
        int widhtMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //至多模式,使用以下两个变量计算真实的宽高
        int height = 0;
        int width = 0;
        //每一行的宽高
        int lineWidth = 0;
        int lineHeight = 0;
        //获取子视图
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //只有调用了如下的方法,方可计算子视图测量的宽和高
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            //获取子视图的宽和高
            int childWidth = childView.getMeasuredWidth();
            int childHight = childView.getMeasuredHeight();
            //要想保证可以获取子视图的边距参数对象,必须重写generateLayoutParams()
            MarginLayoutParams mp = (MarginLayoutParams) childView.getLayoutParams();
            if (lineWidth + childWidth + mp.leftMargin + mp.rightMargin < widthSize) {//不换行
                lineWidth += childWidth + mp.leftMargin + mp.rightMargin;
                lineHeight = Math.max(lineHeight, childHight + mp.topMargin + mp.bottomMargin);
            } else {//换行
                width = Math.max(lineWidth, width);
                height += lineHeight;
                //重置
                lineWidth = childWidth + mp.leftMargin + mp.rightMargin;
                lineHeight = childHight + mp.topMargin + mp.bottomMargin;
            }
            //最后一个元素
            if (i == childCount - 1) {
                height += lineHeight;
                width = Math.max(lineWidth, width);
            }
        }
        Log.e("TAG", "widthSize==" + widthSize + ",heightSize==" + heightSize);// widthSize==768,heightSize==838
        Log.e("TAG", "width==" + width + ",height==" + height);//width==720,height==282
        setMeasuredDimension(widhtMode == MeasureSpec.EXACTLY ? widthSize : width, heightMode == MeasureSpec.EXACTLY ? heightSize : height);
    }

    //重写的目的,给每个子视图指定显示的位置:childview.layout();
    private List<List<View>> allViews = new ArrayList<>();//每一行的子视图宽度的集合构成的集合
    private List<Integer> allHeight = new ArrayList<>();//每一行的高度构成的集合

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //1.给两个集合添加元素
        int childCount = getChildCount();
        //获取布局的宽(也就是屏幕的宽)
        int widthSize = this.getMeasuredWidth();
        //行高和行宽
        int lineWidth = 0;
        int lineHeight = 0;
        List<View> lineList = new ArrayList<>();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //获取子视图的宽和高
            int childWidth = childView.getMeasuredWidth();
            int childHight = childView.getMeasuredHeight();
            //要想保证可以获取子视图的边距参数对象,必须重写generateLayoutParams()
            MarginLayoutParams mp = (MarginLayoutParams) childView.getLayoutParams();
            if (lineWidth + childWidth + mp.leftMargin + mp.rightMargin <= widthSize) {//不换行
                lineList.add(childView);
                lineWidth += childWidth + mp.leftMargin + mp.rightMargin;
                lineHeight = Math.max(lineHeight, childHight + mp.topMargin + mp.bottomMargin);
            } else {//换行
                allHeight.add(lineHeight);
                allViews.add(lineList);
                //重置
                lineWidth = childWidth + mp.leftMargin + mp.rightMargin;
                lineHeight = childHight + mp.topMargin + mp.bottomMargin;
                lineList = new ArrayList<>();
                lineList.add(childView);
            }
            if(i==childCount-1){
                allHeight.add(lineHeight);
                allViews.add(lineList);
            }

        }
        Log.e("TAG","allviews.size=="+allViews.size()+",allHeights.size=="+allHeight.size());
        //2.给每个元素添加位置
        int x=0;
        int y=0;
         for(int i=0;i<allViews.size();i++){
             List<View> views = allViews.get(i);//获取每一行的集合
             for(int j=0;j<views.size();j++){//获取每一行的view
                 View childView = views.get(j);
                 MarginLayoutParams mp = (MarginLayoutParams) childView.getLayoutParams();
                 int left=x+mp.leftMargin;
                 int top=y+mp.topMargin;
                 int right=left+childView.getMeasuredWidth();
                 int bottom=top+childView.getMeasuredHeight();
                 x+=mp.leftMargin+mp.rightMargin+childView.getMeasuredWidth();
                 childView.layout(left,top,right,bottom);
             }
             y+=allHeight.get(i);
             x=0;
         }
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        MarginLayoutParams mp = new MarginLayoutParams(getContext(), attrs);
        return mp;
    }
}


http://www.niftyadmin.cn/n/3649062.html

相关文章

Android中关于横竖屏问题

在以前的版本中只要在AndroidManifest.xml文件中对activity指定android:configChanges"keyboardHidden|orientation"属性&#xff0c;转屏的时候就会不再重新调用OnCreate()函数&#xff0c;而是调用onConfigurationChanged()。 但是在自从android3.2以后&#xff0c…

应用双节点,数据库是dg_如何使用节点构建轻量级发票应用程序:数据库和API

应用双节点,数据库是dg介绍 (Introduction) To get paid for goods and services provided, businesses need to send invoices to their customers informing them of the services that they will be charged for. Back then, people had paper invoices which they gave to …

查找算法集:顺序查找、二分查找、插值查找、动态查找(数组实现、链表实现)

//search.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "LinkTable.h"#defineMAX_KEY 500//------------------------------数组实现部分----------------------------------/**//* 无序数组顺序查找算法…

网页开端第四次培训笔记

CSS常用属性设置 1.背景&#xff08;css背景属性用于定义HTML元素的背景效果 background-color 设置元素的背景效果background-image 设置元素的背景图像&#xff0c;默认情况下&#xff0c;背景图像进行平铺重复显示&#xff0c; …

父子节点 构建_如何使用节点构建轻量级发票应用程序:用户界面

父子节点 构建介绍 (Introduction) In the first part of this series, you set up the backend server for the invoicing application. In this tutorial you will build the part of the application that users will interact with, known as the user interface. 在本系列…

Android零碎小知识

获取当前的版本号 public double getVersionCode() {try {int versionCode getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;return versionCode;} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}return 0; }将版本号设置成1.…

TabActivity实现多页显示效果

由于手机屏幕有限&#xff0c;所以我们要尽量充分利用屏幕资源。在我们的应用程序中通常有多个Activity&#xff0c;而且会经常切换显示&#xff0c;这样我们就可以用TabActivity来显示。其效果如图1所示。 图1 tabActivity显示效果 本文就来研究TabActivity。根据帮助文档的解…

网页开端第五次培训笔记

JavaScript简介 JavaScript是一种具有面向对象能力的、解释型的程序设计语言。更具体点&#xff0c;它是基于对象和时间驱动并具有相对安全性的客户端脚本语言。它的主要目的是&#xff0c;验证发往服务器端的数据、增加Web互动、加强用户体验度等。 JavaScript的组成 ECMASc…