Fragment'ta findViewById


1035

Parça için XML'de oluşturduğunuz ImageView öğesine atıfta bulunacak bir parça içinde bir ImageView oluşturmaya çalışıyorum. Ancak, findViewByIdyöntem yalnızca bir Activity sınıfını genişletirsem çalışır. Fragment'te de kullanabileceğim bir şey var mı?

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);
    }
}

findViewByIdYöntemin özelliği, yöntemin tanımlanmamış bildiren üzerinde bir hata var.


Android için ButterKnife vizör kütüphanesini kullanın. Ayrıca nasıl çalıştığını, gelişiminizi daha hızlı hale getirmek için android uygulama geliştirmenize nasıl entegre edileceğini ve kullanılacağını gösterin.
Shomu

'Biraz' zaman geçti ama hala bir cevap kabul etmedin. Yanıtlanmış olarak işaretlenebilmesi için size en çok yardımcı olan cevabı seçebilir misiniz?
David3103

Veri Bağlama orang Görünüm Bağlama kullanmak için teşvik edilir manuel findViewById
mochadwi

Yanıtlar:


1433

Yöntemi uygulamaktan getView () veya View parametresini kullanın onViewCreated. Parçanın ( onCreateView()yöntemle döndürülen ) kök görünümünü döndürür . Bununla arayabilirsin 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); 

As getView()sonra işler onCreateView(), sen içeride kullanamazsınız onCreate()veya onCreateView()yöntemler fragmanının.


323
Not: yalnızca onCreateView () öğesinden sonra çalışır. Yani, bunu onCreate () de kullanamazsınız
Dmitry Zaytsev

7
öyleyse onCreate doğru yer değilse bunu uygulamak için geçersiz kılabilecek işlev nedir?
Nico AD

16
ImageViewŞişirilmiş düzenden geliyorsa bu yardımcı olmaz - ayrıntılar için cevabım bakın. Aksi takdirde, onCreateView bunu yapmak için doğru yer @ N-AccessDev
MattJenko

25
Bunu yapmak için en iyi yer onViewCreated yöntemi
advantej

37
Belgeler onActivityCreated(), görüşlerinizi referans almak ve saklamak için önerilen yer olduğunu belirtir . Sen gerekir geri onları ayarlayarak bu depolanmış başvuruları temizlemek nulliçinde onDestroyView()ya da sızıntı olur Activity.
Monstieur

618

Sen Fragment görüşünü ve çağrıyı şişirmek gerekir findViewById()üzerinde Viewo getiriler.

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
V.findViewById (R.id.someid) yaptığınızda, bu kesinlikle şişirilmiş görünümdeki tüm widget'lar için çalışır. Ya şişirmeye çalıştığı imageView, şişirilmiş görünümün dışındaysa?
Raunak

18
Daha sonra "sahip olan" ve imageView'i şişiren sınıfın ona genel erişim sağlaması gerekir. Yine de bu çok kötü bir uygulamadır. Parçalar yalnızca düzenlerinde bulunan UI öğelerine erişebilmelidir.
LeffelMania

1
Görünüşe göre kodunuzda yanlış bir şey var (kullanıcı arayüzünü arka plan iş parçacığından güncelleme) benim değil.
LeffelMania

1
Teşekkürler, faydalı oldu. İlişkisiz yorum olarak: kodunuzdaki Java adlandırma kurallarına sadık kalmaya çalışın. "V", Java'da değişken adı gibi görünmüyor.
altumano

3
Bu doğru cevap olmalı. Kabul edilen kişi seni terk eder NullPointerException.
Machado

132

FragmentSınıf içinde görüşlerinizi her zaman başlatmanız gereken onViewCreated () geçersiz kılma yöntemini alacaksınız.

@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);
}

Her zaman olduğu Fragment durumunda hatırlamak onViewCreated()yöntemi null adlı veya iade otomatik eğer denilen olmaz super.onCreateView()den onCreateView()yöntemle. Varsayılan ListFragmentolarak ListFragmentgeri dönüş durumunda varsayılan olarak çağrılır FrameLayout.

Not: başarıyla yürütüldükten getView()sonra parçanın görünümünü sınıfın herhangi bir yerinde alabilirsiniz onCreateView(). yani

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

4
Birçok insanın bu yanıtı iptal etmediğine şaşırdım - bu, dinleyicileri parçalara kurmanın doğru yoludur ... Belki de bu API'da yeni bir gelişmeydi.
Sonny

