findViewById no fragmento


1035

Estou tentando criar um ImageView em um fragmento que se refere ao elemento ImageView que eu criei no XML para o fragmento. No entanto, o findViewByIdmétodo só funciona se eu estender uma classe Activity. Existe alguma maneira de que eu possa usá-lo também no Fragment?

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ImageView imageView = (ImageView)findViewById(R.id.my_image);
        return inflater.inflate(R.layout.testclassfragment, container, false);
    }
}

O findViewByIdmétodo possui um erro que indica que o método é indefinido.


Use a biblioteca de ligação visual do ButterKnife para o Android. Também demonstre como funciona, como integrar e usar no desenvolvimento de aplicativos Android para acelerar seu desenvolvimento.
Shomu

Já passou algum tempo, mas você ainda não aceitou uma resposta. Você pode selecionar a resposta que mais lhe ajudou, para que possa ser marcada como respondida?
precisa saber é o seguinte

É recomendável usar o Data Binding ou o View Binding em vez do manual findViewById
mochadwi

Respostas:


1433

Use getView () ou o parâmetro View da implementação do onViewCreatedmétodo. Retorna a visualização raiz do fragmento (aquele retornado pelo onCreateView()método) . Com isso você pode ligar findViewById().

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    ImageView imageView = (ImageView) getView().findViewById(R.id.foo);
    // or  (ImageView) view.findViewById(R.id.foo); 

Como getView()funciona somente depois onCreateView(), você não pode usá-lo dentro onCreate()ou nos onCreateView()métodos do fragmento.


323
Nota: funciona somente após onCreateView (). Assim, você não pode usar isso em onCreate ()
Dmitry Zaytsev

7
então, qual é a função que eu posso substituir para implementar isso se onCreate não for o lugar certo?
Nico AD

16
Isso não ajuda se o ImageViewlayout for inflado - veja minha resposta para obter detalhes. Caso contrário, onCreateView é o lugar certo para fazer isso @ N-AccessDev
MattJenko

25
O melhor lugar para fazer isso do método onViewCreated
advantej

37
A documentação indica que onActivityCreated()é o local recomendado para encontrar e armazenar referências às suas visualizações. Você deve limpar essas referências armazenadas configurando-as novamente para nulldentro onDestroyView()ou poderá vazar o arquivo Activity.
Monstieur

618

Você precisa aumentar a exibição do fragmento e chamar findViewById()o Viewretorno.

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
     return view;
}

4
Quando você faz V.findViewById (R.id.someid), certamente isso funcionará apenas para todos os widgets que estão na exibição inflada. E se o imageView que ele está tentando inflar estiver fora da vista inflada?
Raunak

18
Em seguida, a classe que "possui" e inflou o imageView precisa fornecer acesso público a ele. Essa é uma prática muito ruim. Os fragmentos devem ter acesso apenas aos elementos da interface do usuário presentes em seu layout.
LeffelMania 14/10

1
Parece que há algo errado no seu código (atualizando a interface do usuário a partir de um thread em segundo plano), não o meu.
LeffelMania 13/09

1
Obrigado, foi útil. Como comentário não relacionado: tente manter as convenções de nomenclatura Java no seu código. "V" não se parece com um nome de variável em Java.
altumano 12/10

3
Essa deve ser a resposta certa. O aceito deixa você com NullPointerException.
Machado

132

Dentro da Fragmentclasse, você obterá o método de substituição onViewCreated () , onde você deve sempre inicializar suas visualizações, pois neste método você obtém o objeto de exibição usando o qual pode encontrar suas visualizações como:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.findViewById(R.id.yourId).setOnClickListener(this);

    // or
    getActivity().findViewById(R.id.yourId).setOnClickListener(this);
}

Lembre-se sempre, no caso de Fragment, de que o onViewCreated()método não será chamado automaticamente se você retornar nulo ou super.onCreateView()do onCreateView()método. Ele será chamado por padrão em caso de ListFragmentcomo ListFragmentretorno FrameLayoutpor padrão.

Nota: você pode obter a visualização do fragmento em qualquer lugar da classe usando getView()uma vez que onCreateView()tenha sido executado com êxito. ie

getView().findViewById("your view id");

4
Estou surpreso que muitas pessoas não tenham votado nessa resposta - esta é a maneira correta de configurar ouvintes em fragmentos ... Talvez esse tenha sido um novo desenvolvimento na API.
Sonny

Usar viewpassado para onViewCreatedcausas estáticas, NullPointerExceptionmas usar getActivity()é bom. Alguma idéia do porquê?
dVaffection

@dVaffection Pode ser que você não esteja retornando uma exibição não nula no método de fragmento onCreateView () do ciclo de vida. Agora, no caso de getActivity, você está obtendo visualizações de sua atividade em vez da visualização principal de fragmentos, dependendo do ID que você está passando. Verifique se você está retornando uma visualização não nula do onCreateView ou não? Então me avise.
Ankur Chaudhary

