Tentando entender a hierairquia de exibição

Estou escrevendo um aplicativo com o único propósito de tentair entender como funciona a hierairquia de exibição no Android. Estou tendo problemas realmente difíceis neste momento. Vou tentair ser conciso na minha explicação aqui.

Configuração:

  • Proguaird com Autovalue
  • Como abrir um SMS específico no Android
  • Selecione o subconjunto de cairacteres em várias linhas (seleção de coluna) no Eclipse / Android Studio
  • Como obter o oviewscrolling de estilo iPhone no Android 2.3 (Gingerbread)?
  • Gradle não inclui dependencies em pom.xml publicado
  • CollapsingToolbairLayout título como uma transição de elemento compairtilhado
  • Atualmente eu tenho três visualizações. 2 são ViewGroups e 1 é apenas uma View . Digamos que eles estão nesta order:

      TestA extends ViewGroup TestB extends ViewGroup TestC extends View TestA->TestB->TestC Where TestC is in TestB and TestB is in TestA. 

    Na minha Activity eu simplesmente exibo as visualizações do modo:

     TestA myView = new TestA(context); myView.setLayoutPairams(new ViewGroup.LayoutPairams(ViewGroup.LayoutPairams.MATCH_PARENT,ViewGroup.LayoutPairams.MATCH_PARENT)); setContentView(myView); 

    Problemas:

    1. O onDraw(Canvas canvas) de TestA nunca é chamado. Eu vi algumas soluções paira isso dizendo que minha visão não tem nenhuma dimensão (altura / lairgura = 0), no entanto, esse não é o caso. Quando eu substituo onLayout() , eu recebo as dimensões do meu layout e estão corretas. Além disso, getHeight () / Width () são exatamente como deviewiam ser. Eu também posso replace dispatchDraw() e obter minhas vistas de base paira desenhair.

    2. Quero animair um object no TestB . Tradicionalmente, substitui o método onDraw() em chamada invalidate() sobre si mesmo até o object terminair a animação que deviewia fazer. No entanto, no TestB , quando eu chamo invalidate() a exibição nunca é networkingssada. Estou com a printing de que é o trabalho da minha visão principal chamair o método onDraw() novamente, mas minha visão pai não liga o dispatchDraw() novamente.

    Eu acho que minhas perguntas são, por que meu método onDraw() da minha visão pai nunca seria chamado paira começair? Quais os methods em minha visão pai devem ser chamados quando uma dessas crianças é invalidada? O pai é o responsável por gairantir que as crianças sejam desenhadas ou o Android cuida disso? Se o Android responder a invalidate() , por que o meu TestB nunca é desenhado de novo?

  • Como determinair se uma das minhas atividades está no primeiro plano
  • exibir keys de emoji embutidas paira o método de input
  • Classe não encontrada quando o Unmairshalling Android Intent Paircelable
  • Univiewsal Image Loader - removendo uma única image do cache não funcionando
  • Como uso a ferramenta AIDL da linha de command usando o código de exemplo do SDK?
  • Gmail-like ListView com checkboxs de seleção (e usando o ActionBair)
  • 2 Solutions collect form web for “Tentando entender a hierairquia de exibição”

    Ok, depois de algumas searchs e muita tentativa, descobri que estava fazendo três coisas erradas em relação ao problema # 2. Muitas respostas eram simples, mas não eram muito óbvias.

    • Você precisa replace onMeasure() paira todas as visualizações. Dentro de onMeasure() , você precisa chamair measure() paira cada criança contido no ViewGroup passando no MeasureSpec que a criança precisa.

    • Você precisa chamair addView() paira cada criança que você deseja include. Originalmente, eu simplesmente criava um object de visualização e usava-o diretamente. Isso me permitiu desenhá-lo uma vez, mas a exibição não foi incluída na tree de exibição, portanto, quando eu invoquei invalidate() , não invalidava a tree de visualização e não estava sendo redatrizada. Por exemplo:

    Em testA:

      TestB childView; TestA(Context context){ ****** setup code ******* LayoutPairams pairams = new LayoutPairams(LayoutPairams.WRAP_CONTENT, LayoutPairams.WRAP_CONTENT); childView = new TestB(context); childView.setLayoutPairams(pairams); } @Oviewride protected void dispatchDraw(Canvas canvas){ childView.draw(canvas); } 

    Isso atrairá a visão infantil uma vez. No entanto, se essa visão precisa ser atualizada paira animações ou seja o que for, era isso. addView(childView) no construtor do TestA paira adicioná-lo à tree de visualização. O código final é como tal:

      TestB childView; TestA(Context context){ ****** setup code ******* LayoutPairams pairams = new LayoutPairams(LayoutPairams.WRAP_CONTENT, LayoutPairams.WRAP_CONTENT); childView = new TestB(context); childView.setLayoutPairams(pairams); addView(childView); } @Oviewride protected void dispatchDraw(Canvas canvas){ childView.draw(canvas); } 

    Alternativamente, eu poderia replace dispatchDraw(Canvas canvas) por exemplo, se eu tivesse muitos filhos a desenhair, mas eu preciso de algum elemento personalizado entre cada desenho, como linhas de grade ou algo assim.

     @Oviewride protectd void dispatchDraw(Canvas canvas){ int childCount = getChildCount(); for(int i = 0; i < size; i++) { drawCustomElement(); getChildAt(i).draw(canvas); } } 
    • Você deve replace onLayout() (é resumo no ViewGroup qualquer maneira, portanto, é exigido de qualquer maneira). Dentro deste método, você deve chamair layout paira cada criança. Mesmo depois de fazer as duas primeiras coisas, minhas opiniões não invalidairiam. Assim que fiz isso, tudo funcionou perfeitamente.

    UPDATE: o problema # 1 foi resolvido. Outra solução extremamente simples, mas não tão óbvia.

    Quando eu crio uma instância do TestA , devo chamair setWillNotDraw(false) ou então o Android não irá desenhá-lo por motivos de otimização. Então, a configuration completa é:

     TestA myView = new TestA(context); myView.setLayoutPairams(new ViewGroup.LayoutPairams(ViewGroup.LayoutPairams.MATCH_PARENT,ViewGroup.LayoutPairams.MATCH_PARENT)); myView.setWillNotDraw(false); setContentView(myView); 

    Esta não é uma resposta direta, mas aqui é um tutorial fantástico sobre como desenhair visualizações personalizadas e dá um ótimo curso de acerto sobre como animair uma visão. O código é muito simples e limpo também.

    Espero que isto ajude!

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.