Bir parçada bağlam kullanma


664

Bağlamı bir parçada nasıl alabilirim?

Ben yapıcı bağlamda alır, ancak benim veritabanı kullanmak gerekir, getApplicationContext()ve FragmentClass.thisbu yüzden ne yapabilirim çalışmıyor?

Veritabanı oluşturucu

public Database(Context ctx)
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

Yanıtlar:


1313

getActivity()İle ilişkili etkinliği döndüren şunu kullanabilirsiniz fragment.
Etkinlik bir context (beri Activityuzanır Context) .


212
getActivity (), daha önce ilgili parçanın eklentisi çağrılırsa null değerini döndürebilir.
arne.jans

4
Bu Google blogunu bellek sızıntıları hakkında okuyordum ... android-developers.blogspot.com/2009/01/… . GetActivity () yöntemini kullanırsam uygulama bellek sızıntısı riski altında olmaz mı? Blog, getApplicationContext () yöntemi, Fragment sınıfı için değil, yalnızca Activity sınıfı için çalıştığından mümkün olmayan "Bağlam etkinliği yerine bağlam uygulamasını kullanmayı deneyin" öneriyor.
Simon

40
Ayrılmış fragmanlar sorununun bir çözümü getActivity().getApplicationContext(), fragman oluşturulduğunda örnek değişkeninde değerini saklamak ve daha sonra fragman sınıfında istediğiniz zaman bu bağlamı kullanmaktır. Bu bağlam parça kopmalarından kurtulacaktır.
Piovezan

8
Uygulama bağlamını iletmek yerine, Uygulama sınıfınızın içinde statik bir bağlam oluşturun ve bunu onCreate () öğesine başlatın: MyApplication.sContext = getApplicationContext (); o zaman ayrılma konusunda endişelenmeden herhangi bir etkinlikten / parçadan erişebilirsiniz.
Eduko

3
@milaniez: getActivityher zaman mevcuttu. Bu var getContextAPI 23. ilave edildi
mhsmith

130

Yukarıdaki cevap olarak yapmak için onAttach, fragman yöntemini geçersiz kılabilirsiniz :

public static class DummySectionFragment extends Fragment{
...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        DBHelper = new DatabaseHelper(activity);
    }
}

3
OnAttach henüz çağrılmadıysa getActivity () null döndürdüğü için bunu tavsiye ederim.
arne.jans

9
Ancak, onAttach () çağrıldığında hiçbir görünüm olmadığını unutmayın. Böylece henüz manzaraya sahip bir şey yapamazsınız!
Zordid

2
@iambox yerine DatabaseHelperbir FragmentActivityyerine ne olacak Activity? Örneğin, bir Adapter...
Jago

4
Etkinliğinize bir referans depolarsanız, onAttach(Activity activity)o zaman bunu serbest bırakmalısınızonDetach()
vovahost

3
onAttachYöntem, kullanımdan kaldırıldıOverrides deprecated method in 'android.support.v4.app.Fragment'
Muhammed Saqib

24

Ekli etkinliğinizin bağlamını elde etmek için her zaman getActivity () yöntemini kullanın, ancak her zaman bir şeyi unutmayın: Parçalar biraz kararsızdır ve getActivitybirkaç kez null döndürür, bu nedenle içeriğe almadan önce her zaman parçanın is Added () yöntemini kontrol edin getActivity().


15
Ben parçaların "biraz kararsız" olduğunu söyleyemem, getActivity () parçasının bir etkinliğe ait olmadığında null değerini döndürmesi oldukça normal görünüyor. Uygulamanızı (ve Fragment sınıfını değil) kararsız hale getirecek getActivity () "null değerini döndürmemelidir" (bu yanlıştır).
personne3000

3
@ personne3000 Daha fazlasını duymak isterim. Bir parça ne zaman bir Faaliyete ait değildir? Bu ne zaman oluyor ve neden? GetActivity () işlevini kullanmak için parçadaki is Added () öğesini kontrol etmeli miyiz? Herhangi bir kural var mı?
Sotti