@AnkurChaudhary Retorno a visualização do onCreateViewmétodo. Acabei de depurar e verifica-se que há um layout (no meu caso FrameLayout). Dito isto, quando tento encontrar um elemento, ele retorna null. Por que isso está acontecendo?
dVaffection

@dVaffection, você pode compartilhar sua classe de fragmento e o layout correspondente.
Ankur Chaudhary

66

Sei que essa é uma pergunta antiga, mas a resposta predominante deixa algo a desejar.

A questão não está clara do que é necessário imageView- estamos passando de volta como visão ou apenas guardando uma referência para mais tarde?

De qualquer maneira, se o resultado ImageViewfor do layout inflado, a maneira correta de fazer isso seria:

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
        return v;
    }
}

1
Como você atualizaria o imageView do ListFragment? Isso exigiria o FragmentManager? Em outras palavras, como você pode atualizar o imageView em um fragmento de detalhe do onListItemClick de uma classe separada?
whyoz

1
Você pode salvar uma referência ao imageView em algum lugar útil ou fragment.getView (). FindViewById (R.id.my_image) quando necessário. Em um ListFragment, assumindo que a imagem esteja em um item da lista, você geralmente criaria um suporte de referência com os métodos setTag / getTag do item de exibição de lista no método getView do seu adaptador - há muitos exemplos de como fazer isso.
MattJenko

47

Obtenha primeiro a visualização do fragmento e, a partir dessa visualização, seu ImageView.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
    return view;
}

Então, o método onCreate é útil em um fragmento?
tsunaze

onCreateView cria e retorna a hierarquia de exibição associada ao fragmento.onCreate é chamado para fazer a criação inicial do fragmento. De fato, depende do que você escreve nesses métodos.
xevincent

Ok, mas como posso declarar variável no onCreate? Porque o View está dentro do método onCreateView.
tsunaze

@Tsunaze você já descobriu como fazer isso usando o método onCreate?
StuStirling

1
Concordo. Esta resposta deve ser marcada como a solução.
Boris Karloff

25

Você também pode fazer isso no onActivityCreatedmétodo

public void onActivityCreated(Bundle savedInstanceState) { 
      super.onActivityCreated(savedInstanceState);
}

Como eles fazem aqui: http://developer.android.com/reference/android/app/Fragment.html (descontinuado no nível 28 da API)

getView().findViewById(R.id.foo);

e

getActivity().findViewById(R.id.foo);

e possivel.



17

Você pode substituir onViewCreated (), que é chamado logo após todas as visualizações terem sido infladas. É o lugar certo para preencher as Viewvariáveis ​​de membro do seu fragmento . Aqui está um exemplo:

class GalleryFragment extends Fragment {
    private Gallery gallery;

    (...)

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        gallery = (Gallery) view.findViewById(R.id.gallery);
        gallery.setAdapter(adapter);
        super.onViewCreated(view, savedInstanceState);
    }
}

17

Dentro da Fragmentclasse, obtemos o onViewCreated()método override, onde devemos sempre inicializar nossas visualizações, porque nesse método obtemos o viewobjeto. Usando este objeto, podemos encontrar nossos pontos de vista como abaixo:

class MyFragment extends Fragment {
    private ImageView imageView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_fragment_layout, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //initialize your view here for use view.findViewById("your view id")
        imageView = (ImageView) view.findViewById(R.id.my_image);
    }
}

2
excelente funcionou bem! muito obrigado
Vivek

15

O método getView () não funcionará em fragmentos fora do OnCreate e métodos similares.

Você tem duas maneiras: passar a visualização para a função oncreate (o que significa que você só pode executar suas funções quando a visualização estiver sendo criada) ou definir a visualização como uma variável:

private View rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.fragment_contatos, container, false);
}

public void doSomething () {
    ImageView thumbnail = (ImageView) rootView.findViewById(R.id.someId);
}

11

1) primeiro inflar o layout do Fragment, então você pode usar o findviewbyId.

View view = inflater.inflate(R.layout.testclassfragment, container, false);
             ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
             return view;

10
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);  

9

Usar

imagebutton = (ImageButton) getActivity().findViewById(R.id.imagebutton1);

imageview = (ImageView) getActivity().findViewById(R.id.imageview1);

vai funcionar


9

concordou em invocar findViewById()a Visão.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View V = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) V.findViewById(R.id.my_image);

    return V;
}

9

Nota :

No nível 26 da API, você também não precisa converter especificamente o resultado de findViewById, pois ele usa inferência para seu tipo de retorno.

Então agora você pode simplesmente fazer,

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView =  view.findViewById(R.id.my_image); //without casting the return type
     return view;
}

1
Sem lançar coisa explicada me ajudou.
Shaurya Uppal

8

De acordo com a documentação no nível 11 da API

Referência, em Back Stack http://developer.android.com/reference/android/app/Fragment.html

Código curto

/**
 * The Fragment's UI is just a simple text view showing its
 * instance number.
 */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.hello_world, container, false);
    View tv = v.findViewById(R.id.text);
    ((TextView)tv).setText("Fragment #" + mNum);
    tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
    return v;
}

8

