我已经阅读了与此问题相关的所有其他主题,似乎没有人帮我解决问题。
我正在asynctask中执行一些后台任务,需要持续进行方向更改(configChanges)。我已经通过使用片段和setRetainInstance(true)得到了数据,我相信,但我的按钮(我假设任何视图真的)在方向更改时重新创建片段时被设置为null。当我在方向发生变化(重新创建片段)后尝试操作按钮引用时,这会导致空指针错误。
我试过包装按钮并调用语句中的按钮来检查包是否为空。这会停止崩溃,但不允许在重新创建片段时再次使用该按钮。
以下类扩展了Fragment。
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setRetainInstance(true);
currentActivity = super.getActivity();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onActivityCreated(Bundle)");
super.onActivityCreated(savedInstanceState);
simpleForecastIntent = new Intent(currentActivity, SimpleForecastActivity.class);
Button fetchDataButton = (Button) currentActivity.findViewById(R.id.fetchDataButton);
if (savedInstanceState == null) {
fetchDataButton.setOnClickListener(fetchDataButtonListener);
fetchDataButton.setTransformationMethod(null);
}
locationManager = (LocationManager)
currentActivity.getSystemService(Context.LOCATION_SERVICE);
if (isTaskRunning) {
progressDialog = ProgressDialog.show(currentActivity, "Fetching data", "Please wait...");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreateView(LayoutInflater, ViewGroup, Bundle)");
return inflater.inflate(R.layout.main_menu, container, false);
}
main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activities.MainActivity">
<include layout="@layout/toolbar" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/fetchDataButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/locationField"
android:text="@string/fetch_weather_data"
android:layout_centerHorizontal="true" />
<EditText
android:id="@+id/locationField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/enter_location"
android:layout_alignEnd="@+id/fetchDataButton"
android:layout_alignLeft="@+id/fetchDataButton"
android:layout_alignRight="@+id/fetchDataButton"
android:layout_alignStart="@+id/fetchDataButton"
android:inputType="textPostalAddress" />
<ListView
android:id="@+id/previousLocationsList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/fetchDataButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</LinearLayout>
我花了太多时间在一些如此微不足道的事情上,确实需要朝着正确的方向前进。如何在重新创建片段时让按钮不为空?
编辑已解决: 我正在使用处理活动的上下文来查找按钮的视图。而不是新活动视图上下文。
@Override
public void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setRetainInstance(true);
currentActivity = super.getActivity();
}
答案 0 :(得分:1)
问题是您在onActivityCreated
而不是onCreateView
中引用了按钮。在方向更改时,视图会被拆除然后重新创建。您应该覆盖onCreateView
并从那里维护对按钮的引用。
更新:
我看到你的代码是如何工作的,但在我看来,它遵循一个糟糕的设计模式。您仍然在onActivityCreated中实例化您的视图引用,而不是在onCreateView中膨胀之后立即实例化。
我会把它切换成这样的东西:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreateView(LayoutInflater, ViewGroup, Bundle)");
View root = inflater.inflate(R.layout.main_menu, container, false);
Button fetchDataButton = (Button) root.findViewById(R.id.fetchDataButton);
...
return root;
}