Kullanma viewgeçirilen onViewCreatedhareketsiz nedenleri NullPointerExceptionancak kullanarak getActivity()gayet iyi. Neden herhangi bir fikir?
dVaffection

@dVaffection Parça onCreateView () yaşam döngüsü yönteminde boş olmayan bir görünüm döndürmüyor olabilirsiniz. Şimdi getActivity durumunda, parça ana görünümünden ziyade etkinliğinizden görünümler alıyorsunuz, hangi kimliği geçtiğinize bağlı. Lütfen onCreateView öğesinden boş olmayan bir görünüm döndürüp döndürmediğinizi kontrol edin. O zaman bana haber ver.
Ankur Chaudhary

@AnkurChaudhary Yöntemden görünüm döndürürüm onCreateView. Sadece hata ayıkladım ve bir düzen var (benim durumumda FrameLayout) çıkıyor. Geri dönen bir eleman bulmaya çalıştığımda söyleniyor null. Neden oluyor?
dVaffection

@ dVaffection, lütfen parça ve sınıf düzeninizi paylaşır mısınız?
Ankur Chaudhary

66

Bunun eski bir soru olduğunu anlıyorum, ama hakim cevap arzulanan bir şey bırakıyor.

Soru, neyin gerekli olduğu konusunda net değil imageView- onu görünüm olarak geri mi aktarıyoruz yoksa yalnızca daha sonra başvurmak için mi kaydediyoruz?

Her iki durumda ImageViewda, şişirilmiş düzenden geliyorsa, bunu yapmanın doğru yolu şöyle olacaktır:

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
O zaman imageView'ı ListFragment'tan nasıl güncellersiniz? Bu FragmentManager gerektirir mi? Başka bir deyişle, imageView'i ayrı bir sınıfın onListItemClick'inden ayrıntılı bir parçada nasıl güncelleyebilirsiniz?
whyoz

1
İmageView'e bir referansı kullanışlı bir yere kaydedersiniz veya fragment.getView (). FindViewById (R.id.my_image) gerektiğinde. ListFragment'ta, görüntünün bir liste öğesinde olduğu varsayılarak, genellikle Bağdaştırıcınızın getView yöntemindeki liste görünümü öğesinin setTag / getTag yöntemleriyle bir başvuru sahibi oluşturabilirsiniz - bunun nasıl yapılacağına dair birçok örnek vardır.
MattJenko

47

Önce fragman görünümünü alın ve sonra bu görünümden ImageView'inizi alın.

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;
}

Peki, onCreate yöntemi bir Fragment'te faydalı mı?
Tsunaze

onCreateView, fragment ile ilişkili görünüm hiyerarşisini oluşturur ve döndürür. onCreate, parçanın ilk oluşturulmasını yapmaya çağrılır. Gerçekten de, bu yöntemlerde ne yazdığınıza bağlıdır.
xevincent

Tamam, ama onCreate'da nasıl değişken bildirebilirim? Çünkü Görünüm onCreateView yönteminin içindedir.
Tsunaze

@Tsunaze bunu onCreate yönteminden nasıl yapacağınızı öğrendiniz mi?
StuStirling

1
Katılıyorum. Bu cevap çözüm olarak işaretlenmelidir.
Boris Karloff

25

Ayrıca onActivityCreatedYöntem içinde yapabilirsiniz .

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

Burada yaptıkları gibi: http://developer.android.com/reference/android/app/Fragment.html (API 28 düzeyinde kullanımdan kaldırıldı)

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

ve

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

mümkün.



17

Tüm görünümler şişirildikten hemen sonra çağrılan onViewCreated () yöntemini geçersiz kılabilirsiniz. Parçanızın üye Viewdeğişkenlerini doldurmak için doğru yer . İşte bir örnek:

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

FragmentSınıf içinde onViewCreated()her zaman görüşlerimizi başlatmamız gereken geçersiz kılma yöntemini alırız çünkü bu yöntemde viewnesne alırız . Bu nesneyi kullanarak görüşlerimizi aşağıdaki gibi bulabiliriz:

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
mükemmel iyi çalıştı! çok teşekkürler
Vivek

15

GetView () yöntemi OnCreate ve benzeri yöntemler dışındaki parçalarda çalışmaz.

