findViewById di Fragment

1035

Saya mencoba membuat ImageView dalam Fragmen yang akan merujuk pada elemen ImageView yang telah saya buat dalam XML untuk Fragmen. Namun, findViewByIdmetode ini hanya berfungsi jika saya memperpanjang kelas Activity. Apakah ada yang bisa saya gunakan di Fragment juga?

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

The findViewByIdmetode memiliki kesalahan di atasnya yang menyatakan bahwa metode ini tidak terdefinisi.

disederhanakan.
sumber
Gunakan perpustakaan viewbinding ButterKnife untuk android. Juga tunjukkan cara kerjanya, bagaimana mengintegrasikan dan menggunakan dalam pengembangan aplikasi android Anda untuk membuat pengembangan Anda lebih cepat.
Shomu
'Beberapa waktu telah berlalu tetapi Anda masih belum menerima jawaban. Dapatkah Anda memilih jawaban yang paling membantu Anda sehingga ini dapat ditandai sebagai dijawab?
David3103
Dianjurkan untuk menggunakan Data Binding orang View Binding sebagai gantinya manual findViewById
mochadwi

Jawaban:

1433

Gunakan getView () atau parameter View dari penerapan onViewCreatedmetode. Ini mengembalikan tampilan root untuk fragmen (yang dikembalikan dengan onCreateView()metode) . Dengan ini, Anda dapat menelepon 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); 

Sebagai getView()hanya berfungsi setelah onCreateView(), Anda tidak dapat menggunakannya di dalam onCreate()atau onCreateView()metode fragmen.

untung
sumber
323
Catatan: ini hanya berfungsi setelah onCreateView (). Jadi, Anda tidak dapat menggunakan ini di onCreate ()
Dmitry Zaytsev
7
jadi apa fungsi yang bisa saya timpa untuk mengimplementasikan ini jika onCreate bukan tempat yang tepat?
Nico AD
16
Ini tidak membantu jika ImageViewberasal dari tata letak yang meningkat - lihat jawaban saya untuk detailnya. Kalau tidak, onCreateView adalah tempat yang tepat untuk melakukan ini @ N-AccessDev
MattJenko
25
Tempat terbaik untuk melakukan ini adalah metode
onViewCreated
37
Dokumentasi menyatakan bahwa itu onActivityCreated()adalah tempat yang direkomendasikan untuk menemukan dan menyimpan referensi ke pandangan Anda. Anda harus membersihkan ini referensi disimpan dengan menetapkan mereka kembali ke nulldalam onDestroyView()atau Anda akan membocorkan Activity.
Monstieur
618

Anda perlu untuk mengembang melihat dan panggilan Fragmen ini findViewById()pada Viewitu kembali.

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;
}
LeffelMania
sumber
4
Ketika Anda melakukan V.findViewById (R.id.someid), pasti itu hanya akan berfungsi untuk semua widget yang ada dalam tampilan yang meningkat. Bagaimana jika imageView yang sedang dia coba kembangkan berada di luar tampilan inflated?
Raunak
18
Maka kelas yang "memiliki" dan menggembungkan imageView perlu menyediakan akses publik ke sana. Itu adalah praktik yang sangat buruk. Fragmen seharusnya hanya memiliki akses ke elemen UI yang ada di tata letaknya.
LeffelMania
1
Sepertinya ada sesuatu yang salah dalam kode Anda (memperbarui UI dari utas latar belakang), bukan milikku.
LeffelMania
1
Terima kasih, ini berguna. Sebagai komentar yang tidak terkait: cobalah untuk tetap menggunakan konvensi penamaan Java dalam kode Anda. "V" tidak terlihat seperti nama variabel di Jawa.
altumano
3
Ini harus menjadi jawaban yang tepat. Yang diterima meninggalkan Anda NullPointerException.
Machado
132

Di dalam Fragmentkelas Anda akan mendapatkan metode override onViewCreated () di mana Anda harus selalu menginisialisasi pandangan Anda karena dalam metode ini Anda mendapatkan objek tampilan menggunakan yang dapat Anda temukan seperti:

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

Selalu ingat dalam kasus Fragmen bahwa onViewCreated()metode tidak akan dipanggil secara otomatis jika Anda mengembalikan nol atau super.onCreateView()dari onCreateView()metode. Ini akan dipanggil secara default dalam kasus ListFragmentseperti ListFragmentpengembalian FrameLayoutsecara default.

Catatan: Anda bisa mendapatkan tampilan fragmen di mana saja di kelas dengan menggunakan getView()setelah onCreateView()berhasil dieksekusi. yaitu