2
@Sotti Bunun için yeni bir soru oluşturmanızı (veya mevcut bir soruyu aramanızı) öneririm, çünkü bu konu orijinal sorudan biraz farklıdır. Genel bilgi için developer.android.com/guide/components/fragments.html#Lifecycle'a bakabilirsiniz . Temel olarak, onAttach ve onDetach'tan önce, etkinlik yok. Ve onAttach ve onActivityCreated arasında, etkinliğin onCreate öğesi henüz çağrılmadı. GetActivity () kullanırken, etkinliğinizin önceden oluşturulduğundan emin olun ve yok edildiğinde veya parçanız ayrıldığında ne olacağını düşünün.
personne3000

22

Bulduğum parçanın bağlamını elde etmenin en kolay ve en kesin yolu, yöntemi en azından burada ViewGroupçağırdığınızda doğrudan onCreateViewalmaktır getActivity():

public class Animal extends Fragment { 
  Context thiscontext;
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    thiscontext = container.getContext();

10
konteynerin bağlamı bu, sanırım ... "bu bağlam" değil.
Fattie

2
@ AG1, kodunuzu neden kilitlediğini açıklayabilir misiniz? Şimdiye kadar sahip olduğum en iyi çözüm
Machado

3
Aslında dialogFragment'lerinde kap null olabilir . Dikkatli ol!
Lucas Teske

Bu çözüm onCreateView değil, onViewCreated içinde kullanılmalıdır.
Andrea De Simone

13

Daha önce ben kullanıyorum onAttach (Activity activity)almak için contextdeFragment

Sorun

onAttach (Activity activity)Yöntem API seviyesi 23 kaldırıldı.

Çözüm

Şimdi içeriğe girmek FragmentiçinonAttach (Context context)

onAttach (Context context)

  • Bir parçasına ilk kez bir parça eklendiğinde çağrılır context. onCreate(Bundle)bundan sonra çağrılır.

belgeleme

/**
 * Called when a fragment is first attached to its context.
 * {@link #onCreate(Bundle)} will be called after this.
 */
@CallSuper
public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

BASİT KOD

public class FirstFragment extends Fragment {


    private Context mContext;
    public FirstFragment() {
        // Required empty public constructor
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext=context;
    }

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

        Toast.makeText(mContext, "THIS IS SAMPLE TOAST", Toast.LENGTH_SHORT).show();
        // Inflate the layout for this fragment
        return rooView;
    }

}

NOT

Biz de kullanabilirsiniz getActivity()almak için contextde Fragments ancak getActivity()dönebilirsiniz nullsenin eğer fragmenthenüz ebeveyne bağlı değil activity,


11
@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    context=activity;
}

6

inflaterGeçersiz kılma sırasında bağlamı parametreden de alabilirsiniz onCreateView.

public static class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
        /* ... */
        Context context = inflater.getContext();
        /* ... */
    }
}

5

Başka bir alternatif yaklaşım:

Bağlamı kullanarak şunları elde edebilirsiniz:

getActivity().getApplicationContext();

5

Parçanın içindeki bağlamı elde etmek aşağıdakileri kullanarak mümkün olacaktır getActivity():

public Database()
{
    this.context = getActivity();
    DBHelper = new DatabaseHelper(this.context);
}
  • Dikkatli olun, Activitykullanarak parçayı kullanarak ilişkilendirmek getActivity()için kullanabilirsiniz, ancak bellek sızıntılarına neden olması önerilmez.

Daha iyi bir yaklaşımı almak gerekir düşünüyorum Activitydan onAttach()yöntemle:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    context = activity;
}

Bu görünüm yine de etkinliğin bir parçası olmadığı sürece, bir görünüm elde etmek için getActivity'yi bir parçada kullanmamalısınız. Neden bir parçayı bir görüntüye şişirip ondan bir şeye başvurmuyorsunuz?
tyczj

