ChatGPT解决这个技术问题 Extra ChatGPT

在片段中使用上下文

如何在片段中获取上下文?

我需要使用我的数据库,其构造函数接受上下文,但 getApplicationContext()FragmentClass.this 不起作用,我该怎么办?

数据库构造函数

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

A
AskNilesh

您可以使用 getActivity(),它返回与 fragment 关联的活动。
活动是 context(因为 Activity 扩展了 Context


如果在相应片段的 onAttach 之前调用 getActivity() ,则它可以返回 null。
我正在阅读有关内存泄漏的 Google 博客...android-developers.blogspot.com/2009/01/…。如果我使用 getActivity() 方法,应用程序不会有内存泄漏的风险吗?该博客建议“尝试使用上下文应用程序而不是上下文活动”,这实际上是不可能的,因为 getApplicationContext() 仅适用于 Activity 类而不适用于 Fragment 类。
分离片段问题的解决方案是在创建片段时将 getActivity().getApplicationContext() 的值存储在实例变量中,然后在片段类中随时使用该上下文。该上下文将在片段分离中幸存下来。
不要传递应用程序上下文,而是在 Application 类中创建一个静态上下文并在 onCreate() 上对其进行初始化: MyApplication.sContext = getApplicationContext();然后您可以从任何活动/片段访问它,而不必担心分离。
@milaniez:getActivity 一直可用。它是在 API 23 中添加的 getContext
M
Mateus Gondim

按照上面的答案,您可以覆盖片段的 onAttach 方法:

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

我建议这样做,因为如果尚未调用 onAttach,getActivity() 将返回 null。
但是,请记住,调用 onAttach() 时,没有视图。所以你还不能对视图做任何事情!
@iambox 如果 DatabaseHelper 需要 FragmentActivity 而不是 Activity 怎么办?例如,对于 Adapter...
如果您在 onAttach(Activity activity) 中存储对您的活动的引用,那么您应该在 onDetach() 中释放它
onAttach 方法已被弃用,Overrides deprecated method in 'android.support.v4.app.Fragment'
s
sfmirtalebi

获取我发现的片段上下文的最简单和最精确的方法是在调用 onCreateView 方法时直接从 ViewGroup 获取它,至少在这里你肯定不会为 getActivity() 获得 null:

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

那是容器的上下文,我认为......不是“这个上下文”。
@AG1 你能解释一下为什么它会导致你的代码崩溃吗?这是迄今为止我得到的最好的解决方案
实际上,在 dialogFragments 上,容器可以为空。小心点!
此解决方案应在 onViewCreated 中使用,而不是在 onCreateView 中。
P
Peter Mortensen

始终使用 getActivity() 方法来获取附加活动的上下文,但始终记住一件事:Fragment 有点不稳定,并且 getActivity 有时会返回 null,因此,请务必在获取之前检查 Fragment 的 isAdded() 方法getActivity() 的上下文。


我不会说片段“有点不稳定”,当片段不属于活动时 getActivity() 返回 null 似乎很正常。假设 getActivity() “不应该返回 null”(这是错误的)会使您的应用程序(而不是 Fragment 类)不稳定。
@personne3000 我想听更多。片段何时不属于 Activity?这是什么时候发生的,为什么?我们是否应该检查片段中的 isAdded() 以使用 getActivity()?有什么经验法则吗?
@Sotti 我鼓励您为此创建一个新问题(或查找现有问题),因为这个特定主题与原始问题略有不同。您可以查看 developer.android.com/guide/components/fragments.html#Lifecycle 了解一般信息。基本上,在 onAttach 之前和 onDetach 之后,没有任何活动。而在onAttach 和onActivityCreated 之间,活动的onCreate 还没有被调用。使用 getActivity() 时,请确保您的活动已经创建,并考虑如果它被销毁或您的片段被分离会发生什么。
A
AskNilesh

以前我使用 onAttach (Activity activity)Fragment 中获取 context

问题

onAttach (Activity activity) 方法在 API 级别 23 中已弃用。

解决方案

现在要在 Fragment 中获取上下文,我们可以使用 onAttach (Context context)

onAttach(上下文上下文)

当片段第一次附加到其上下文时调用。 onCreate(Bundle) 将在此之后被调用。

文档

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

示例代码

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

}

笔记

我们还可以使用 getActivity()Fragments 中获取 context,但如果您的 fragment 当前未附加到父 activitygetActivity() 可以返回 null


是的,它很好的解决方案,但需要测试各种情况。
A
All Іѕ Vаиітy

正确的方法是使用

requireContext()

和例子

ContextCompat.getColor(requireContext(), R.color.colorAccent),

上下文!= ApplicationContext
requireContext() 可能引发异常时,它如何被认为是正确的?我认为这是一种有害的使用方式。
t
taran mahal
@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    context=activity;
}

J
JoséAntonio Campillo

requireContext() 方法是最简单的选择

requireContext()

例子

MyDatabase(requireContext())

l
luizfls

覆盖 onCreateView 时,您还可以从 inflater 参数获取上下文。

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

P
Peter Mortensen

另一种替代方法是:

您可以使用以下方法获取上下文:

getActivity().getApplicationContext();

J
Jorgesys

可以使用 getActivity() 获取片段内的上下文:

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

注意,使用 getActivity() 来获取与 Fragment 关联的 Activity,可以使用,但不建议使用它会导致内存泄漏。

我认为更好的方法必须是从 onAttach() 方法中获取 Activity

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