getView().findViewById("your view id");
Ankur Chaudhary
sumber
4
Saya terkejut tidak banyak orang yang telah meningkatkan tanggapan ini - ini adalah cara yang benar untuk mengatur pendengar pada fragmen ... Mungkin ini adalah perkembangan baru di API.
Sonny
Penggunaan viewditeruskan ke onViewCreatedmasih menyebabkan NullPointerExceptiontetapi menggunakan getActivity()tidak masalah. Ada ide mengapa?
dVaffection
@dVaffection Mungkin Anda tidak mengembalikan tampilan non null dalam metode siklus hidup onCreateView (). Sekarang dalam kasus getActivity Anda mendapatkan tampilan dari aktivitas Anda daripada tampilan utama fragmen tergantung pada id apa yang Anda lewati. Harap periksa apakah Anda mengembalikan tampilan non null dari onCreateView atau tidak? Kalau begitu beri tahu saya.
Ankur Chaudhary
@AnkurChaudhary Saya mengembalikan tampilan dari onCreateViewmetode. Saya baru saja debug dan ternyata ada tata letak (dalam kasus saya FrameLayout). Itu dikatakan ketika saya mencoba untuk menemukan elemen yang dikembalikan null. Mengapa ini terjadi?
dVaffection
@dVaffection bisa tolong bagikan kelas fragmen dan tata letak yang sesuai.
Ankur Chaudhary
66

Saya menyadari ini adalah pertanyaan lama, tetapi jawaban yang ada meninggalkan sesuatu yang diinginkan.

Pertanyaannya tidak jelas apa yang diperlukan imageView- apakah kita meneruskannya sebagai pandangan, atau hanya menyimpan referensi untuk nanti?

Either way, jika ImageViewberasal dari tata letak yang meningkat, cara yang benar untuk melakukan ini adalah:

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;
    }
}
MattJenko
sumber
1
Lalu bagaimana Anda memperbarui imageView dari ListFragment? Apakah ini membutuhkan FragmentManager? Dengan kata lain, bagaimana Anda dapat memperbarui imageView dalam fragmen detail dari onListItemClick kelas terpisah?
whyoz
1
Anda dapat menyimpan referensi ke imageView di tempat yang mudah digunakan, atau fragment.getView (). FindViewById (R.id.my_image) saat Anda membutuhkannya. Dalam ListFragment, dengan asumsi gambar ada dalam item daftar, Anda biasanya akan membuat pemegang referensi dengan metode setTag / getTag dari item tampilan daftar dalam metode getView Adaptor Anda - ada banyak contoh cara melakukan ini.
MattJenko
47

Dapatkan dulu tampilan fragmen dan kemudian dapatkan dari tampilan ini ImageView Anda.

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;
}
sungguh benar
sumber
Jadi, apakah metode onCreate berguna dalam Fragmen?
Tsunaze
onCreateView membuat dan mengembalikan hierarki tampilan yang terkait dengan fragment.onCreate dipanggil untuk melakukan pembuatan awal fragmen. Memang, itu tergantung pada apa yang Anda tulis dalam metode ini.
xevincent
Oke, tapi bagaimana saya bisa mendeklarasikan variabel di onCreate? Karena View ada di dalam metode onCreateView.
Tsunaze
@Tsunaze pernahkah Anda mengetahui cara melakukan ini dari metode onCreate?
StuStirling
1
Saya setuju. Jawaban ini harus ditandai sebagai solusinya.
Boris Karloff
25

Anda juga bisa melakukannya di onActivityCreatedMetode.

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

Seperti yang mereka lakukan di sini: http://developer.android.com/reference/android/app/Fragment.html (tidak digunakan lagi di API level 28)

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

dan

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

mungkin.

kerdil
sumber
18

getView() akan memberikan tampilan root

View v = getView().findViewByID(R.id.x); 
pengembang mimpi
sumber
17

Anda dapat mengganti onViewCreated () yang dipanggil tepat setelah semua tampilan telah meningkat. Ini adalah tempat yang tepat untuk mengisi Viewvariabel anggota Fragment Anda . Ini sebuah contoh:

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);
    }
}
Lez
sumber
17

Di dalam Fragmentkelas kita mendapatkan onViewCreated()metode override di mana kita harus selalu menginisialisasi pandangan kita karena dalam metode ini kita mendapatkan viewobjek. Menggunakan objek ini kita dapat menemukan pandangan kita seperti di bawah ini:

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);
    }
}
Vipul Prajapati
sumber
2
luar biasa bekerja dengan baik! terima kasih banyak
Vivek
15

Metode getView () tidak akan bekerja pada fragmen di luar OnCreate dan metode serupa.

Anda memiliki dua cara, meneruskan tampilan ke fungsi pada oncreate (apa artinya Anda hanya dapat menjalankan fungsi saat tampilan sedang dibuat) atau mengatur tampilan sebagai variabel:

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);
}
sagit
sumber
11

1) pertama kali mengembang layout Fragment maka Anda dapat menggunakan findviewbyId.

View view = inflater.inflate(R.layout.testclassfragment, container, false);
             ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
             return view;
priti
sumber
10
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);  
sandhu
sumber
9

Menggunakan

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

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

ini akan bekerja

Manoj ahirwar
sumber
9

