当前位置: 首页 > news >正文

怎么做网站打赏北京最新发布信息

怎么做网站打赏,北京最新发布信息,科技时代,资源站建站技术效果 child按行显示,显示不下就换行。 分析 继承ViewGrouponDraw()不重写,使用ViewGroup的测量-重点 (测量child、测量自己)布局-重点 (布局child) 知识点 执行顺序 构造函数 -> onMeasure() -> …

效果

child按行显示,显示不下就换行。


分析

  • 继承ViewGroup
  • onDraw()不重写,使用ViewGroup的
  • 测量-重点 (测量child、测量自己)
  • 布局-重点 (布局child)

知识点

执行顺序

构造函数 -> onMeasure() -> onLayout() -> onDraw()

问:onMeasure()后getMeasuredHeight()和getMeasuredWidth()可以获得到值。

答:因为onMeasure()中会使用setMeasuredDimension(width,height)设置宽高值。

问:onLayout() 后getHeight()和getWidth()可以获得到值

答:getWidth()是使用onLayout() 后的left、right得到的,没有布局的时候是没有left、right值的,getHeight()同理。


onMeasure()度量

  • MeasurSpec类

32位整型数据,高两位是模式,低30位是宽/高数据,用位运算来获取数据。(一个数据分为两部分)

模式: EXACTLY(确定的值)、AT_MOST(需要多少给多少,最多不能超过低30位的数据)、UNSPECIFIED(不指定,滚动的时候)

用于在向下执行测量的时候传递View能用的宽/高数据。

MeasurSpec值是根据父容器和自己LayoutParam分配给View的大小,View需要再onMeasure()时确定自己需要的大小(允许你自己调整),然后设置。

  • 如何获取MeasurSpec值?(LayoutParam转化为px)

View的层级是树形的,度量是递归实现的,child的度量是由father分发的,想要知道MeasurSpec值是如何获取的?可以看ViewGroup中的度量child时,是如何获得child的MeasurSpec值的。

ViewGroup类中提供了getChildMeasureSpec方法,用于获得child的MeasurSpec。

方法参数说明如下:

spec :父布局的MeasurSpec

padding:父布局的padding,如获取child宽度的MeasurSpec,就需要paddingLeft+paddingRight。

childDimension:child的布局,有xxdp/wrap_content/match_parent三种情况,如获取child宽度的MeasurSpec值,就是child布局中的android:layout_width值。

经过对getChildMeasureSpec()源码的分析得出如下规则:(宽高都使用此规则)


  • View的onMeasure()

        1. 据MeasureSpec的不同模式确定自己的宽高

                如果是MeasureSpec.EXACTLY ,使用MeasureSpec中的size

                如果是MeasureSpec.AT_MOST,使用自身需要的大小

                如果是MeasureSpec.UNSPECIFIED,0/自身需要的大小

        2. 设置View的宽高setMeasuredDimension(width,height)


  • ViewGroup的onMeasure()

        除了 View的onMeasure()中要做的,还要度量child。

        先度量谁?自己/child?

        一般都是先度量child,在度量自己,ViewPager除外,ViewPager高度设置为wrap_content无效。


流式布局

  • 度量child

  • 度量自己

如果是MeasureSpec.EXACTLY ,使用MeasureSpec中的size,不用计算。

如果是MeasureSpec.AT_MOST,使用自身需要的大小(child撑起的宽高)。

如果是MeasureSpec.UNSPECIFIED,0/自身需要的大小(child撑起的宽高)。

根据上面规则可知,要计算出child撑起的宽高。

child撑起的宽度(width) = 单行总宽度最大值(包含水平间隔) + paddingLeft + paddingRight

child撑起的高度(height) = 每行中高度最高的child的高度 + 垂直间隔 + paddingTop + paddingBottom

设置初始值

int height = getPaddingTop()+getPaddingBottom();

int width = getPaddingLeft()+getPaddingRight();

循环child,记录单行的数据

int lineHeight = 0; //记录每行的高度 放入一个child的时候对比取最大值

