2

我正在尝试制作一个应用程序,我可以让用户选择一张图片以显示在他们的个人资料上。我可以在 imageview 上浏览和设置他们选择的图像。但是一旦活动被破坏,图像就会丢失。我试图实现 onSaveInstanceState 但它仍然是一样的。我想知道我是否正确使用它。我希望你能帮助像我这样的新手。提前致谢。这是我正在使用的代码:

public class AccountFragment extends Fragment implements OnClickListener {
private LoginDataBaseAdapter loginDataBaseAdapter;
Bitmap image;
Bitmap bitmap;
String picture_location;
TextView textTargetUri;
ImageView targetImage;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {


        View rootView = inflater.inflate(R.layout.fragment_account, container, false);


            textTargetUri = (TextView) rootView.findViewById(R.id.targeturi);

            targetImage=(ImageView) rootView.findViewById(R.id.profpic);

            targetImage.setOnClickListener(new ImageView.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                Intent   intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 0);
            }});

            if (savedInstanceState != null) {
                //if there is a bundle, use the saved image resource (if one is there)
                image = savedInstanceState.getParcelable("BitmapImage");
                targetImage.setImageBitmap(image);
                textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
            } 



        return rootView;



    }

    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState){
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putParcelable("BitmapImage", bitmap);
        savedInstanceState.putString("path_to_picture", picture_location);
    }


    @Override
    public void onActivityResult( int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK){
            Uri targetUri = data.getData();
            picture_location = targetUri.toString();
            textTargetUri.setText(targetUri.toString());
            Bitmap bitmap;
            try {
                bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(targetUri));
                targetImage.setImageBitmap(bitmap);
            } 
            catch (FileNotFoundException e){
                e.printStackTrace();
            }
        }   
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub

    }}

顺便说一句,您可能已经注意到,我尝试使用不同的方法,而不是在 oncreate 之后使用 onRestoreInstanceState。我从另一个问题中找到了答案,您也可以在 oncreate 中实现它。我使用它是因为每当我声明函数 onRestoreInstanceState 时,都会要求我删除 @Override 注释。

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState){       
            image = savedInstanceState.getParcelable("BitmapImage");
            targetImage.setImageBitmap(image);
            textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
    }
4

4 回答 4

1

如果您没有完成活动,您可以使用onSavedInstance()来存储picture_location值并将其绑定回值中onCreate(SavedInst)/onRestore()picture_location值中。

于 2014-08-29T14:49:17.457 回答
1

使用 onSaveInstanceState 和 onCreate/onRestoreInstanceState 用于短期活动状态保存 - 但不能用于应用程序数据的持久存储。

您可以在此处阅读有关 onSaveInstanceState的信息

您可以在此处阅读有关持久存储的信息

codeMagic 建议使用 SharedPrefs(请参阅持久存储链接)作为您的长期持久存储。如果你想这样做,我建议在你的 onActivityResult 方法中保存图像 URI(链接有一个很好的例子),然后调用一个方法来读取 SharedPref 并加载你可以调用的图像onCreate 以及来自 onActivityResult。

您可能还希望将自己的图像/位图副本存储在应用程序自己的内部存储中(请参阅持久存储链接)。

于 2014-08-29T15:02:54.407 回答
0

1)//清单.xml

2)//公共类MainActivity扩展AppCompatActivity实现LocationListener{...

SharedPreferences.Editor editor;

3)//protected void onCreate(Bundle savedInstanceState){ ...

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
            PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 3);
    }

4)//共享首选项 SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", getApplicationContext().MODE_PRIVATE); 编辑器 = pref.edit();

5)//设置图像路径 if (pref.getString("mydraw", null) != null) {

        img6.setImageURI(Uri.parse(pref.getString("mydraw", null)));

    } else {
        //set default image
        img6.setImageResource(R.drawable.poseidon);
    }

6)//protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {...

if (requestCode == 100) { if (resultCode == RESULT_OK) {

            img6.setImageURI(data.getData());

            //save URI as string
            editor.putString("mydraw", data.getData().toString());
            editor.commit(); // commit changes

        }
    }
于 2021-02-15T14:28:32.433 回答
0

在位图实例状态的情况下,不建议保留有关所选图像的信息。

您可以在此处找到解释:处理配置更改

我在这里写了很多关于它的博客:在屏幕旋转期间保留选定的图像

下面我粘贴我的图示解决方案的实现:

1 - 创建一个片段并将其配置为保留在内存中

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;

public class ImageRetainingFragment extends Fragment {
    private Bitmap selectedImage;

    @Override    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // retain this fragment        
        setRetainInstance(true);
}

public void setImage(Bitmap selectedImage) {
    this.selectedImage = selectedImage;
}

public Bitmap getImage() {
    return this.selectedImage;
}
}

2 - 在您的活动中使用它

private static final String FRAGMENT_NAME = "imageFragment";


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ....

    initializeImageRetainingFragment();
    tryLoadImage();
}


private void initializeImageRetainingFragment() {
    // find the retained fragment on activity restarts    
    FragmentManager fragmentManager = getSupportFragmentManager();
    this.imageRetainingFragment = (ImageRetainingFragment)  fragmentManager.findFragmentByTag(FRAGMENT_NAME);
    // create the fragment and bitmap the first time   
    if (this.imageRetainingFragment == null) {
         this.imageRetainingFragment = new ImageRetainingFragment();
         fragmentManager.beginTransaction()
         // Add a fragment to the activity state. 
         .add(this.imageRetainingFragment, FRAGMENT_NAME)
         .commit();
   }
}
private void tryLoadImage() {
   if (this.imageRetainingFragment == null) {
       return;
   }

   Bitmap selectedImage = this.imageRetainingFragment.getImage();
      if (selectedImage == null) {
        return;
      }

      ImageView selectedImageView = (ImageView)findViewById(R.id.selectedImage);
      selectedImageView.setImageBitmap(selectedImage);
}
于 2016-04-01T16:01:31.320 回答