您不应该在片段中使用 getActivity 来获取视图,除非该视图是活动的一部分。为什么要在片段中膨胀视图然后甚至不引用其中的任何内容?
这个答案是关于一些不同的事情,您正在谈论在哪个视图层次结构中搜索视图。Activity.findViewById 只是在该活动的注册内容视图(通过 setContentView 设置)中搜索视图的便捷方法。在您的正确示例中,您调用的是 View.findViewById,而不是 Activity.findViewById,并且您正在调用 正确 根视图上的方法。完全不同的问题,显然您将无法在不持有该视图的视图层次结构中找到您的视图。
P
Peter Mortensen

getContext() 出现在 API 23 中。在代码中的所有位置将其替换为 getActivity()。

看看它是否修复了错误。尝试使用介于目标和最低 API 级别之间的方法,否则会出现此错误。


A
Androbin

由于 API 级别 23 有 getContext(),但如果您想支持旧版本,您可以使用 getActivity().getApplicationContext(),而我仍然建议使用 Fragment 的支持版本,即 android.support.v4.app.Fragment


K
Kishan Solanki

对于 Kotlin,您可以直接在片段中使用 context。但在某些情况下,您会发现类似的错误

类型不匹配:推断类型是上下文?但上下文是预期的

为此,您可以这样做

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

感谢您使用 Kotlin 版本,该版本运行良好,但是我正在尝试使用它获取 Picasso.get() 的上下文,但它从来没有工作过,我已经尽我所能从上面的示例中获取上下文。充其量我会收到此消息-传递了太多参数...请帮助。 val ctx = context ?: return Picasso.get(ctx) .load(selectedGallery.imageUrl) .placeholder(R.mipmap.ic_launcher) .into(galleryImage)
@Ade 在您的片段中,尝试使用“活动!!”而不是“ctx”,让我知道它是否有帮助
@KishanSolanki124。非常感谢您的快速回复。我尝试了您的建议,结果相同 - 仍然无法正常工作。确切的错误提示是 - Too many arguments for public open fun get(): Picasso!。这条消息让我想,也许还有别的错误?不过很高兴,找到了一种方法来继续我的工作,即使用毕加索而无需获取上下文。再次感谢。
A
Abduhafiz

kotlin 中只需使用 activity 而不是 getActivity()


q
qazimusab

getActivity() 是 Context 的子级,因此应该适合您


l
lomza

使用支持库中的片段 -

android.support.v4.app.Fragment

然后覆盖

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

通过这种方式,您可以确保上下文始终为非空值。


R
Rahul

你有不同的选择:

如果您的 minSDK <= 21,那么您可以使用 getActivity(),因为这是一个 Context。

如果您的 minSDK >=23,那么您可以使用 getContext()。

如果您不需要支持旧版本,请使用 getContext()


M
Mostafa Onaizan

在片段中获取上下文的安全方法

if(isAdded){
requireActivit();//this is your context
}

R
Ramesh R

您可以使用 getActivity() 方法获取上下文,也可以使用 getContext() 方法。

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

我希望它有帮助!


还有其他答案提供了 OP 的问题,它们是前一段时间发布的。发布答案 see: How do I write a good answer? 时,请确保添加新的解决方案或更好的解释,尤其是在回答较旧的问题时。
r
rink.attendant.6

理想情况下,您不需要使用全局变量。该片段有不同的通知,其中之一是 onActivityCreated。您可以在片段的这个生命周期事件中获取活动的实例。

然后:您可以根据需要取消引用片段以获取活动、上下文或应用程序上下文:

this.getActivity() 将为您提供活动的句柄 this.getContext() 将为您提供上下文的句柄 this.getActivity().getApplicationContext() 将为您提供应用程序上下文的句柄。在将应用程序上下文传递给数据库时,您最好使用它。


P
Peter Mortensen

简单的方法是使用 getActivity()。但我认为在这里使用 getActivity() 方法获取上下文的主要混淆是空指针异常。

为此,首先检查 isAdded() 方法,该方法将确定是否添加,然后我们可以使用 getActivity() 获取 Activity 的上下文。


这与 Ankur Chaudhary's answer 有何不同?
S
Satan Pandeya

您可以致电 getActivity(),或者,

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

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

p
perror

我认为你可以使用

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

      Context context = getActivity.getContext();

  }
}

U
Umair

我需要使用 arrayAdapter IN 片段的上下文,当我使用 getActivity 时发生错误但是当我用 getContext 替换它时它对我有用

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

K
Kinggeov

在你片段上

((Name_of_your_Activity) getActivity()).helper

活动时

DbHelper helper = new DbHelper(this);

S
Shihab Uddin

kotlin 样本的内部片段会帮助某人

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

如果您使用数据绑定;

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

像这样在 onCreateView 中初始化 bindingView

private lateinit var bindingView: FragmentBookingHistoryDetailBinding

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

E
Ehsan Pagheh

您可以使用 getActivity(),它返回与片段关联的活动。活动是一个上下文(因为活动扩展了上下文)。

注意:如果在相应片段的 onAttach 之前调用 getActivity(),它可能会返回 null。

2.或

获取我发现的片段上下文的最简单和最精确的方法是在调用 onCreateView 方法时直接从 ViewGroup 中获取它,至少在这里你肯定不会为 getActivity() 获取 null:

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

S
S. B.

在 Kotlin 中,您可以使用:requireActivity().applicationContext