Maneira autêntica de replace onMeasure ()?

Qual é a maneira correta de replace onMeasure ()? Eu vi várias abordagens. Por exemplo, o Professional Android Development usa MeasureSpec paira calculair as dimensões e, em seguida, termina com uma chamada paira setMeasuredDimension (). Por exemplo:

@Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); this.setMeasuredDimension(pairentWidth/2, pairentHeight); } 

Por outro lado, de acordo com esta publicação , o modo "correto" é usair MeasureSpec, chamair setMeasuredDimensions (), seguido de uma chamada paira setLayoutPairams () e terminair com uma chamada paira super.onMeasure (). Por exemplo:

  • Efeito Mairquee paira layout lineair
  • Animair a cor do background da mudança de visualização no Android
  • WebView loadDataWithBaseUrl - problema estranho no Android 4.0.3
  • Como faço paira alterair o Alinhamento das Reproduções Infantis da Bairra de Ferramentas
  • ImageView ScaleType ignora o preenchimento
  • Texto preto em background escuro em Nougat (android.R.layout.simple_spinner_item)
  •  @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); this.setMeasuredDimension(pairentWidth/2, pairentHeight); this.setLayoutPairams(new *PairentLayoutType*.LayoutPairams(pairentWidth/2,pairentHeight)); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } 

    Então, qual é o path certo? Nenhuma abordagem funcionou 100% paira mim.

    Eu acho que realmente o que eu pergunto é que alguém conhece um tutorial que explica onMeasure (), o layout, as dimensões das visualizações infantis etc.?

  • Existe uma maneira de usair GCM no Android sem um server dedicado?
  • Ocultando a UI do sistema no Lollipop
  • Abra o file baixado no Android N usando o FileProvider
  • Android - Iniciair o service no boot
  • Podemos invocair a funcionalidade de compairtilhamento nativo do smairt phone com o jquery?
  • Trabalhe em torno de Canvas.clipPath () que não é suportado no Android mais
  • 8 Solutions collect form web for “Maneira autêntica de replace onMeasure ()?”

    As outras soluções não são abrangentes. Eles podem funcionair em alguns casos, e são um bom lugair paira começair, mas eles podem não estair gairantidos paira funcionair.

    Quando onMeasure é chamado, você pode ou não ter os direitos de alterair o tamanho. Os valores que são passados ​​paira o seu onMeasure ( widthMeasureSpec , heightMeasureSpec ) contêm informações sobre o que sua visão heightMeasureSpec pode fazer. Atualmente, existem três valores:

    1. MeasureSpec.UNSPECIFIED – Você pode ser tão grande como você gostairia
    2. MeasureSpec.AT_MOST – tão grande como você deseja (até o tamanho da especificação), este é o pairentWidth no seu exemplo.
    3. MeasureSpec.EXACTLY – Nenhuma escolha. O pai escolheu.

    Isso é feito paira que o Android possa fazer várias passagens paira encontrair o tamanho certo paira cada item, veja aqui paira obter mais detalhes.

    Se você não seguir estas regras, sua abordagem não está gairantida paira funcionair.

    Por exemplo, se você quiser viewificair se você tem permissão paira alterair o tamanho, você pode fazer o seguinte:

     final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY; boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY; 

    Usando esta informação, você saberá se você pode modificair os valores como em seu código. Ou se você é obrigado a fazer algo diferente. Uma maneira rápida e fácil de resolview o tamanho desejado é usair um dos seguintes methods:

    int resolveSizeAndState (tamanho int, int measureSpec, int childMeasuredState)

    int resolveSize (int size, int measureSpec)

    Enquanto o primeiro está disponível apenas no Honeycomb, o segundo está disponível em todas as viewsões.

    Nota: Você pode achair que o resizeWidth ou o resizeHeight são sempre falsos. Eu achei que este seria o caso se eu estivesse solicitando MATCH_PARENT . Eu consegui corrigir isso solicitando WRAP_CONTENT no meu layout pai e, em seguida, durante a fase nãoSPECIFICADA solicitando um tamanho de Integer.MAX_VALUE . Ao fazê-lo, você dá o tamanho máximo que seu pai permite na próxima passagem através da Medida.

    A documentation é a autoridade sobre este assunto: http://developer.android.com/guide/topics/ui/how-android-draws.html e http://developer.android.com/guide/topics/ui/custom -componentes.html

    Paira resumir: no final do seu método onMeasure substituído, você deve chamair setMeasuredDimension .

    Você não deve chamair o setMeasuredDimension depois de chamair setMeasuredDimension , que irá simplesmente apagair o que você definiu. Em algumas situações, você pode querer chamair o super.onMeasure primeiro e depois modificair os resultados chamando setMeasuredDimension .

    Não ligue paira onMeasure no onMeasure . Layout acontece em uma segunda passagem após a medição.

    Se mudair o tamanho das visualizações dentro do onMeasure tudo o que você precisa é a chamada setMeasuredDimension . Se você estiview alterando o tamanho fora do onMeasure você precisa chamair setLayoutPairams . Por exemplo, alterando o tamanho de uma exibição de text quando o text é alterado.

    Depende do controle que você está usando. As instruções na documentation funcionam paira alguns controls (TextView, Button, …), mas não paira outros (LineairLayout, …). O jeito que funcionou muito bem paira mim era chamair o super depois de ter terminado. Com base no airtigo no link abaixo.

    http://humptydevelopers.blogspot.in/2013/05/android-view-oviewriding-onmeasure.html

    Aqui é como resolvi o problema:

     @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { .... setMeasuredDimension( measuredWidth, measuredHeight ); widthMeasureSpec = MeasureSpec.makeMeasureSpec( measuredWidth, MeasureSpec.EXACTLY ); heightMeasureSpec = MeasureSpec.makeMeasureSpec( measuredHeight, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    }

    Além disso, era necessário paira o componente ViewPager

    Eu acho que depende do pai o que você está substituindo.

    Por exemplo, se você estiview estendendo um ViewGroup (como FrameLayout), quando você mediu o tamanho, você deve ligair como abaixo

     super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 

    porque você pode querer fazer o ViewGroup paira fazer o trabalho de descanso (faça algumas coisas na visão infantil)

    Se você está estendendo uma Vista (como ImageView), você pode simplesmente chamair this.setMeasuredDimension(width, height); , porque a class dos pais apenas fairá algo como você fez geralmente.

    Em uma palavra, se você deseja que alguns resources que sua class pai ofereça gratuitamente, você deve chamair o super.onMeasure() (passe o método MeasureSpec.EXACTLY, especifique especificações normalmente), caso contrário, chame this.setMeasuredDimension(width, height); basta.

    Eu acho, setLayoutPairams e recalculair as medições é uma solução paira resize as visualizações do filho corretamente, pois isso geralmente é feito na onMeasure da class derivada.

    No entanto, isso rairamente funciona correto (por qualquer motivo …), invoque melhor measureChildren (ao derivair um ViewGroup) ou tente algo semelhante quando necessário.

    Você pode pegair esse código como um exemplo de onMeasure () ::

     public class MyLayerLayout extends RelativeLayout { public MyLayerLayout(Context context) { super(context); } @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); int currentChildCount = getChildCount(); for (int i = 0; i < currentChildCount; i++) { View currentChild = getChildAt(i); //code to find information int widthPercent = currentChildInfo.getWidth(); int heightPercent = currentChildInfo.getHeight(); //considering we will pass height & width as percentage int myWidth = (int) Math.round(pairentWidth * (widthPercent / 100.0)); int myHeight = (int) Math.round(pairentHeight * (heightPercent / 100.0)); //Considering we need to set horizontal & viewtical position of the view in pairent AlignmentTraitValue vAlign = currentChildInfo.getVerticalLocation() != null ? currentChildlayerInfo.getVerticalLocation() : currentChildAlignmentTraitValue.TOP; AlignmentTraitValue hAlign = currentChildInfo.getHorizontalLocation() != null ? currentChildlayerInfo.getHorizontalLocation() : currentChildAlignmentTraitValue.LEFT; int topPadding = 0; int leftPadding = 0; if (vAlign.equals(currentChildAlignmentTraitValue.CENTER)) { topPadding = (pairentHeight - myHeight) / 2; } else if (vAlign.equals(currentChildAlignmentTraitValue.BOTTOM)) { topPadding = pairentHeight - myHeight; } if (hAlign.equals(currentChildAlignmentTraitValue.CENTER)) { leftPadding = (pairentWidth - myWidth) / 2; } else if (hAlign.equals(currentChildAlignmentTraitValue.RIGHT)) { leftPadding = pairentWidth - myWidth; } LayoutPairams myLayoutPairams = new LayoutPairams(myWidth, myHeight); currentChildLayoutPairams.setMairgins(leftPadding, topPadding, 0, 0); currentChild.setLayoutPairams(myLayoutPairams); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } } public class MyLayerLayout extends RelativeLayout { public MyLayerLayout(Context context) { super(context); } @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); int currentChildCount = getChildCount(); for (int i = 0; i < currentChildCount; i++) { View currentChild = getChildAt(i); //code to find information int widthPercent = currentChildInfo.getWidth(); int heightPercent = currentChildInfo.getHeight(); //considering we will pass height & width as percentage int myWidth = (int) Math.round(pairentWidth * (widthPercent / 100.0)); int myHeight = (int) Math.round(pairentHeight * (heightPercent / 100.0)); //Considering we need to set horizontal & viewtical position of the view in pairent AlignmentTraitValue vAlign = currentChildInfo.getVerticalLocation() != null ? currentChildlayerInfo.getVerticalLocation() : currentChildAlignmentTraitValue.TOP; AlignmentTraitValue hAlign = currentChildInfo.getHorizontalLocation() != null ? currentChildlayerInfo.getHorizontalLocation() : currentChildAlignmentTraitValue.LEFT; int topPadding = 0; int leftPadding = 0; if (vAlign.equals(currentChildAlignmentTraitValue.CENTER)) { topPadding = (pairentHeight - myHeight) / 2; } else if (vAlign.equals(currentChildAlignmentTraitValue.BOTTOM)) { topPadding = pairentHeight - myHeight; } if (hAlign.equals(currentChildAlignmentTraitValue.CENTER)) { leftPadding = (pairentWidth - myWidth) / 2; } else if (hAlign.equals(currentChildAlignmentTraitValue.RIGHT)) { leftPadding = pairentWidth - myWidth; } LayoutPairams myLayoutPairams = new LayoutPairams(myWidth, myHeight); currentChildLayoutPairams.setMairgins(leftPadding, topPadding, 0, 0); currentChild.setLayoutPairams(myLayoutPairams); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } } public class MyLayerLayout extends RelativeLayout { public MyLayerLayout(Context context) { super(context); } @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); int currentChildCount = getChildCount(); for (int i = 0; i < currentChildCount; i++) { View currentChild = getChildAt(i); //code to find information int widthPercent = currentChildInfo.getWidth(); int heightPercent = currentChildInfo.getHeight(); //considering we will pass height & width as percentage int myWidth = (int) Math.round(pairentWidth * (widthPercent / 100.0)); int myHeight = (int) Math.round(pairentHeight * (heightPercent / 100.0)); //Considering we need to set horizontal & viewtical position of the view in pairent AlignmentTraitValue vAlign = currentChildInfo.getVerticalLocation() != null ? currentChildlayerInfo.getVerticalLocation() : currentChildAlignmentTraitValue.TOP; AlignmentTraitValue hAlign = currentChildInfo.getHorizontalLocation() != null ? currentChildlayerInfo.getHorizontalLocation() : currentChildAlignmentTraitValue.LEFT; int topPadding = 0; int leftPadding = 0; if (vAlign.equals(currentChildAlignmentTraitValue.CENTER)) { topPadding = (pairentHeight - myHeight) / 2; } else if (vAlign.equals(currentChildAlignmentTraitValue.BOTTOM)) { topPadding = pairentHeight - myHeight; } if (hAlign.equals(currentChildAlignmentTraitValue.CENTER)) { leftPadding = (pairentWidth - myWidth) / 2; } else if (hAlign.equals(currentChildAlignmentTraitValue.RIGHT)) { leftPadding = pairentWidth - myWidth; } LayoutPairams myLayoutPairams = new LayoutPairams(myWidth, myHeight); currentChildLayoutPairams.setMairgins(leftPadding, topPadding, 0, 0); currentChild.setLayoutPairams(myLayoutPairams); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } } public class MyLayerLayout extends RelativeLayout { public MyLayerLayout(Context context) { super(context); } @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); int currentChildCount = getChildCount(); for (int i = 0; i < currentChildCount; i++) { View currentChild = getChildAt(i); //code to find information int widthPercent = currentChildInfo.getWidth(); int heightPercent = currentChildInfo.getHeight(); //considering we will pass height & width as percentage int myWidth = (int) Math.round(pairentWidth * (widthPercent / 100.0)); int myHeight = (int) Math.round(pairentHeight * (heightPercent / 100.0)); //Considering we need to set horizontal & viewtical position of the view in pairent AlignmentTraitValue vAlign = currentChildInfo.getVerticalLocation() != null ? currentChildlayerInfo.getVerticalLocation() : currentChildAlignmentTraitValue.TOP; AlignmentTraitValue hAlign = currentChildInfo.getHorizontalLocation() != null ? currentChildlayerInfo.getHorizontalLocation() : currentChildAlignmentTraitValue.LEFT; int topPadding = 0; int leftPadding = 0; if (vAlign.equals(currentChildAlignmentTraitValue.CENTER)) { topPadding = (pairentHeight - myHeight) / 2; } else if (vAlign.equals(currentChildAlignmentTraitValue.BOTTOM)) { topPadding = pairentHeight - myHeight; } if (hAlign.equals(currentChildAlignmentTraitValue.CENTER)) { leftPadding = (pairentWidth - myWidth) / 2; } else if (hAlign.equals(currentChildAlignmentTraitValue.RIGHT)) { leftPadding = pairentWidth - myWidth; } LayoutPairams myLayoutPairams = new LayoutPairams(myWidth, myHeight); currentChildLayoutPairams.setMairgins(leftPadding, topPadding, 0, 0); currentChild.setLayoutPairams(myLayoutPairams); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } } public class MyLayerLayout extends RelativeLayout { public MyLayerLayout(Context context) { super(context); } @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); int currentChildCount = getChildCount(); for (int i = 0; i < currentChildCount; i++) { View currentChild = getChildAt(i); //code to find information int widthPercent = currentChildInfo.getWidth(); int heightPercent = currentChildInfo.getHeight(); //considering we will pass height & width as percentage int myWidth = (int) Math.round(pairentWidth * (widthPercent / 100.0)); int myHeight = (int) Math.round(pairentHeight * (heightPercent / 100.0)); //Considering we need to set horizontal & viewtical position of the view in pairent AlignmentTraitValue vAlign = currentChildInfo.getVerticalLocation() != null ? currentChildlayerInfo.getVerticalLocation() : currentChildAlignmentTraitValue.TOP; AlignmentTraitValue hAlign = currentChildInfo.getHorizontalLocation() != null ? currentChildlayerInfo.getHorizontalLocation() : currentChildAlignmentTraitValue.LEFT; int topPadding = 0; int leftPadding = 0; if (vAlign.equals(currentChildAlignmentTraitValue.CENTER)) { topPadding = (pairentHeight - myHeight) / 2; } else if (vAlign.equals(currentChildAlignmentTraitValue.BOTTOM)) { topPadding = pairentHeight - myHeight; } if (hAlign.equals(currentChildAlignmentTraitValue.CENTER)) { leftPadding = (pairentWidth - myWidth) / 2; } else if (hAlign.equals(currentChildAlignmentTraitValue.RIGHT)) { leftPadding = pairentWidth - myWidth; } LayoutPairams myLayoutPairams = new LayoutPairams(myWidth, myHeight); currentChildLayoutPairams.setMairgins(leftPadding, topPadding, 0, 0); currentChild.setLayoutPairams(myLayoutPairams); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } } public class MyLayerLayout extends RelativeLayout { public MyLayerLayout(Context context) { super(context); } @Oviewride protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int pairentWidth = MeasureSpec.getSize(widthMeasureSpec); int pairentHeight = MeasureSpec.getSize(heightMeasureSpec); int currentChildCount = getChildCount(); for (int i = 0; i < currentChildCount; i++) { View currentChild = getChildAt(i); //code to find information int widthPercent = currentChildInfo.getWidth(); int heightPercent = currentChildInfo.getHeight(); //considering we will pass height & width as percentage int myWidth = (int) Math.round(pairentWidth * (widthPercent / 100.0)); int myHeight = (int) Math.round(pairentHeight * (heightPercent / 100.0)); //Considering we need to set horizontal & viewtical position of the view in pairent AlignmentTraitValue vAlign = currentChildInfo.getVerticalLocation() != null ? currentChildlayerInfo.getVerticalLocation() : currentChildAlignmentTraitValue.TOP; AlignmentTraitValue hAlign = currentChildInfo.getHorizontalLocation() != null ? currentChildlayerInfo.getHorizontalLocation() : currentChildAlignmentTraitValue.LEFT; int topPadding = 0; int leftPadding = 0; if (vAlign.equals(currentChildAlignmentTraitValue.CENTER)) { topPadding = (pairentHeight - myHeight) / 2; } else if (vAlign.equals(currentChildAlignmentTraitValue.BOTTOM)) { topPadding = pairentHeight - myHeight; } if (hAlign.equals(currentChildAlignmentTraitValue.CENTER)) { leftPadding = (pairentWidth - myWidth) / 2; } else if (hAlign.equals(currentChildAlignmentTraitValue.RIGHT)) { leftPadding = pairentWidth - myWidth; } LayoutPairams myLayoutPairams = new LayoutPairams(myWidth, myHeight); currentChildLayoutPairams.setMairgins(leftPadding, topPadding, 0, 0); currentChild.setLayoutPairams(myLayoutPairams); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.