Android Framelayout 显示单个 ImageButton

Android Framelayout Displays single ImageButton

这是我的相机片段框架布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/sc_background">

    <FrameLayout
        android:id="@+id/sc_camera_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:layout_marginBottom="16dp"
        >

        <ImageButton
            android:id="@+id/sc_btn_flip_camera"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/sc_ic_camera_switch"
            style="?attr/scButtonSwitchCameraStyle"
            />

        <ImageButton
            android:id="@+id/sc_btn_take_picture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/sc_ic_camera"
            style="?attr/scButtonTakePictureStyle"
            />

        <ImageButton
            android:id="@+id/sc_btn_record_video"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/sc_ic_video"
            style="?attr/scButtonRecordVideoStyle"
            />

        <ImageButton
            android:id="@+id/sc_btn_stop_recording_video"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/sc_ic_stop"
            style="?attr/scButtonStopRecordingStyle"
            />

    </LinearLayout>

</FrameLayout>

但是当我 运行 我的 phone 上的程序时它只显示 sc_btn_take_picture。

    private static final String TAG = SimpleCameraFragment.class.getSimpleName();

    public static final int MENU_ITEM_QUALITY = 18438;


    interface Contract {

        void onPictureTaken(File photo);

        void onVideoRecorded(File video);

        void startSwitchingCamera(boolean currentlyFront);

        void changeCameraContainerSize(int width, int height);
    }

    public static SimpleCameraFragment newInstance(
            boolean startWithFrontFacingCamera,
            boolean camIsSwitchable,
            File directory,
            String location,
            Size pictureSize) {

        SimpleCameraFragment fragment = new SimpleCameraFragment();

        Bundle args = new Bundle(5);
        args.putBoolean(KEY_USE_FFC, startWithFrontFacingCamera);
        args.putBoolean(KEY_CAM_SWITCHABLE, camIsSwitchable);
        args.putString(KEY_FILE_DIR, directory == null ? null : directory.getPath());
        args.putString(KEY_FILE_NAME, location != null ? location : UUID.randomUUID().toString());
        args.putInt(KEY_PICTURE_SIZE, pictureSize.ordinal());

        fragment.setArguments(args);
        return fragment;
    }

    public enum Size {
        AVATAR(640 * 480),
        NORMAL(1280 * 960);

        private final int product;

        Size(int product) {
            this.product = product;
        }

        static Size tryOrdinal(int ordinal) {
            for (Size size : values()) {
                if (size.ordinal() == ordinal) {
                    return size;
                }
            }
            return NORMAL;
        }
    }

    public static final String KEY_USE_FFC = "com.askcs.teamup.ui.fragment.CameraFragment.USE_FFC";
    public static final String KEY_CAM_SWITCHABLE = "com.askcs.teamup.ui.fragment.CameraFragment.CAM_IS_SWITCHABLE";
    public static final String KEY_FILE_DIR = "com.askcs.teamup.ui.fragment.CameraFragment.FILE_DIR";
    public static final String KEY_FILE_NAME = "com.askcs.teamup.ui.fragment.CameraFragment.EXTRA_FILENAME";
    public static final String KEY_PICTURE_SIZE = "com.askcs.teamup.ui.fragment.CameraFragment.PICTURE_SIZE";

    private Contract contractor;
    private String flashMode = null;

    private boolean useFrontFacingCamera;
    private boolean canSwitchCamera;
    private boolean autoFocusAvailable;
    private File finalFile;
    private File dir;
    private String fileName;

    private int jpegQuality = 85;
    private Size imageSize = Size.NORMAL;

    private ImageButton btnTakePicture;
    private ImageButton btnSwitchCamera;
    private ImageButton btnRecordVideo;
    private ImageButton btnStopRecordingVideo;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);

        setHasOptionsMenu(true);

        String dirString = getArguments().getString(KEY_FILE_DIR);
        fileName = getArguments().getString(KEY_FILE_NAME);
        imageSize = Size.tryOrdinal(getArguments().getInt(KEY_PICTURE_SIZE, 0));
        useFrontFacingCamera = getArguments().getBoolean(KEY_USE_FFC);
        canSwitchCamera = getArguments().getBoolean(KEY_CAM_SWITCHABLE);

        dir = TextUtils.isEmpty(dirString) ? getActivity().getCacheDir() : new File(dirString);

        SimpleCameraHost.Builder builder =
                new SimpleCameraHost.Builder(new CameraHost(getActivity()));

        builder.useFullBleedPreview(false);

        setCameraHost(builder.build());
    }

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

        View view = super.onCreateView(inflater, container, savedInstanceState);

        FrameLayout root = (FrameLayout) inflater.inflate(R.layout.sc_camera_fragment, null);

        ((FrameLayout) root.findViewById(R.id.sc_camera_container)).addView(view);

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (autoFocusAvailable) {
                    autoFocus();
                }
            }
        });

        btnTakePicture = (ImageButton) root.findViewById(R.id.sc_btn_take_picture);
        btnTakePicture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onTakePictureClick();
            }
        });

        btnSwitchCamera = (ImageButton) root.findViewById(R.id.sc_btn_flip_camera);
        btnSwitchCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onSwitchCameraClick();
            }
        });

        btnRecordVideo = (ImageButton) root.findViewById(R.id.sc_btn_record_video);
        btnRecordVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onRecordVideoClick();
            }
        });

        btnStopRecordingVideo = (ImageButton) root.findViewById(R.id.sc_btn_stop_recording_video);
        btnStopRecordingVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onStopRecordVideoClick();
            }
        });

        return root;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        resetButtons();
    }

    void onTakePictureClick() {

        btnTakePicture.setEnabled(false);
        btnSwitchCamera.setEnabled(false);
        btnRecordVideo.setEnabled(false);

        takePicture();
    }

    void onSwitchCameraClick() {

        // Disable functions to prevent issues during fragment replacement
        btnTakePicture.setEnabled(false);
        btnSwitchCamera.setEnabled(false);
        btnRecordVideo.setEnabled(false);
        btnStopRecordingVideo.setEnabled(false);

        // Tell the parent activity to replace this fragment by the one with the 'different' camera view
        // If current is front, change to back. If current is back, change to front.
        ((SimpleCameraActivity) getActivity()).startSwitchingCamera( useFrontFacingCamera );

    }

    void onRecordVideoClick() {

        btnTakePicture.setEnabled(false);
        btnTakePicture.setVisibility(GONE);

        btnSwitchCamera.setEnabled(false);
        btnSwitchCamera.setVisibility(GONE);

        btnRecordVideo.setEnabled(false);
        btnRecordVideo.setVisibility(GONE);

        btnStopRecordingVideo.setEnabled(true);
        btnStopRecordingVideo.setVisibility(VISIBLE);

        try {
            record();
        }
        catch (Exception e) {
            Log.e(TAG, "Something went wrong while calling record()", e);
        }
    }

    void onStopRecordVideoClick() {

        btnStopRecordingVideo.setEnabled(false);

        try {
            stopRecording();
        }
        catch (IOException e) {
            Log.e(TAG, "Something went wrong while calling stopRecording()", e);
        }
    }

    void resetButtons() {

        if (btnTakePicture != null) {
            btnTakePicture.setVisibility(VISIBLE);
            btnTakePicture.setEnabled(true);
        }

        if (btnRecordVideo != null) {
            btnRecordVideo.setVisibility(GONE);
            btnRecordVideo.setEnabled(false);
        }

        // Check if we have to show the switch camera button
        if (btnSwitchCamera != null) {

            if(canSwitchCamera) {
                btnSwitchCamera.setVisibility(VISIBLE);
                btnSwitchCamera.setEnabled(true);
            } else {
                btnSwitchCamera.setVisibility(GONE);
                btnSwitchCamera.setEnabled(false);
            }

        }

        if (btnStopRecordingVideo != null) {
            btnStopRecordingVideo.setVisibility(GONE);
            btnStopRecordingVideo.setEnabled(false);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        this.contractor = (Contract) activity;
    }

    @Override
    public void onDetach() {
        super.onDetach();

        this.contractor = null;
    }

    @Override
    public void takePicture() {
        if (!btnTakePicture.isEnabled()) {

            btnTakePicture.setVisibility(View.GONE);
            btnTakePicture.setEnabled(false);

            super.takePicture(new PictureTransaction(getCameraHost()).flashMode(flashMode).mirrorFFC(true));
        }
    }

    @Override
    public void stopRecording() throws IOException {
        super.stopRecording();

        contractor.onVideoRecorded(finalFile);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);

        MenuItem qualitySlider = menu.add(0, MENU_ITEM_QUALITY, 0, R.string.sc_menu_label_quality);
        MenuItemCompat.setShowAsAction(qualitySlider, MenuItem.SHOW_AS_ACTION_NEVER);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case MENU_ITEM_QUALITY:

                new DialogFragment() {

                    private int newJpegQuality;

                    @Override
                    public Dialog onCreateDialog(Bundle savedInstanceState) {

                        LinearLayout rootView = (LinearLayout) View.inflate(getActivity(), R.layout.sc_dialog_quality, null);

                        SeekBar qualityBar = (SeekBar) rootView.getChildAt(0);
                        qualityBar.setMax(50);
                        qualityBar.setProgress(jpegQuality - 50);
                        qualityBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                            @Override
                            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                                if (fromUser) {
                                    newJpegQuality = 50 + progress;
                                    getDialog().setTitle(getString(R.string.sc_image_quality, new Object[]{newJpegQuality}));
                                }
                            }

                            @Override
                            public void onStartTrackingTouch(SeekBar seekBar) {
                                // ignored
                            }

                            @Override
                            public void onStopTrackingTouch(SeekBar seekBar) {
                                // ignored
                            }
                        });

                        return new AlertDialog.Builder(getActivity())
                                .setTitle("Image quality: " + jpegQuality + "%")
                                .setView(rootView)
                                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        jpegQuality = newJpegQuality;
                                        dialog.dismiss();
                                    }
                                })
                                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        dialog.dismiss();
                                    }
                                })
                                .create();
                    }
                }.show(getFragmentManager(), "quality-slider");

                return true;
        }

        return (super.onOptionsItemSelected(item));
    }

    class CameraHost extends SimpleCameraHost {

        public CameraHost(Context _ctxt) {
            super(_ctxt);
        }

        @Override
        public Camera.Parameters adjustPictureParameters(PictureTransaction xact, Camera.Parameters parameters) {

            parameters.setJpegQuality(jpegQuality);

            for (Camera.Size size : parameters.getSupportedPictureSizes()) {
                Log.v(TAG, "w=" + size.width + ", h=" + size.height);
            }

            return parameters;
        }

        @Override
        public Camera.Size getPictureSize(PictureTransaction xact, Camera.Parameters parameters) {

            List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
            ArrayList<Integer> calculated = new ArrayList<Integer>();

            for (Camera.Size size : sizes) {
                calculated.add(size.height * size.width);
            }

            int closestIndexUntilNow = 0;
            int lastDelta = Integer.MAX_VALUE;
            for (int i = 0; i < calculated.size(); i++) {

                int delta = Math.abs(imageSize.product - calculated.get(i));

                if (delta < lastDelta) {
                    closestIndexUntilNow = i;
                }

                lastDelta = delta;
            }

            Camera.Size size = sizes.get(closestIndexUntilNow);

            Log.v(TAG, "Chosen size: w=" + size.width + ", h=" + size.height);

            return size;
        }

        @Override
        public float maxPictureCleanupHeapUsage() {
            return super.maxPictureCleanupHeapUsage();
        }

        @Override
        protected File getPhotoPath() {

            if (finalFile == null) {
                finalFile = super.getPhotoPath();
            }

            return finalFile;
        }

        @Override
        public RecordingHint getRecordingHint() {
            return RecordingHint.STILL_ONLY;
        }

        @Override
        protected File getVideoPath() {

            if (finalFile == null) {
                finalFile = super.getVideoPath();
            }

            return finalFile;
        }

        @Override
        protected File getPhotoDirectory() {
            return dir;
        }

        @Override
        protected String getPhotoFilename() {

            if (!fileName.endsWith(".jpg")) {
                fileName += ".jpg";
            }

            Log.v(TAG, String.valueOf(fileName));

            return fileName;
        }

        @Override
        protected File getVideoDirectory() {
            return dir;
        }

        @Override
        protected String getVideoFilename() {

            if (!fileName.endsWith(".mp4")) {
                fileName += ".mp4";
            }

            Log.v(TAG, String.valueOf(fileName));

            return fileName;
        }

        @Override
        public boolean useFrontFacingCamera() {
            return useFrontFacingCamera;
        }

        @Override
        public boolean useSingleShotMode() {
            return true;
        }

        @Override
        public void saveImage(PictureTransaction xact, byte[] image) {

            File photo = getPhotoPath();

            if (photo.exists()) {
                photo.delete();
            }

            try {
                FileOutputStream fos = new FileOutputStream(photo.getPath());
                BufferedOutputStream bos = new BufferedOutputStream(fos);

                bos.write(image);
                bos.flush();
                fos.getFD().sync();
                bos.close();
            }
            catch (IOException e) {
                handleException(e);
            }

            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    btnTakePicture.setEnabled(false);
                    btnRecordVideo.setEnabled(false);
                    btnStopRecordingVideo.setEnabled(false);

                    btnTakePicture.setVisibility(GONE);
                    btnRecordVideo.setVisibility(GONE);
                    btnStopRecordingVideo.setVisibility(GONE);

                    resetButtons();

                    contractor.onPictureTaken(new File(dir, fileName));
                }
            });
        }

        @Override
        public void autoFocusAvailable() {
            autoFocusAvailable = true;
        }

        @Override
        public void autoFocusUnavailable() {
            autoFocusAvailable = false;
        }

        @Override
        public void onCameraFail(com.google.cam2.camera.CameraHost.FailureReason reason) {
            super.onCameraFail(reason);

            Toast.makeText(getActivity(),
                    "Sorry, but you cannot use the camera now!",
                    Toast.LENGTH_LONG).show();
        }

        @Override
        public Camera.Parameters adjustPreviewParameters(Camera.Parameters parameters) {
            flashMode =
                    CameraUtils.findBestFlashModeMatch(parameters,
                            Camera.Parameters.FLASH_MODE_RED_EYE,
                            Camera.Parameters.FLASH_MODE_AUTO,
                            Camera.Parameters.FLASH_MODE_ON);

            List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
            ArrayList<Integer> calculated = new ArrayList<Integer>();

            for (Camera.Size size : sizes) {
                calculated.add(size.height * size.width);
            }

            int closestIndexUntilNow = 0;
            int lastDelta = Integer.MAX_VALUE;
            for (int i = 0; i < calculated.size(); i++) {

                int delta = Math.abs(imageSize.product - calculated.get(i));

                if (delta < lastDelta) {
                    closestIndexUntilNow = i;
                }

                lastDelta = delta;
            }

            Camera.Size size = sizes.get(closestIndexUntilNow);

            parameters.setPreviewSize(size.width, size.height);

            return (super.adjustPreviewParameters(parameters));
        }

        @Override
        public Camera.Size getPreviewSize(int displayOrientation, int width, int height, Camera.Parameters parameters) {

            List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
            ArrayList<Integer> calculated = new ArrayList<Integer>();

            for (Camera.Size size : sizes) {
                calculated.add(size.width * size.height);
            }

            int closestIndexUntilNow = 0;
            int lastDelta = Integer.MAX_VALUE;
            for (int i = 0; i < calculated.size(); i++) {

                int delta = Math.abs(imageSize.product - calculated.get(i));

                if (delta < lastDelta) {
                    closestIndexUntilNow = i;
                }

                lastDelta = delta;
            }

            Camera.Size size = sizes.get(closestIndexUntilNow);
//            contractor.changeCameraContainerSize(size.width, size.height);

            return size;
        }

        @Override
        public boolean mirrorFFC() {
            return true;
        }
    }
}

到目前为止,我尝试在父 FrameLayout 上添加 LinearLayout。我还在框架布局中直接添加了图像按钮。但是当我 运行 进入我的设备时,它只显示 sc_btn_take_picture。我也附上截图。

我认为您需要将 android:orientation="horizontal" 添加到您设置相机控制图像按钮的线性布局中

我认为问题出在您的 resetButtons() 方法中,其中大部分设置为 setVisibility(GONE);

btnTakePicture 设置为可见,btnSwitchCamera 仅在 canSwitchCamera 为真时设置为可见,但我们无法从您的代码中看到设置的位置.其他按钮在 resetButtons() 方法中设置为消失。