在片段中使用上下文
Posted
技术标签:
【中文标题】在片段中使用上下文【英文标题】:Using context in a fragment 【发布时间】:2012-01-03 03:47:59 【问题描述】:如何获取片段中的上下文?
我需要使用我的数据库,其构造函数接受上下文,但getApplicationContext()
和FragmentClass.this
不起作用,我该怎么办?
数据库构造函数
public Database(Context ctx)
this.context = ctx;
DBHelper = new DatabaseHelper(context);
【问题讨论】:
【参考方案1】:您可以使用getActivity()
,它返回与fragment
关联的活动。
该活动是context
(因为Activity
扩展了Context
)。
【讨论】:
getActivity() 如果在相应片段的 onAttach 之前调用,则可以返回 null。 我正在阅读有关内存泄漏的 Google 博客...android-developers.blogspot.com/2009/01/…。如果我使用 getActivity() 方法,应用程序不会有内存泄漏的风险吗?该博客建议“尝试使用上下文应用程序而不是上下文活动”,这实际上是不可能的,因为 getApplicationContext() 仅适用于 Activity 类而不适用于 Fragment 类。 解决片段分离问题的解决方案是在片段创建时将getActivity().getApplicationContext()
的值存储在实例变量中,然后在片段类中随时使用该上下文。该上下文将在片段分离中幸存下来。
不要传递应用程序上下文,而是在 Application 类中创建一个静态上下文并在 onCreate() 上对其进行初始化: MyApplication.sContext = getApplicationContext();那么您可以从任何活动/片段中访问它,而不必担心分离。
@milaniez:getActivity
一直可用。它是在 API 23 中添加的 getContext
。【参考方案2】:
按照上面的答案,你可以重写片段的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'
【参考方案3】:
获取我发现的片段上下文的最简单和最精确的方法是直接从ViewGroup
获取它,当您调用onCreateView
方法时,至少在这里您肯定不会为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。【参考方案4】:始终使用getActivity() 方法来获取附加活动的上下文,但始终记住一件事:Fragment 有点不稳定,getActivity
有时会返回 null,因此,请始终检查 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() 时,请确保您的 Activity 已经创建,并考虑如果它被销毁或您的 Fragment 被分离会发生什么。【参考方案5】:以前我使用onAttach (Activity activity)
在Fragment
中获取context
问题
onAttach (Activity activity)
方法在 API 级别 23 中已弃用。
解决方案
现在要在Fragment
中获取上下文,我们可以使用onAttach (Context context)
在片段首次附加到其
onAttach (Context context)
context
时调用。 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
但是getActivity()
可以返回null
如果您的fragment
当前未附加到父activity
,
【讨论】:
是的,它的解决方案很好,但需要测试各种情况。【参考方案6】:@Override
public void onAttach(Activity activity)
// TODO Auto-generated method stub
super.onAttach(activity);
context=activity;
【讨论】:
【参考方案7】:requireContext() 方法是最简单的选择
requireContext()
例子
MyDatabase(requireContext())
【讨论】:
【参考方案8】:当覆盖onCreateView
时,您还可以从inflater
参数中获取上下文。
public static class MyFragment extends Fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
/* ... */
Context context = inflater.getContext();
/* ... */
【讨论】:
【参考方案9】:正确的方法是使用
requireContext()
例子
ContextCompat.getColor(requireContext(), R.color.colorAccent),
原始答案(见答案修订版)
【讨论】:
上下文 != ApplicationContext【参考方案10】:另一种替代方法是:
您可以使用以下方法获取上下文:
getActivity().getApplicationContext();
【讨论】:
【参考方案11】:可以使用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
,并且您在正确 根视图上调用该方法。完全不同的问题,显然您将无法在不包含该视图的视图层次结构中找到您的视图。【参考方案12】:
getContext()
出现在 API 23 中。将其替换为代码中的任何地方的 getActivity()。
看看它是否修复了错误。尝试使用介于目标和最低 API 级别之间的方法,否则会出现此错误。
【讨论】:
【参考方案13】:由于 API 级别 23,有 getContext()
,但如果您想支持旧版本,您可以使用 getActivity().getApplicationContext()
,而我仍然建议使用 Fragment
的支持版本,即 android.support.v4.app.Fragment
。
【讨论】:
【参考方案14】:对于 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!。这条消息让我想,也许还有别的错误?不过很高兴,找到了一种方法来继续我的工作,即使用毕加索而无需获取上下文。再次感谢。【参考方案15】:getActivity()
是 Context 的子级,因此应该适合您
【讨论】:
【参考方案16】:使用支持库中的片段 -
android.support.v4.app.Fragment
然后覆盖
void onAttach (Context context)
this.context = context;
这样可以确保上下文始终是非空值。
【讨论】:
【参考方案17】:你有不同的选择:
如果您的 minSDK getActivity(),因为这是Context
。
如果您的 minSDK >=23,那么您可以使用getContext()
。
如果您不需要支持旧版本,请使用getContext()
。
【讨论】:
【参考方案18】:在 kotlin 中只需使用 activity
而不是 getActivity()
【讨论】:
【参考方案19】:您可以使用 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? 时,请确保添加新的解决方案或更好的解释,尤其是在回答较老的问题时。【参考方案20】:在片段中获取上下文的安全方法
if(isAdded)
requireActivit();//this is your context
【讨论】:
【参考方案21】:理想情况下,您不需要使用全局变量。该片段有不同的通知,其中之一是 onActivityCreated。可以在fragment的这个生命周期事件中获取activity的实例。
然后:您可以根据需要取消引用片段以获取活动、上下文或应用程序上下文:
this.getActivity()
将为您提供活动的句柄
this.getContext()
将为您提供上下文句柄
this.getActivity().getApplicationContext()
将为您提供应用程序上下文的句柄。您最好在将应用程序上下文传递给数据库时使用它。
【讨论】:
【参考方案22】:简单的方法是使用getActivity()
。但我认为在这里使用getActivity()
方法获取上下文的主要混淆是空指针异常。
为此,首先使用isAdded()
方法判断是否添加,然后我们可以使用getActivity()
获取Activity的上下文。
【讨论】:
这与Ankur Chaudhary's answer有何不同?【参考方案23】:您可以拨打getActivity()
或者,
public void onAttach(Context context)
super.onAttach(context);
this.activity = (CashActivity) context;
this.money = this.activity.money;
【讨论】:
【参考方案24】:我认为你可以使用
public static class MyFragment extends Fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
Context context = getActivity.getContext();
【讨论】:
【参考方案25】: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;
【讨论】:
【参考方案26】:我需要使用 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));
【讨论】:
【参考方案27】:你的片段
((Name_of_your_Activity) getActivity()).helper
在活动中
DbHelper helper = new DbHelper(this);
【讨论】:
【参考方案28】: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)
【讨论】:
以上是关于在片段中使用上下文的主要内容,如果未能解决你的问题,请参考以下文章