Bu yanıt farklı bir şey hakkında, görüntülemeleri aramak için hangi görünüm hiearchy'sinden bahsediyorsunuz. Activity.findViewByIdBu etkinliğin kayıtlı içerik görünümünde (üzerinden ayarlanmış setContentView) bir görünüm aramak için uygun bir yöntemdir . Doğru örneğinizde View.findViewByIddeğil Activity.findViewById, çağırıyorsunuz ve yöntemi doğru kök görünümünde çağırıyorsunuz . Tamamen farklı bir sorun ve açıkçası, o görünümü içermeyen bir görünüm aramasında görünümünüzü bulamazsınız.
JHH

3

getContext() API 23'te geldi. Kodun her yerinde getActivity () ile değiştirin.

Hatayı düzeltip düzeltmediğine bakın. Hedef ve minimun API düzeyi arasında bulunan yöntemleri kullanmaya çalışın, aksi takdirde bu hata ortaya çıkacaktır.


3

API düzeyinde 23 yana orada olduğu getContext()sen kullanabilirsiniz eski sürümlerini desteklemek istiyorlarsa ama getActivity().getApplicationContext()yine de destek sürümünün kullanılmasını tavsiye ederken Fragmenthangi android.support.v4.app.Fragment.


2

getActivity() Bağlamın bir çocuğu, bu yüzden sizin için çalışmalı


2

Destek Kitaplığındaki parçaları kullanın -

android.support.v4.app.Fragment

ve sonra geçersiz kıl

void onAttach (Context context) {
  this.context = context;
}

Bu şekilde, bağlamın her zaman boş olmayan bir değer olacağından emin olabilirsiniz.


2

Farklı seçenekleriniz var:

  • Eğer minSDK <= 21 ise, getActivity()bu bir Context.
  • MinSDK'nız> = 23 ise, kullanabilirsiniz getContext().

Eski sürümleri desteklemeniz gerekmiyorsa, devam edin getContext().


2

Kotlin için contextdoğrudan parçalarda kullanabilirsiniz . Ama bazı kasada bir hata bulacaksınız

Tür uyuşmazlığı: çıkartılan tür Bağlam mı? ancak bağlam bekleniyordu

bunun için bunu yapabilirsin

val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))

İyi çalışan bir Kotlin sürümü availing için teşekkürler, ancak bununla birlikte Picasso.get () için Context almaya çalışıyorum ve asla işe yaramaz, bağlamı almak için yukarıdaki örneklerden de yapabileceğim her şeyi denedim. En iyi ihtimalle bu mesajı alıyorum -Çok fazla argüman geçti ... Lütfen yardım et. val ctx = context?: dönüş Picasso.get (ctx) .load (selectedGallery.imageUrl) .placeholder (R.mipmap.ic_launcher) .into (galleryImage)
Ade

@Ade Parçanızda, "etkinlik !!" yerine "ctx" ve bana yardımcı olup olmadığını bildirin
Kishan Solanki

@ KishanSolanki124. Hızlı yanıt için çok teşekkürler. Aynı sonucu vererek önerinizi denedim - Hala çalışmıyor. Kesin hata istemi - halka açık eğlence için çok fazla argüman olsun get (): Picasso !. Bu mesaj beni düşündürüyor, belki başka bir şey hatadır? Ancak memnuniyetle, bağlam almadan Picasso'yu kullanarak çalışmalarıma devam etmenin bir yolunu buldum. Tekrar teşekkürler.
Ade


2

Kotlin'de API 29+ ile yapmak zorundaydım

activity?.applicationContext!!

Bir örnek

ContextCompat.getColor(activity?.applicationContext!!, R.color.colorAccent),

Context! = ApplicationContext
Gabriele Mariotti

1

İdeal olarak, globalleri kullanmanıza gerek yoktur. Parçanın farklı bildirimleri var, bunlardan biri çalışıyorActivityCreated. Etkinliğin örneğini parçanın bu yaşam döngüsü olayında alabilirsiniz.

Daha sonra: etkinlik, bağlam veya applicationcontext'i istediğiniz gibi almak için parçanın seçimini kaldırabilirsiniz:

