如何在片段中获取上下文?
我需要使用我的数据库,其构造函数接受上下文,但 getApplicationContext()
和 FragmentClass.this
不起作用,我该怎么办?
数据库构造函数
public Database(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
按照上面的答案,您可以覆盖片段的 onAttach
方法:
public static class DummySectionFragment extends Fragment{
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
DBHelper = new DatabaseHelper(activity);
}
}
DatabaseHelper
需要 FragmentActivity
而不是 Activity
怎么办?例如,对于 Adapter
...
onAttach(Activity activity)
中存储对您的活动的引用,那么您应该在 onDetach()
中释放它
onAttach
方法已被弃用,Overrides deprecated method in 'android.support.v4.app.Fragment'
获取我发现的片段上下文的最简单和最精确的方法是在调用 onCreateView
方法时直接从 ViewGroup
获取它,至少在这里你肯定不会为 getActivity()
获得 null:
public class Animal extends Fragment {
Context thiscontext;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
thiscontext = container.getContext();
始终使用 getActivity() 方法来获取附加活动的上下文,但始终记住一件事:Fragment 有点不稳定,并且 getActivity
有时会返回 null,因此,请务必在获取之前检查 Fragment 的 isAdded() 方法getActivity()
的上下文。
以前我使用 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
当前未附加到父 activity
,getActivity()
可以返回 null
,
正确的方法是使用
requireContext()
和例子
ContextCompat.getColor(requireContext(), R.color.colorAccent),
requireContext()
可能引发异常时,它如何被认为是正确的?我认为这是一种有害的使用方式。
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
context=activity;
}
requireContext() 方法是最简单的选择
requireContext()
例子
MyDatabase(requireContext())
覆盖 onCreateView
时,您还可以从 inflater
参数获取上下文。
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/* ... */
Context context = inflater.getContext();
/* ... */
}
}
另一种替代方法是:
您可以使用以下方法获取上下文:
getActivity().getApplicationContext();
可以使用 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;
}
Activity.findViewById
只是在该活动的注册内容视图(通过 setContentView
设置)中搜索视图的便捷方法。在您的正确示例中,您调用的是 View.findViewById
,而不是 Activity.findViewById
,并且您正在调用 正确 根视图上的方法。完全不同的问题,显然您将无法在不持有该视图的视图层次结构中找到您的视图。
getContext()
出现在 API 23 中。在代码中的所有位置将其替换为 getActivity()。
看看它是否修复了错误。尝试使用介于目标和最低 API 级别之间的方法,否则会出现此错误。
由于 API 级别 23 有 getContext()
,但如果您想支持旧版本,您可以使用 getActivity().getApplicationContext()
,而我仍然建议使用 Fragment
的支持版本,即 android.support.v4.app.Fragment
。
对于 Kotlin,您可以直接在片段中使用 context
。但在某些情况下,您会发现类似的错误
类型不匹配:推断类型是上下文?但上下文是预期的
为此,您可以这样做
val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
在 kotlin 中只需使用 activity
而不是 getActivity()
getActivity()
是 Context 的子级,因此应该适合您
使用支持库中的片段 -
android.support.v4.app.Fragment
然后覆盖
void onAttach (Context context) {
this.context = context;
}
通过这种方式,您可以确保上下文始终为非空值。
你有不同的选择:
如果您的 minSDK <= 21,那么您可以使用 getActivity(),因为这是一个 Context。
如果您的 minSDK >=23,那么您可以使用 getContext()。
如果您不需要支持旧版本,请使用 getContext()
。
在片段中获取上下文的安全方法
if(isAdded){
requireActivit();//this is your context
}
您可以使用 getActivity() 方法获取上下文,也可以使用 getContext() 方法。
View root = inflater.inflate(R.layout.fragment_slideshow, container, false);
Context c = root.getContext();
我希望它有帮助!
理想情况下,您不需要使用全局变量。该片段有不同的通知,其中之一是 onActivityCreated。您可以在片段的这个生命周期事件中获取活动的实例。
然后:您可以根据需要取消引用片段以获取活动、上下文或应用程序上下文:
this.getActivity()
将为您提供活动的句柄 this.getContext()
将为您提供上下文的句柄 this.getActivity().getApplicationContext()
将为您提供应用程序上下文的句柄。在将应用程序上下文传递给数据库时,您最好使用它。
简单的方法是使用 getActivity()
。但我认为在这里使用 getActivity()
方法获取上下文的主要混淆是空指针异常。
为此,首先检查 isAdded()
方法,该方法将确定是否添加,然后我们可以使用 getActivity()
获取 Activity 的上下文。
您可以致电 getActivity()
,或者,
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (CashActivity) context;
this.money = this.activity.money;
}
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;
}
}
我认为你可以使用
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Context context = getActivity.getContext();
}
}
我需要使用 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));
在你片段上
((Name_of_your_Activity) getActivity()).helper
活动时
DbHelper helper = new DbHelper(this);
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)
您可以使用 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();
//...
//...
//...
}
在 Kotlin 中,您可以使用:requireActivity().applicationContext
getActivity().getApplicationContext()
的值存储在实例变量中,然后在片段类中随时使用该上下文。该上下文将在片段分离中幸存下来。getActivity
一直可用。它是在 API 23 中添加的getContext
。