setuju dengan memanggil findViewById()View.

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;
}
Piyama
sumber
9

Catatan :

Dari API Level 26, Anda juga tidak perlu secara khusus menampilkan hasil findViewById karena menggunakan inferensi untuk tipe pengembaliannya.

Jadi sekarang Anda bisa melakukannya,

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;
}
Kartik Shandilya
sumber
1
Tanpa casting hal menjelaskan membantu saya.
shaurya uppal
8

Menurut dokumentasi pada API level 11

Referensi, di Back Stack http://developer.android.com/reference/android/app/Fragment.html

Kode pendek

/**
 * 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;
}
Dexter
sumber
8

Menggunakan getView()mengembalikan tampilan fragmen, maka Anda dapat memanggil findViewById()untuk mengakses elemen tampilan apa pun di tampilan fragmen.

Mahmoud Badri
sumber
3
tampilan bukan aktivitas
Steve M
7

Coba ini bekerja untuk saya

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);
    }
}
Bipin Bharti
sumber
Ya, kode ini di sini tidak apa-apa. Hasil edit Anda untuk yang lain tidak.
OneCricketeer
@ cricket_007 ok mana yang bisa Anda lihat saya?
Bipin Bharti
Maaf saya tidak mengerti bahasa Inggris Anda, tetapi semuanya sudah diperbaiki sekarang. Saya tidak punya apa-apa untuk ditunjukkan kepada Anda.
OneCricketeer
5

Cara terbaik untuk mengimplementasikan ini adalah sebagai berikut:

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
}

Dengan cara ini, rootView dapat digunakan untuk setiap kontrol yang ditentukan dalam tata letak xml dan kode jauh lebih bersih dengan cara ini.

Semoga ini membantu :)

Michele La Ferla
sumber
Saya pikir ini bisa menjadi mungkin, tapi, itu tidak berhasil
Mike Brian Olivera
5

1) Nyatakan file tata letak Anda.

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

2) Lalu, dapatkan id dari pandangan Anda

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

Gunakan plugin gradle skeleton , itu akan secara otomatis menghasilkan kelas pemegang pandangan dengan referensi tata letak Anda.

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

Sekarang dengan asumsi Anda telah ImageViewmendeklarasikan dalam my_layout.xmlfile Anda , itu akan secara otomatis menghasilkan kelas myLayout untuk Anda.

Ilya Gazman
sumber
4

Coba ini:

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

return v;
AbhayBohra
sumber
4

mencoba

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;
}
Ramkumar.M
sumber
Tidak ada alasan untuk bidang ini. Anda selalu dapat menelepon getView()nanti
OneCricketeer
3

Anda dapat menelepon findViewById()dengan Objek Aktivitas yang Anda dapatkan di dalampublic void onAttach(Activity activity) metode Anda di dalam Fragmen Anda.

Simpan Aktivitas ke dalam variabel misalnya:

Di kelas Fragmen : private Activity mainActivity; Dalam onAttach()metode: this.mainActivity=activity;

Terakhir, jalankan setiap findViewById melalui vairable: mainActivity.findViewById(R.id.TextView);

Tuan Kejutan
sumber
3

Ada satu metode lagi yang disebut onViewCreated.

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

Di dalam metode onCreateView

1) pertama Anda harus mengembang tata letak / tampilan yang ingin Anda tambahkan misalnya. LinearLayout

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

2) Kemudian Anda dapat menemukan id imageView Anda dari tata letak

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

3) mengembalikan tata letak yang meningkat

return ll;
Devendra Kulkarni
sumber
Ini identik dengan jawaban LeffelMania.
Reti43
2

Anda harus mengembang tampilan

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
}}
Surajit Mondal
sumber
2

Dalam fragmen, kita memerlukan tampilan jendela itu sehingga kita membuat onCreateView dari fragmen ini.

Kemudian dapatkan tampilan dan gunakan untuk mengakses setiap id tampilan dari elemen tampilan tersebut.

  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;
        }
    }
Mayank Garg
sumber
1) Apa yang ini tambahkan ke jawaban lain? 2) Anda sepertinya telah menjawab dua kali
OneCricketeer
2

Layout inflater ditampilkan di sini. Layout inflater adalah kelas yang membuat kita dapat menggunakan tampilan XML dalam kode java. Jadi Anda bisa mengembang tampilan root xml dalam variabel v dengan kode berikut. Dan kemudian menggunakan v, Anda dapat menemukan tampilan anak dari tampilan root 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;
    }
}
Wijay Sharma
sumber
1

Cara termudah untuk menggunakan hal-hal seperti itu adalah dengan menggunakan butterknife. Dengan ini Anda dapat menambahkan sebanyak mungkin Onclciklisteners hanya dengan @OnClick () seperti yang dijelaskan di bawah ini:

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;
    }
}
Amit
sumber
Mengapa tidak memilih, jika Anda menggunakan ini, Anda dapat menggunakan beberapa onclick juga pada pernyataan.
Amit