Primeiro de tudo: sim, eu li todos os outros tópicos sobre este tópico. E não apenas os deste site ... (veja, estou um pouco frustrado)
A maioria deles vem com o conselho de usar, em android:id
vez de apenas id
no arquivo XML. Eu fiz.
Aprendi que dos outros isso View.findViewById
funciona de maneira diferente Activity.findViewById
. Eu lidei com isso também.
No meu location_layout.xml
, eu uso:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="@+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
Na minha atividade eu faço:
...
setContentView( R.layout.location_layout );
e na minha classe de exibição personalizada:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
que retorna null
. Fazendo isso, minha Atividade funciona bem. Então talvez seja por causa da Activity.findViewById
e View.findViewById
diferenças. Então, eu armazenei o contexto passado para o construtor de exibição da alfândega localmente e tentei:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
que também retornou null
.
Então, eu mudei meu modo de exibição personalizado para estender ViewGroup
vez View
e mudou a location_layout.xml
deixar a TextView
ser um filho direto do meu ponto de vista personalizado, de modo que o View.findViewById
deve funcionar como deveria. Surpresa: não resolveu nada.
Então, o que diabos estou fazendo de errado?
Eu aprecio qualquer comentário.
fonte
Respostas:
Possivelmente porque você está ligando muito cedo. Espere até
onFinishInflate()
. Aqui está um projeto de amostra demonstrando umView
acesso personalizado ao seu conteúdo.fonte
onFinishInflate()
.Possivelmente, você está ligando
findViewById
antes de ligarsetContentView
? Se for esse o caso, tente ligarfindViewById
APÓS ligarsetContentView
fonte
Verifique se você não possui várias versões do seu layout para diferentes densidades de tela. Encontrei este problema uma vez ao adicionar um novo ID a um layout existente, mas esqueci de atualizar a versão do hdpi. Se você esquecer de atualizar todas as versões do arquivo de layout, ele funcionará para algumas densidades de tela, mas não para outras.
fonte
FindViewById pode ser nulo se você chamar o super construtor errado em uma exibição personalizada. A tag ID faz parte do attrs, portanto, se você ignorar o attrs, exclua o ID.
Isso seria errado
Isto está certo
fonte
No meu caso, eu tinha duas atividades no meu projeto,
main.xml
emain2.xml
. Desde o início,main2
era uma cópiamain
, e tudo funcionou bem, até que eu adicionei novoTextView
paramain2
, assim que oR.id.textview1
tornou-se disponível para o resto do aplicativo. Então tentei buscá-lo por chamada padrão:e sempre foi nulo. Aconteceu que no
onCreate
construtor eu estava instanciando nãomain2
, mas o outro. Eu tinha:ao invés de
Percebi isso depois que cheguei aqui, no site.
fonte
Juntamente com as causas clássicas, mencionadas em outros lugares:
setContentView()
antesfindViewById()
id
você deseja estar na exibição ou no layout fornecidosetContentView()
id
não seja duplicado acidentalmente em diferentes layoutsHá uma que encontrei para visualizações personalizadas em layouts padrão, que vão contra a documentação:
Em teoria, você pode criar uma exibição personalizada e adicioná-la a um layout ( veja aqui ). No entanto, descobri que nessas situações, às vezes, o
id
atributo funciona para todas as visualizações no layout, exceto as personalizadas. A solução que eu uso é:FrameLayout
com as mesmas propriedades de layout que você gostaria que a visualização personalizada tivesse. Dê um apropriadoid
, digamosframe_for_custom_view
.Em
onCreate
:que coloca a exibição personalizada no quadro.
fonte
fonte
Uma resposta para quem usa o ExpandableListView e se depara com essa pergunta com base no título.
Eu tive esse erro ao tentar trabalhar com TextViews em meus modos de exibição filho e grupo como parte de uma implementação ExpandableListView.
Você pode usar algo como o seguinte em suas implementações dos métodos getChildView () e getGroupView ().
Eu encontrei isso aqui .
fonte
Eu sou muito novo no Android / Eclipse, por engano, adicionei o material da interface do usuário ao
activity_main.xml
invés defragment_main.xml
. Levei algumas horas para descobrir isso ...fonte
FWIW, não vejo que alguém tenha resolvido isso da mesma maneira que eu precisava. Nenhuma reclamação no momento da compilação, mas eu estava obtendo uma exibição nula em tempo de execução e chamando as coisas na ordem correta. Ou seja, findViewById () após setContentView (). O problema acabou sendo que minha visão é definida em content_main.xml, mas em minha activity_main.xml, eu não tinha essa instrução:
Quando adicionei isso ao activity_main.xml, não mais NullPointer.
fonte
Eu tenho esse mesmo problema. Eu estava usando uma biblioteca de terceiros que permite substituir o adaptador para um GridView e especificar seu próprio layout para cada célula do GridView.
Eu finalmente percebi o que estava acontecendo. O Eclipse ainda estava usando o arquivo xml de layout da biblioteca para cada célula no GridView, mesmo que não desse indicação. No meu adaptador personalizado, ele indicava que estava usando o recurso xml do meu próprio projeto, embora em tempo de execução, não estivesse.
Então, o que fiz foi garantir que meus layouts e IDs personalizados em XML fossem diferentes daqueles que ainda estavam na biblioteca, limpando o projeto e, em seguida, ele começou a ler os layouts personalizados corretos que estavam no meu projeto.
Em resumo, tenha cuidado se estiver substituindo o adaptador de uma biblioteca de terceiros e especificando seu próprio xml de layout para o adaptador usar. Se o layout do seu projeto tiver o mesmo nome de arquivo da biblioteca, você poderá encontrar um bug realmente difícil de encontrar!
fonte
No meu caso particular, eu estava tentando adicionar um rodapé a um ListView. A seguinte chamada em onCreate () estava retornando nula.
Alterar isso para aumentar a exibição do rodapé em vez de encontrá-lo por ID resolveu esse problema.
fonte
No meu caso, eu estava usando o ExpandableListView e havia definido
android:transcriptMode="normal"
. Isso estava fazendo com que poucas crianças no grupo expansível desaparecessem e eu recebia a exceção NULL sempre que costumava rolar a lista.fonte
Para mim, eu tinha dois layouts de XML para a mesma atividade - um no modo retrato e outro na paisagem. É claro que eu havia mudado o id de um objeto no xml landscape, mas havia me esquecido de fazer a mesma alteração na versão retrato. Certifique-se de alterar um que você faça da mesma forma para o outro xml ou você não receberá um erro até executá-lo / depurá-lo e ele não poderá encontrar o ID que não mudou. Oh erros estúpidos, por que você deve me punir assim?
fonte
Defina o conteúdo da atividade de um recurso de layout. ie
setContentView(R.layout.basicXml)
.;fonte
Além das soluções acima, verifique se o
tools:context=".TakeMultipleImages"
layout possui o mesmo valor no arquivo mainfest.xml:android:name=".TakeMultipleImages"
para o mesmo elemento de atividade. ocorre quando usar copiar e colar para criar nova atividadefonte
Eu tenho o mesmo problema, mas acho que vale a pena compartilhar com vocês. Se você precisar localizar o ViewById no layout personalizado, por exemplo:
você não pode obter a visualização no construtor. Você deve chamar findViewById após a exibição ter sido inflada. É um método que você pode substituir
onFinishInflate
fonte
Só queria jogar meu caso específico aqui. Pode ajudar alguém abaixo da linha.
Eu estava usando a diretiva no meu XML da interface do usuário do Android assim:
Visualização principal:
Visualização filho (retry_button):
.findViewById (R.id.retry) sempre retornaria nulo. Mas, se eu movesse o ID da exibição filho para a tag include, ele começou a funcionar.
Pai fixo:
Filho fixo:
fonte
Meu caso não é como o anterior, nenhuma solução funcionou. Presumo que minha visão tenha sido muito profunda na hierarquia de layout. Mudei para um nível acima e não era mais nulo.
fonte
No meu caso, eu havia inflado o layout, mas as visualizações filho estavam retornando nulas. Originalmente eu tinha isso:
No entanto, quando eu mudei para o seguinte, funcionou:
A chave era referenciar especificamente o layout já inflado para obter as visualizações filho. Ou seja, para adicionar
footerView
:fonte
Na minha experiência, parece que isso também pode acontecer quando seu código é chamado após OnDestroyView (quando o fragmento está na pilha de trás). Se você estiver atualizando a interface do usuário na entrada de um BroadCastReceiver, verifique se esse é o caso .
fonte
INFLATE O LAYOUT !! (que contém o ID)
No meu caso, findViewById () retornou nulo, porque o layout no qual o elemento foi gravado não foi inflado ...
Por exemplo. fragment_layout.xml
findViewById (R.id.listview) retornou nulo, porque eu não havia feito inflater.inflate (R.layout.fragment_layout, ..., ...); antes disso.
Espero que esta resposta ajude alguns de vocês.
fonte
Minha correção foi apenas limpar o projeto.
fonte
O findViewById também pode retornar nulo se você estiver dentro de um fragmento. Conforme descrito aqui: findViewById no fragmento
Você deve chamar getView () para retornar a vista de nível superior dentro de um fragmento. Depois, você pode encontrar os itens de layout (botões, visualizações de texto etc.)
fonte
Eu tentei todas as opções acima, nada estava funcionando .. então tive que deixar meu ImageView estático
public static ImageView texture;
etexture = (ImageView) findViewById(R.id.texture_back);
, então , não acho que seja uma boa abordagem, mas isso realmente funcionou para o meu caso :)fonte
No meu caso, findViewById retornou nulo quando mudei a chamada de um objeto pai para um objeto adaptador instanciado pelo pai. Após tentar os truques listados aqui sem êxito, movi o findViewById de volta para o objeto pai e passei o resultado como um parâmetro durante a instanciação do objeto do adaptador. Por exemplo, eu fiz isso no objeto pai:
Depois passei o hdSpinner como parâmetro durante a criação do objeto do adaptador:
fonte
Falha para mim porque um dos campos no meu ID de atividade estava correspondendo ao ID em outra atividade. Corrigi-o, dando um ID único.
No meu loginActivity.xml, o ID do campo de senha era "password". Na minha atividade de registro, eu apenas o corrigi, fornecendo o ID r_password, e ele não retornou um objeto nulo:
fonte
Eu estava enfrentando um problema semelhante ao tentar fazer uma exibição personalizada para um
ListView
.Eu resolvi isso simplesmente fazendo o seguinte:
fonte
Maneiras de depurar e encontrar o problema:
No meu caso, eu estava usando o activity_main.xml no meu módulo de aplicativo e também no meu módulo de biblioteca. Portanto, quando eu executei as etapas acima, em vez do layout que criei na biblioteca, o layout dentro do módulo do aplicativo foi inflado.
Então, mudei o nome do arquivo activity_main.xml para activity_main_lib.xml.
Portanto, verifique se você não possui nomes de layout duplicados em todo o projeto .
fonte