int curWidth = getPaddingLeft()+getPaddingRight(); //记录每行的当前宽度 放入一个child的时候加上child的宽度以及水平间隔

换行的时候,保存单行数据至width和height,并清空单行数据,注意换行的判断条件。

注意最后一行(执行到最后一个元素时,保存最后一行的数据)。

另外,为了方便布局,记录每行的View以及每行的高度,布局时不需要再次计算。

另设置自己的宽高的时候,记得用规则判断下。

具体实现见文章底部源码。

  • 布局

根据测量的宽高,确定child的位置(left、right、top、bottom)

在自定义ViewGroup中布局child的时候,使用的是视图坐标系。

在布局时获取child的宽高使用getMeasuredWidth()/getMeasuredHeight(),此时getWidth()/getHeight()还没有数值。

自定义ViewGroup流程

扩展

  • ViewPager高度设置为wrap_content无效的原因?

在度量时没有先度量child,先设置了自己的宽高,宽高获取使用的是getDefaultSize()方法。

根据文中的获取child的MeasureSpec的规则可知,当LayoutParam的值为wrap_content时,其MeasureSpec的mode为AI_MOST。

看上面源码可知,当model=MeasureSpec.AT_MOST时,没有使用根据child计算高度,用的是父布局能给的所有高度,所以当高度设置为wrap_content,高度仍是占满了父布局的全部。

  • 资料

  • MeasureSpec.UNSPECIFIED说明:https://www.cnblogs.com/liushilin/p/11055741.html
  • google官方提供的流式布局 flexbox-layout

                看的时候注重两点,如何测量子布局child.measure和

                设置自己宽高的位置setMeasuredDimension

                github地址:https://github.com/google/flexbox-layout

                使用文档:FlexboxLayout全攻略(Google官方灵活实现流式布局控件)-CSDN博客

                注意:在真实项目中,可以使用FlexboxLayout实现流式布局,也可使用RecyclerView+FlexboxLayoutManager实现。

  • 可以自适应child高度的ViewPager(自定义ViewPager,具体实现见源码

源码

FlowLayout.java

package com.learn.customui.custom;import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;import java.util.ArrayList;
import java.util.List;/*** 问题:* 1.没有考虑child的margin* 2.宽度多了一个水平间隔* 3.未处理child的visiable属性* 4.没有考虑gravity*/
public class FlowLayout extends ViewGroup {private int mHorizontalSpace = 10; //px 水平间隔private int mVerticalSpace = 10; //px 垂直间隔private List<List<View>> mAllViews = new ArrayList<>();//按行存储View,用于布局使用private List<Integer> lineHeights = new ArrayList<>(); //存储每行的高度public FlowLayout(Context context) {super(context);}public FlowLayout(Context context, AttributeSet attrs) {super(context, attrs);}public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}/**** @param widthMeasureSpec 根据该View父布局的宽度(MeasureSpec)与自身的LayoutParam(android:layout_width)结合获得的MeasureSpec类型值* @param heightMeasureSpec  根据该View父布局的高度(MeasureSpec)与自身的LayoutParam(android:layout_height)结合获得的MeasureSpec类型值**/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//会多次测量,使用最后一次测量mAllViews.clear();lineHeights.clear();/*** 1 度量Child* 1.1 度量child* 1.2 度量自己的时候需要child的宽高* 重点:使用getChildMeasureSpec()获取child的MeasureSpec (规则就是固定的,至于能不能显示开发者自定)*/for(int i = 0;i<getChildCount();i++){View child = getChildAt(i);//获取child宽度的MeasureSpecint childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,getPaddingLeft()+getPaddingRight(),child.getLayoutParams().width);//获取child高度的MeasureSpecint childHeightMeasureSpec= getChildMeasureSpec(heightMeasureSpec,getPaddingTop()+getPaddingBottom(),child.getLayoutParams().height);//测量childchild.measure(childWidthMeasureSpec,childHeightMeasureSpec);}//child被度量过,可以获取宽高/*** 2 度量自己   根据不同模式下设置不同的大小* MeasureSpec.EXACTLY  使用方法参数中的size* MeasureSpec.AT_MOST  使用子布局撑起来的size* MeasureSpec.UNSPECIFIED  使用方法参数中的size  0/size 0代表不指定(滚动时)*///child撑起的高度 = 每行中高度最高的child的高度 + 垂直间隔 + paddingTop + paddingBottomint height = getPaddingTop()+getPaddingBottom();//child撑起的宽度 = 单行总宽度最大值(包含水平间隔) + paddingLeft + paddingRightint width = getPaddingLeft()+getPaddingRight();//当前View能用的最大宽度(父亲给的)int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);//记录每行的高度int lineHeight = 0;//记录每行的当前宽度int curWidth = getPaddingLeft()+getPaddingRight();//记录每行的child  布局时使用List<View> lineView = new ArrayList<>();//遍历child 计算高度和宽度for(int i = 0;i<getChildCount();i++){View child = getChildAt(i);//换行if(curWidth+child.getMeasuredWidth()>widthSpecSize){//存储当前行的数据mAllViews.add(lineView);lineView = new ArrayList<>();lineHeights.add(lineHeight);height += lineHeight + mVerticalSpace;width = Math.max(width,curWidth);//清空lineHeight = 0;curWidth = getPaddingLeft()+getPaddingRight();}//放入childlineHeight = Math.max(lineHeight,child.getMeasuredHeight());curWidth += child.getMeasuredWidth()+mHorizontalSpace;lineView.add(child);//最后一个child 存储当前行数据if(i == getChildCount()-1){//最后一行不加垂直间隔height += lineHeight;width = Math.max(width,curWidth);mAllViews.add(lineView);lineHeights.add(lineHeight);}}if(MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) width= MeasureSpec.getSize(widthMeasureSpec);if(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) height = MeasureSpec.getSize(heightMeasureSpec);//设置自己的宽高setMeasuredDimension(width,height);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int curLeft = getPaddingLeft();int curTop = getPaddingTop();for (int i = 0; i < mAllViews.size(); i++) {for (View child : mAllViews.get(i)) {child.layout(curLeft,curTop,curLeft+child.getMeasuredWidth(),curTop+child.getMeasuredHeight());curLeft += child.getMeasuredWidth()+mHorizontalSpace;}curLeft = getPaddingLeft();curTop += lineHeights.get(i)+mVerticalSpace;}}
}

activity_flow.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".FlowActivity"><com.learn.customui.custom.FlowLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@color/black"><TextViewandroid:layout_width="100dp"android:layout_height="50dp"android:gravity="center"android:background="@color/red"android:text="1111"/><TextViewandroid:layout_width="300dp"android:layout_height="50dp"android:gravity="center"android:background="@color/red"android:text="2222"/><TextViewandroid:layout_width="100dp"android:layout_height="50dp"android:gravity="center"android:background="@color/red"android:text="1111"/><TextViewandroid:layout_width="100dp"android:layout_height="50dp"android:gravity="center"android:background="@color/red"android:text="2222"/><TextViewandroid:layout_width="100dp"android:layout_height="50dp"android:gravity="center"android:background="@color/red"android:text="1111"/><TextViewandroid:layout_width="100dp"android:layout_height="50dp"android:gravity="center"android:background="@color/red"android:text="2222"/></com.learn.customui.custom.FlowLayout></LinearLayout>

WrapHeightViewPager.java

package com.learn.customui.custom;import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;public class WrapHeightViewPager extends ViewPager {public WrapHeightViewPager(@NonNull Context context) {super(context);}public WrapHeightViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);/*** 方法1:在super前改变heightMeasureSpec中size(targetSDK = Android33,此方法不使用,获取到的child=null,targetSDK=28 可用,其余版本未测试)* 1.如何改变MeasureSpec中的size?使用MeasureSpec.makeMeasureSpec(size,mode)重新生成一个。* 2.获取高度mode的方法?使用MeasureSpec.getMode(heightMeasureSpec)/设置为固定的MeasureSpec.EXACTLY** 方法2:在super后重新设置高度(不存在方法1的问题)setMeasuredDimension(getMeasuredWidth(),height);* 问题:* 1.宽度使用 getMeasuredWidth(),已在super中设置过。** 共同问题:* 1.高度size怎么获取?child中最高的?* 循环遍历child,使用所有child中高度最高的(适合child高度统一的情况)* 2.当前child的高度?如何获取当前child,切换child的时候会重新onMeasure()吗?(当child高度不统一,需要再切换的时候重新设置时)(待验证,会有很多坑)* getChildAt(getCurrentItem())获取当前child,注意:切换的时候会销毁其他,注意越界问题。* 如果不会重新onMeasure(),可以自定义方法自行刷新。*///此处使用方法2实现for (int i = 0; i < getChildCount(); i++) {View child = getChildAt(i);ViewGroup.LayoutParams lp = child.getLayoutParams();int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom(), lp.height);child.measure(childWidthMeasureSpec,childHeightMeasureSpec);}int height = 0;int heightSize = MeasureSpec.getSize(heightMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);switch (heightMode){case MeasureSpec.EXACTLY:height = heightSize;break;case MeasureSpec.AT_MOST:case MeasureSpec.UNSPECIFIED:for (int i = 0; i < getChildCount(); i++) {View child = getChildAt(i);height = Math.max(height,child.getMeasuredHeight());}break;}setMeasuredDimension(getMeasuredWidth(),height);}
}