this.getActivity()size etkinlik this.getContext()için bir tanıtıcı this.getActivity().getApplicationContext()verecek bağlam size bir tanıtıcı verecek uygulama bağlamı için tanıtıcı verecektir. Uygulama bağlamını db'ye geçirirken tercihen kullanmalısınız.


1

Basit yol, getActivity() . Ama bence kullanımı büyük bir karışıklıkgetActivity() buradaki bağlamı elde etmek yöntemi boş bir işaretçi istisnası olduğunu düşünüyorum.

Bunun için önce isAdded()eklenip eklenmeyeceğini belirleyecek yönteme danışın ve daha sonra getActivity()Etkinlik bağlamını almak için.



1

Arayabilir getActivity()veya,

public void onAttach(Context context) {
    super.onAttach(context);
    this.activity = (CashActivity) context;
    this.money = this.activity.money;
}

1

Bağlam elde etmek için getActivity () yöntemini veya getContext () yöntemini kullanabilirsiniz.

 View root = inflater.inflate(R.layout.fragment_slideshow, container, false);
    Context c = root.getContext();

Umut ediyorum bu yardım eder!


1
OP'nin sorusunu sağlayan başka cevaplar da var ve bunlar bir süre önce yayınlandı. Bir cevap gönderirken bkz: İyi bir cevabı nasıl yazarım? , özellikle eski soruları yanıtlarken yeni bir çözüm eklediğinizden veya önemli ölçüde daha iyi bir açıklama eklediğinizden emin olun.
help-info.de

0

getContext () yöntemi, sınıfın bağlamını bir parça etkinliğinde kullanmaya yardımcı olur.


0

Bence kullanabilirsiniz

public static class MyFragment extends Fragment {
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

      Context context = getActivity.getContext();

  }
}

0
public class MenuFragment extends Fragment implements View.OnClickListener {
    private Context mContext;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentMenuBinding binding=FragmentMenuBinding.inflate(inflater,container,false);
        View view=binding.getRoot();
        mContext=view.getContext();
        return view;
    }
}

0

Ayrıca şunları kullanabilirsiniz:

inflater.getContext();

ama kullanmayı tercih ederim

getActivity()

veya

getContext

0

GetActivity hatası kullanırken diziAdapter IN parçası kullanmak için bağlam gerekir , ancak getContext ile değiştirdiğimde benim için çalışıyor

listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1 ,listSensorType));

0

Sen kullanabilirsiniz getActivity()veya getContextFragment.

belgeleme

/**
 * Return the {@link FragmentActivity} this fragment is currently associated with.
 * May return {@code null} if the fragment is associated with a {@link Context}
 * instead.
 *
 * @see #requireActivity()
 */
@Nullable
final public FragmentActivity getActivity() {
    return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}

ve

 /**
     * Return the {@link Context} this fragment is currently associated with.
     *
     * @see #requireContext()
     */
    @Nullable
    public Context getContext() {
        return mHost == null ? null : mHost.getContext();
    }

Profesyonel ipucu

Her zaman kontrol edin, if(getActivity!=null)çünkü fragman aktiviteye bağlı olmadığında boş olabilir . Bazen parça halinde uzun süre işlem yapmak (dinlenme api'sinden veri almak gibi) biraz zaman alır. ve kullanıcı başka bir parçaya giderse. Sonra getActivity boş olacaktır. Ve eğer başa çıkmazsanız NPE alacaksınız.


Bu getActivity () yönteminin sadece boş olabileceğini göstermek için kullanılan bir belgedir. Burada mHost FragmentHostCallbacksınıf örneğidir .
Khemraj

0

Parçanın üzerinde

((Name_of_your_Activity) getActivity()).helper

Faaliyette

DbHelper helper = new DbHelper(this);

0

Kotlin örneği için iç parça birine yardımcı olur

textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

veri bağlama kullanıyorsanız;

bindingView.textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

BağlamaGörüntüsü onCreateView'da böyle başlatıldığında

private lateinit var bindingView: FragmentBookingHistoryDetailBinding

bindingView = DataBindingUtil.inflate(inflater, R.layout.your_layout_xml, container, false)

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.