代码之家  ›  专栏  ›  技术社区  ›  CoolMind

活动重新创建后还原侦听器(将照片传递到从相机返回的自定义视图)

  •  0
  • CoolMind  · 技术社区  · 7 年前

    我有一个带有片段的活动。在一个片段中,我有两个自定义视图。自定义视图包含 ImageView 还有一个听众。侦听器可以转换、在ImageView中显示照片并上载照片。

    我想从相机中拍摄一张照片,将其返回片段,通过侦听器传递到视图(然后在视图中显示并上传)。一切正常,直到摄像机可见后活动被破坏。所以,从相机回来后,我恢复了碎片,把照片放进去 onActivityResult 并尝试通过侦听器传递到视图。但听众是 null ,我不知道它附加到什么视图。

    如何在重新创建活动后将照片传递给视图?

    侦听器:

    public interface Listener {
        void onPhotoObtained(@Nullable Uri uri);
    }
    

    自定义视图:

    public class CustomView extends RelativeLayout implements Listener {
        @BindView(R.id.imageview) ImageView image;
    
        private PhotoManager photoManager;
    
        public void setPhotoManager(@NonNull PhotoManager photoManager) {
            this.photoManager = photoManager;
        }
    
        @Override
        public void onPhotoObtained(@Nullable Uri uri) {
            // transform and show image
        }
    
        @OnClick(R.id.imageview)
        void onPhotoButtonClicked() {
            photoManager.requestPhoto(this);
        }
    }
    

    片段:

    public class MainFragment extends Fragment implements PhotoManager {
    
        @BindView(R.id.view1) CustomView view1;
        @BindView(R.id.view2) CustomView view2;
    
        // A list of listeners to communicate with custom views.
        // When a user clicks an ImageView, this fragment starts a camera to obtain a photo.
        private SparseArray<Listener> listeners;
        private int lastRequestId;
        private Uri uri;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.fragment_main, container, false);
            binder = ButterKnife.bind(this, view);
    
            listeners = new SparseArray<>();
            if (savedInstanceState == null) {
                lastRequestId = 0;
                uri = null;
            } else {
                lastRequestId = savedInstanceState.getInt(BUNDLE_REQUEST_ID);
                uri = savedInstanceState.getParcelable(BUNDLE_KEY_URI);
                // How to create a listener list?
            }
    
            view1.setPhotoManager(this);
            view2.setPhotoManager(this);
    
            return view;
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            if (requestCode == ReceivingPhotoDialogFragment.CAMERA_REQUEST) {
                if (resultCode == RESULT_OK) {
                    if (uri != null) {
                        // listeners become empty after fragment reinitialization
                        Listener listener = listeners.get(lastRequestId);
                        if (listener != null)
                            listener.onPhotoObtained(uri);
                    }
                }
            }
        }
    
        @Override
        public void onSaveInstanceState(@NonNull Bundle outState) {
            bundle.putInt(BUNDLE_REQUEST_ID, lastRequestId);
            bundle.putParcelable(BUNDLE_KEY_URI, uri);
            super.onSaveInstanceState(outState);
        }
    
        @Override
        public void requestPhoto(@NonNull Listener listener) {
            listeners.put(++lastRequestId, listener);
    
            // Request new photo with lastRequestId
            showCamera(lastRequestId);
        }
    
        private void showCamera(int requestId) {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (intent.resolveActivity(getContext().getPackageManager()) != null) {
                File file = null;
                try {
                    file = createImageFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                uri = null;
                if (file != null) {
                    uri = Uri.fromFile(file);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                    intent.putExtra(BUNDLE_REQUEST_ID, requestId);
                    startActivityForResult(intent, CAMERA_REQUEST);
                }
            }
        }
    
        private File createImageFile() throws IOException {
            // Create an image file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            return File.createTempFile(timeStamp, ".jpg", storageDir);
        }
    }
    

    要首先初始化的第二个侦听器:

    public interface PhotoManager {
        void requestPhoto(@NonNull Listener listener);
    }
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   Joel Libby    7 年前

    我仍在努力解决活动生命周期问题,因此这可能不是最好的答案。

    我所做的是把我的监听器作为一个静态变量。这允许变量存在于类中,而不是在销毁时清除的类实例中。

        2
  •  0
  •   Vishal Chhodwani    7 年前

    我认为,您不需要为此重新初始化侦听器, 您需要添加一个名为 configChanges 在您的 AndroidManifest。xml 具有以下内容的活动的文件 主要片段

    <activity 
        android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:screenOrientation="portrait"/>
    

    添加这些标记 配置更改 然后运行代码。