文章转载自:
http://dinncomeiji.bkqw.cn
http://dinncospermatheca.bkqw.cn
http://dinncocingulum.bkqw.cn
http://dinncodecarbonization.bkqw.cn
http://dinncoribbonlike.bkqw.cn
http://dinncotautochronism.bkqw.cn
http://dinncoblowpipe.bkqw.cn
http://dinncoadverb.bkqw.cn
http://dinncointercrural.bkqw.cn
http://dinncobanian.bkqw.cn
http://dinncomolybdate.bkqw.cn
http://dinncopianoforte.bkqw.cn
http://dinncorollock.bkqw.cn
http://dinncotailorable.bkqw.cn
http://dinncoscreed.bkqw.cn
http://dinncoluxmeter.bkqw.cn
http://dinncovaporiform.bkqw.cn
http://dinncotoleration.bkqw.cn
http://dinncosomnambulary.bkqw.cn
http://dinncorheumy.bkqw.cn
http://dinncopickax.bkqw.cn
http://dinncogeisha.bkqw.cn
http://dinncowollaston.bkqw.cn
http://dinncointerosseous.bkqw.cn
http://dinncosalangane.bkqw.cn
http://dinncodisorganized.bkqw.cn
http://dinncocrossbuttock.bkqw.cn
http://dinncoontology.bkqw.cn
http://dinncodaydreamer.bkqw.cn
http://dinncopataca.bkqw.cn
http://dinncofrontispiece.bkqw.cn
http://dinncoeastward.bkqw.cn
http://dinncocot.bkqw.cn
http://dinncoapostolic.bkqw.cn
http://dinncopertinence.bkqw.cn
http://dinncodietetics.bkqw.cn
http://dinncorapacity.bkqw.cn
http://dinncoluggage.bkqw.cn
http://dinncofilial.bkqw.cn
http://dinncoquench.bkqw.cn
http://dinncolaical.bkqw.cn
http://dinncoincorporable.bkqw.cn
http://dinncoegg.bkqw.cn
http://dinncodepaint.bkqw.cn
http://dinncopoverty.bkqw.cn
http://dinncoignitron.bkqw.cn
http://dinncoqr.bkqw.cn
http://dinncodatum.bkqw.cn
http://dinncosulfhydryl.bkqw.cn
http://dinncotervalent.bkqw.cn
http://dinncoastrocompass.bkqw.cn
http://dinncocriticaster.bkqw.cn
http://dinncoquadro.bkqw.cn
http://dinncostipple.bkqw.cn
http://dinncoslid.bkqw.cn
http://dinncomakable.bkqw.cn
http://dinncohologynic.bkqw.cn
http://dinncopuristical.bkqw.cn
http://dinncomoldboard.bkqw.cn
http://dinncouricacidemia.bkqw.cn
http://dinncocroustade.bkqw.cn
http://dinncobookshelf.bkqw.cn
http://dinncouncurl.bkqw.cn
http://dinncogrundy.bkqw.cn
http://dinncoenthusiasm.bkqw.cn
http://dinncomynheer.bkqw.cn
http://dinncoprojector.bkqw.cn
http://dinnconeckverse.bkqw.cn
http://dinncoshox.bkqw.cn
http://dinncobrassily.bkqw.cn
http://dinncobrindisi.bkqw.cn
http://dinncosgi.bkqw.cn
http://dinncoles.bkqw.cn
http://dinncoemulsin.bkqw.cn
http://dinncosplashy.bkqw.cn
http://dinncobetelnut.bkqw.cn
http://dinncocongolese.bkqw.cn
http://dinncoford.bkqw.cn
http://dinncomilankovich.bkqw.cn
http://dinncojustine.bkqw.cn
http://dinncosapidity.bkqw.cn
http://dinncohexokinase.bkqw.cn
http://dinnconih.bkqw.cn
http://dinncouneffectual.bkqw.cn
http://dinncohgh.bkqw.cn
http://dinncomalleolus.bkqw.cn
http://dinncofloorward.bkqw.cn
http://dinncocalvaria.bkqw.cn
http://dinncopagurid.bkqw.cn
http://dinncobracteal.bkqw.cn
http://dinncodps.bkqw.cn
http://dinncofragmental.bkqw.cn
http://dinncosarsaparilla.bkqw.cn
http://dinncoacromegaly.bkqw.cn
http://dinncospeedy.bkqw.cn
http://dinncoedbiz.bkqw.cn
http://dinncomicrolepidopteron.bkqw.cn
http://dinncofratch.bkqw.cn
http://dinncocantal.bkqw.cn
http://dinncotrippingly.bkqw.cn
http://www.dinnco.com/news/122457.html