İki yolunuz vardır, görünümü oncreate'daki işleve geçirin (yani, işlevlerinizi yalnızca görünüm oluşturulurken çalıştırabileceğiniz anlamına gelir) veya görünümü bir değişken olarak ayarlayın:

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) önce Fragment düzenini şişirmek sonra findviewbyId kullanabilirsiniz.

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

kullanım

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

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

Çalışacak


9

findViewById()Görünümü çağırmayı kabul etti .

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

Not :

API Seviye 26'dan, dönüş türü için çıkarım kullandığından findViewById sonucunu özellikle yayınlamanız gerekmez.

Böylece artık sadece

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
Açıklanamayan bir şey olmadan bana yardımcı oldu.
shaurya uppal

8

API düzey 11'deki belgelere göre

Referans, Geri Yığın'da http://developer.android.com/reference/android/app/Fragment.html

kısa kod

/**
 * 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

Kullanarak getView()parçanın görünümünü döndürür, ardından findViewById()parça görünümündeki herhangi bir görünüm öğesine erişmek için arayabilirsiniz .


3
görünüm etkinlik değil
Steve M

7

Bunu dene benim için çalışıyor

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);
    }
}

Evet, buradaki kod tamam. Diğerinde yaptığınız düzenlemeler değil.
OneCricketeer

@ cricket_007 tamam hangisini görebiliyorsun?
Bipin Bharti

Üzgünüm, İngilizcenizi tam olarak anlayamıyorum, ama şimdi her şey düzeltildi. Sana gösterecek hiçbir şeyim yok.
OneCricketeer

5

Bunu uygulamanın en iyi yolu şöyledir:

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
}

Bu şekilde, rootView, xml mizanpajında ​​tanımlanan her kontrol için kullanılabilir ve kod bu şekilde çok daha temizdir.

Bu yardımcı olur umarım :)


bunun mümkün olabileceğini düşündüm, ama işe yaramadı
Mike Brian Olivera

5

1) Düzen dosyanızı beyan edin.

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

2) Ardından, görünümünüzün kimliğini alın

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

4

Gradle skeleton eklentisini kullanın , düzeninize referansla otomatik olarak görünüm tutucu sınıflarını oluşturur.

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;
    }
}

Dosyanızda ImageViewbeyan edilmiş olduğunuzu varsayarsak , sizin için my_layout.xmlotomatik olarak myLayout sınıfını oluşturur.


4

Bunu dene:

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

return v;

4

Deneyin

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;
}

Tarla için bir sebep yok. Daha getView()sonra
istediğiniz

3

Sen diyebilirsin findViewById()ile Etkinlik Nesne size içeri public void onAttach(Activity activity)sizin Fragment içeride yöntemle.

Etkinliği bir değişkene kaydedin, örneğin:

İçinde Parçacık sınıf : private Activity mainActivity; in onAttach()yöntemi: this.mainActivity=activity;

Sonunda varolan ile her findViewById yürütmek: mainActivity.findViewById(R.id.TextView);


3

OnViewCreated adlı bir yöntem daha var.

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

2

Inside onCreateView yöntemi

1) önce eklemek istediğiniz düzeni / görünümü şişirmeniz gerekir örn. LinearLayout

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

2) Ardından imageView kimliğinizi mizanpajdan bulabilirsiniz

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

3) şişirilmiş düzeni iade edin

return ll;

Bu LeffelMani'nin cevabı ile aynı.
Reti43

2

Görünümü şişirmelisin

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

Parçalarda, bu Parçanın bir onCreateView'ını yapabilmemiz için o pencerenin bir görünümüne ihtiyacımız var.

Ardından görünümü alın ve bu görünüm öğelerinin her bir görünüm kimliğine erişmek için kullanın.

  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) Bu diğer cevaplara ne katıyor? 2) İki kez cevap
vermişsiniz

2

Yerleşim şişirme burada resme giriyor. Layout inflater, XML görünümlerini java kodunda kullanabilmemizi sağlayan bir sınıftır. Böylece v değişkenindeki kök xml görünümünü aşağıdaki kodla şişirebilirsiniz. Ve sonra v'yi kullanarak kök görünümünün alt görünümlerini bulabilirsiniz.

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

Bu tür şeyleri kullanmanın en kolay yolu butterknife kullanmaktır. Bununla, aşağıda açıklandığı gibi @OnClick () ile çok sayıda Onclciklistener ekleyebilirsiniz:

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;
    }
}

Neden aşağı oy verdiniz, bunu kullanırsanız, açıklamada da birden fazla onclick kullanabilirsiniz.
Amit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.