如何在方向变化时保留片段中的图像
how to retain images in fragments on orientation changes
我有一个片段,其中有图像按钮 "product image",我正在使用图库意图将图像加载到该图像按钮中,并使用 Glide 库加载该图像,以保留我正在使用的图像使用 onSavedInstanceState() 但问题是当我将方向更改为横向时它会保留图像,但是当我再次切换回纵向模式时它不会保留图像并给我一个空指针异常,如果有一些技术我做错了什么请指导,因为我是 android 开发的新手。
这是我的碎片代码。
public class NoteEditFragment extends Fragment {
ImageButton productImage;
private static final int REQUEST_OPEN_RESULT_CODE = 0;
private Uri mImageUri;
EditText productName;
EditText productPrice;
EditText productDescription;
AlertDialog confirmDialogObject;
Uri myuri;
public NoteEditFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View FragmentLayout = inflater.inflate(R.layout.fragment_note_edit, container, false);
productImage = (ImageButton) FragmentLayout.findViewById(R.id.editNoteButton);
if(savedInstanceState != null){
myuri = Uri.parse(savedInstanceState.getString("imageuri"));
Glide.with(this)
.load(myuri)
.into(productImage);
}
productName = (EditText) FragmentLayout.findViewById(R.id.EditNoteTitle);
Intent intent = getActivity().getIntent();
});
productImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent1 = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent1.addCategory(Intent.CATEGORY_OPENABLE);
intent1.setType("image/*");
startActivityForResult(intent1, REQUEST_OPEN_RESULT_CODE);
}
});
return FragmentLayout;
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(mImageUri != null){
outState.putString("imageuri",mImageUri.toString());}
super.onSaveInstanceState(outState);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if(requestCode == REQUEST_OPEN_RESULT_CODE && resultCode == Activity.RESULT_OK ) {
if(resultData != null) {
mImageUri = resultData.getData();
Glide.with(this)
.load(mImageUri)
.into(productImage);
}
}
}
这是我得到的错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ibrahim_01.notebookapp, PID: 4102
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ibrahim_01.notebookapp/com.example.ibrahim_01.notebookapp.NoteDetailActivity}: java.lang.NullPointerException: uriString
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.<init>(Uri.java:475)
at android.net.Uri$StringUri.<init>(Uri.java)
at android.net.Uri.parse(Uri.java:437)
at com.example.ibrahim_01.notebookapp.NoteEditFragment$override.onCreateView(NoteEditFragment.java:66)
at com.example.ibrahim_01.notebookapp.NoteEditFragment$override.access$dispatch(NoteEditFragment.java)
at com.example.ibrahim_01.notebookapp.NoteEditFragment.onCreateView(NoteEditFragment.java:0)
at android.app.Fragment.performCreateView(Fragment.java:2220)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1130)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1953)
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:152)
at android.app.Activity.performCreateCommon(Activity.java:6232)
at android.app.Activity.performCreate(Activity.java:6239)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
覆盖方法 onCreate 并像这样添加 setRetainInstance(true):
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
第一次旋转时,字段 (imageUri) 已设置。 onSaveInstanceState()
将在捆绑包中循环保留此字段。
现在在横向模式下,您将从 onCreate()
中的包中读取并获取您存储的值。但请注意,imageUri
将为空,因为您将其存储到 myUri
。
当您第二次旋转时,onSaveInstanceState()
将不会保留 imageUri
,因为它为空。但是现在在肖像中,它会尝试读取它(包不为空),return null(因为键 "imageuri" 没有值)并且你在 Uri.parse.
您可以通过删除字段 myUri
并将 onCreate()
中的包中的值分配给 imageUri
来解决。我想 - 我正在 phone!
上阅读这篇文章
我有一个片段,其中有图像按钮 "product image",我正在使用图库意图将图像加载到该图像按钮中,并使用 Glide 库加载该图像,以保留我正在使用的图像使用 onSavedInstanceState() 但问题是当我将方向更改为横向时它会保留图像,但是当我再次切换回纵向模式时它不会保留图像并给我一个空指针异常,如果有一些技术我做错了什么请指导,因为我是 android 开发的新手。 这是我的碎片代码。
public class NoteEditFragment extends Fragment {
ImageButton productImage;
private static final int REQUEST_OPEN_RESULT_CODE = 0;
private Uri mImageUri;
EditText productName;
EditText productPrice;
EditText productDescription;
AlertDialog confirmDialogObject;
Uri myuri;
public NoteEditFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View FragmentLayout = inflater.inflate(R.layout.fragment_note_edit, container, false);
productImage = (ImageButton) FragmentLayout.findViewById(R.id.editNoteButton);
if(savedInstanceState != null){
myuri = Uri.parse(savedInstanceState.getString("imageuri"));
Glide.with(this)
.load(myuri)
.into(productImage);
}
productName = (EditText) FragmentLayout.findViewById(R.id.EditNoteTitle);
Intent intent = getActivity().getIntent();
});
productImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent1 = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent1.addCategory(Intent.CATEGORY_OPENABLE);
intent1.setType("image/*");
startActivityForResult(intent1, REQUEST_OPEN_RESULT_CODE);
}
});
return FragmentLayout;
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(mImageUri != null){
outState.putString("imageuri",mImageUri.toString());}
super.onSaveInstanceState(outState);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if(requestCode == REQUEST_OPEN_RESULT_CODE && resultCode == Activity.RESULT_OK ) {
if(resultData != null) {
mImageUri = resultData.getData();
Glide.with(this)
.load(mImageUri)
.into(productImage);
}
}
}
这是我得到的错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ibrahim_01.notebookapp, PID: 4102
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ibrahim_01.notebookapp/com.example.ibrahim_01.notebookapp.NoteDetailActivity}: java.lang.NullPointerException: uriString
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.<init>(Uri.java:475)
at android.net.Uri$StringUri.<init>(Uri.java)
at android.net.Uri.parse(Uri.java:437)
at com.example.ibrahim_01.notebookapp.NoteEditFragment$override.onCreateView(NoteEditFragment.java:66)
at com.example.ibrahim_01.notebookapp.NoteEditFragment$override.access$dispatch(NoteEditFragment.java)
at com.example.ibrahim_01.notebookapp.NoteEditFragment.onCreateView(NoteEditFragment.java:0)
at android.app.Fragment.performCreateView(Fragment.java:2220)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1130)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1953)
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:152)
at android.app.Activity.performCreateCommon(Activity.java:6232)
at android.app.Activity.performCreate(Activity.java:6239)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
覆盖方法 onCreate 并像这样添加 setRetainInstance(true):
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
第一次旋转时,字段 (imageUri) 已设置。 onSaveInstanceState()
将在捆绑包中循环保留此字段。
现在在横向模式下,您将从 onCreate()
中的包中读取并获取您存储的值。但请注意,imageUri
将为空,因为您将其存储到 myUri
。
当您第二次旋转时,onSaveInstanceState()
将不会保留 imageUri
,因为它为空。但是现在在肖像中,它会尝试读取它(包不为空),return null(因为键 "imageuri" 没有值)并且你在 Uri.parse.
您可以通过删除字段 myUri
并将 onCreate()
中的包中的值分配给 imageUri
来解决。我想 - 我正在 phone!