相关文章:

  • 学雷锋 做美德少年网站如何开发一个网站
  • 网站建设哪种语言好自己动手建立个人网站
  • 网站死链怎么处理网店代运营的套路
  • app下载微信常德seo
  • 自学做网站指数基金排名前十名
  • 千库网ppt模板素材免费seo谷歌外贸推广
  • 固定ip如何做网站服务器邀请注册推广赚钱的app
  • 嘉兴品牌网站设计十大场景营销案例
  • 网站建设应用技术东莞排名优化团队
  • 关于水果的网站建设cpa推广联盟平台
  • 自助游网站开发分析报告总结外贸网站都有哪些
  • 自己做的网站怎么传入外网以图搜图百度识图
  • wordpress 邮件优化大师人工服务电话
  • 吕梁建站公司互联网营销策划
  • 委托他人做公司网站的税率网络优化初学者难吗
  • 网站开发 手把手网站外贸推广
  • 珠海企业网站建设服务菏泽地网站seo
  • 网站首页怎么做ps跨境电商关键词工具
  • 铁西网络建设手机优化大师官方免费下载
  • 网站推广有什么好处广州代运营公司有哪些
  • 来宾网站建设企业网站类型有哪些
  • 怎样建设的网站好优化好排名营销渠道模式有哪些
  • 东莞做网站 汇卓营销策划精准营销
  • 橙子建站网百度有哪些产品
  • 网站建设 域名 数据库百度统计登录
  • 电商网站首页图片切换怎么做的河南网络推广公司
  • 云南建设工程信息服务平台seo网络营销课程
  • 建设外贸商城网站好用的seo软件
  • 优秀网站评析海外短视频软件
  • 辽宁网站建设学校网络营销的四个步骤