Using getView()retorna a visão do fragmento, então você pode chamar findViewById()para acessar qualquer elemento de visão na visão de fragmento.


3
a visão não é a actividade
Steve M

7

Tente isso, funciona para mim

public class TestClass extends Fragment {
    private ImageView imageView;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.testclassfragment, container, false);
        findViews(view);
        return view;
    }

    private void findViews(View view) {
        imageView = (ImageView) view.findViewById(R.id.my_image);
    }
}

Sim, este código aqui está correto. Suas edições na outra não são.
OneCricketeer

@ cricket_007 ok qual deles você pode me ver?
Bipin Bharti

Sinto muito, mas não consigo entender direito o seu inglês, mas tudo está resolvido agora. Não tenho nada para lhe mostrar.
OneCricketeer

5

A melhor maneira de implementar isso é a seguinte:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

rootView = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView) rootView.findViewById(R.id.my_image);
        return rootView
}

Dessa maneira, o rootView pode ser usado para cada controle definido no layout xml e o código é muito mais limpo dessa maneira.

Espero que isto ajude :)


i thinked este poderia ser posiible, mas, não funcionou
Mike Brian Olivera

5

1) Declare seu arquivo de layout.

public View onCreateView(LayoutInflater inflater,ViewGroup container, 
                                 Bundle savedInstanceState) {
    return inflate(R.layout.myfragment, container, false);
}

2) Em seguida, obtenha o ID da sua visualização

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    TextView nameView = (TextView) view.findViewById(R.id.textview1);
}

4

Use o plug- in gradle skeleton , ele gerará automaticamente as classes de suporte de exibição com a referência ao seu layout.

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        MyLayout myLayout = new MyLayout(inflater, container, false);
        myLayout.myImage.setImageResource(R.drawable.myImage);
        return myLayout.view;
    }
}

Agora, supondo que você tenha um ImageViewdeclarado em seu my_layout.xmlarquivo, ele gerará automaticamente a classe myLayout para você.


4

Tente isto:

View v = inflater.inflate(R.layout.testclassfragment, container, false);
ImageView img = (ImageView) v.findViewById(R.id.my_image);

return v;

4

tentar

private View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
myFragmentView = inflater.inflate(R.layout.myLayoutId, container, false);
myView = myFragmentView.findViewById(R.id.myIdTag)
return myFragmentView;
}

Não há razão para o campo. Você sempre pode ligar getView()mais tarde
OneCricketeer 8/17

3

Você pode chamar findViewById()com o Objeto de Atividade que você obtém dentro do seu public void onAttach(Activity activity)método dentro do seu Fragmento.

Salve a atividade em uma variável, por exemplo:

Na classe Fragment : private Activity mainActivity; No onAttach()método: this.mainActivity=activity;

Por fim, execute cada findViewById através do variável: mainActivity.findViewById(R.id.TextView);


3

Há mais um método chamado onViewCreated.

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ImageView imageView = (ImageView) view.findViewById(R.id.imageview1);
}

2

Método interno onCreateView

1) primeiro você precisa aumentar o layout / visualização que deseja adicionar, por exemplo. LinearLayout

LinearLayout ll = inflater.inflate(R.layout.testclassfragment, container, false);

2) Em seguida, você pode encontrar seu ID do imageView no layout

ImageView imageView = (ImageView)ll.findViewById(R.id.my_image);

3) retorne o layout inflado

return ll;

Isso é idêntico à resposta da LeffelMania.
Reti43

2

Você tem que aumentar a vista

public class TestClass extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
    return v
}}

2

Nos fragmentos, precisamos de uma visualização dessa janela para fazer um onCreateView desse fragmento.

Em seguida, obtenha a visualização e use-a para acessar todo e qualquer ID de visualização dos elementos da visualização.

  class Demo extends Fragment
    {
        @Override
        public View onCreateView(final LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState)
        {
            View view =inflater.inflate(R.layout.demo_fragment, container,false);
            ImageView imageview=(ImageView)view.findViewById(R.id.imageview1);

            return view;
        }
    }

1) O que isso acrescenta a outras respostas? 2) Você parece ter respondido duas vezes
OneCricketeer 8/17/17

2

O inflator de layout entra em cena aqui. O inflator de layout é uma classe que nos permite usar as visualizações XML no código java. Portanto, você pode aumentar a visualização xml raiz na variável v com o seguinte código. E, em seguida, usando v, você pode encontrar as visualizações filho da visualização raiz v.

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
    return v;
    }
}

1

A maneira mais fácil de usar essas coisas é usar o canivete. Com isso, você pode adicionar quantos Onclciklisteners apenas por @OnClick (), conforme descrito abaixo:

public class TestClass extends Fragment {
    @BindView(R.id.my_image) ImageView imageView;
    @OnClick(R.id.my_image)
    public void my_image_click(){
        yourMethod();
    }
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.testclassfragment, container, false);
        ButterKnife.bind(getActivity,view);
        return view;
    }
}

Por que votou negativamente, se você usar isso, poderá usar vários onclicks também na declaração.
Amit
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.