Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android layout help, missing elements

I’m trying to creating a layout that contains a "SurfaceView" at the top with a horizontal toolbar that is section into 3 segments in the bottom, however my SurfaceView which contains camera preview is only the only element that is showing. Please point out the error in my layout xml or provide me the similar layout xml, Thanks.

Below is my layout & updates based on user recommendations

Attempt # 1 (RelativeLayout as root):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LayoutForPreview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:screenOrientation="portrait" >

    <SurfaceView
        android:id="@+id/surfaceViewBarcodeScanner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/linearLayoutToolbar"
        android:layout_gravity="top"
        android:scaleType="fitXY" />

    <LinearLayout
        android:id="@+id/linearLayoutToolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:src="@drawable/scanner_bottom_left" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.68"
            android:scaleType="fitXY"
            android:src="@drawable/scanner_bottom_center_toolbar" />

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:src="@drawable/scanner_bottom_right_landscape_button" />
    </LinearLayout>

</RelativeLayout>

Below is my desired GUI look:

enter image description here

Attempt #1 Result , device snapshot , which only shows the SurfaceView:

enter image description here

Snapshot of eclipse GUI tool, which shows what the layout should look like. enter image description here

Attempt # 2 (LinearLayout as root):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LayoutForPreview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:screenOrientation="portrait" >

    <SurfaceView
        android:id="@+id/surfaceViewBarcodeScanner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:scaleType="fitXY"
        android:layout_weight="1" />

    <LinearLayout
        android:id="@+id/linearLayoutToolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="bottom" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:src="@drawable/scanner_bottom_left" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.68"
            android:scaleType="fitXY"
            android:src="@drawable/scanner_bottom_center_toolbar" />

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:src="@drawable/scanner_bottom_right_landscape_button" />
    </LinearLayout>

</LinearLayout>

Attempt #2 , Result , Device snapshot :

enter image description here

Issues:

1) Toolbar appears on top rather than on bottom

2) Camera preview freezes & app crashes. For some reason LinearLayout causes the Camera error 1001 , and I think its related to preview sizes.

Attempt #3 (Add toolbar programmatically to either Relative or Linear layout in activity onCreate).

LinearLayout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LayoutForPreview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:screenOrientation="portrait" >

    <SurfaceView
        android:id="@+id/surfaceViewBarcodeScanner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:scaleType="fitXY"
        android:layout_weight="1" />

</LinearLayout>

Toolbar defined in separate XML added later via Java code:

<?xml version="1.0" encoding="UTF-8"?>
<!--  LinearLayout that contains toolbar that is divided into 3 sections horizontally , layout_below="@+id/BarcodeScannerFrame-->
<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayoutToolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:src="@drawable/scanner_bottom_left" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0.68"
        android:scaleType="fitXY"
        android:src="@drawable/scanner_bottom_center_toolbar" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:src="@drawable/scanner_bottom_right_landscape_button" />
</LinearLayout>

onCreate,onResume,other relevant code snippets of my activity only, the LinearLayout toolbar is added to Linear or Relative layout at runtime:

//import not included 
    public class ScanVinFromBarcodeActivity extends Activity {
        // camera object that is used globally in this activity and also passed
        // reference to PreviewSurface inner class
        private Camera globalCamera;
        private int cameraId = 0;
        // bitmap that would created after picture is taken and converted from
        // camera bytes
        private Bitmap bmpOfTheImageFromCamera = null;
        // global flag whether a camera has been detected
        private boolean isThereACamera = false;
        // layout for this activity
        private LinearLayout RelativeLayoutBarcodeScanner= null;
        // CameraPreview extends SurfaceView displays preview of images from the
        // Camera
        private CameraPreview newCameraPreview = null;
        // used to inflate the xml layout
        private SurfaceView surfaceViewBarcodeScanner = null;
        private boolean cameraPreviewing = false;
        // this continueToAutomaticallyDecode flag is initially set to TRUE, but
        // will be set to FALSE on the first successful decode OR when a crucial
        // method in the code process fails or throws an exception
        private volatile boolean continueToAutomaticallyDecode = true;
        // global flag used to indicate picture taking & decoding is in progress
        private volatile boolean takingPictureAndDecodeInprogress = false;
        // Bitmap options for bitmap creation from camera picture
        BitmapFactory.Options options = null;
        // used for samsung galaxy s devices only
        private Matrix rotationMatrix90CounterClockWise = null;
        // Reader is class from zxing used to decode barcodes
        Reader reader = null;
        // DecodeHintType hashtable is used to provide help to the zxing Reader
        // class
        Hashtable<DecodeHintType, Object> decodeHints = null;
        //
        private boolean onTouchEvent = true;
        //
        private OrientationEventListener orientationEventListener = null;
        // 1 means the screen is PORTRAIT and 2 means screen is LANDSCAPE
        private int latestScreenOrientation = 1;
        //
        Camera.Parameters Flash = null;
        //
        private String globalVIN = null; 
        //
        private Handler handler = null;
        //
        private LinearLayout barcodeVinScannerToolbar = null; 

        public boolean isContinueToAutomaticallyDecode() {

            return continueToAutomaticallyDecode;
        }

        public void setContinueToAutomaticallyDecode(
                boolean continueToAutomaticallyDecode) {

                this.continueToAutomaticallyDecode = continueToAutomaticallyDecode;

        }

        public boolean isTakingPictureAndDecodeInprogress() {
            return takingPictureAndDecodeInprogress;
        }

        public void setTakingPictureAndDecodeInprogress(
                boolean takingPictureAndDecodeInprogress) {

                this.takingPictureAndDecodeInprogress = takingPictureAndDecodeInprogress;

        }

        /*
         * This method , finds FEATURE_CAMERA, opens the camera, set parameters ,
         * add CameraPreview to layout, set camera surface holder, start preview
         */
        @SuppressLint("InlinedApi")
        private void initializeGlobalCamera() {

            try {
                if (!getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_CAMERA)) {
                    Toast.makeText(this, "No camera on this device",
                            Toast.LENGTH_LONG).show();
                } else { // check for front camera ,and get the ID
                    cameraId = findFrontFacingCamera();
                    if (cameraId < 0) {

                        Toast.makeText(this, "No front facing camera found.",
                                Toast.LENGTH_LONG).show();
                    } else {

                        Log.d("ClassScanViewBarcodeActivity",
                                "camera was found , ID: " + cameraId);
                        // camera was found , set global camera flag to true
                        isThereACamera = true;
                        // OPEN
                        globalCamera = getGlobalCamera(cameraId);
                        // parameters auto focus
                        globalCamera.getParameters().setFocusMode(
                                Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                        // set picture format to JPEG, everytime makesure JPEg
                        globalCamera.getParameters().setPictureFormat(
                                ImageFormat.JPEG);
                        autoFocusSetupForBarcode(globalCamera);
                        /*
                         * START early setup variables & setting used in
                         * jpegCallback in order to optimize the jpegCallback code
                         */
                        options = new BitmapFactory.Options();
                        // option set for down sampling he captured image taken from
                        // the camera in order to MemoryOutOfBounds exception
                        options.inSampleSize = 4;
                        // image quality rather than speed in order to achieve early
                        // barcode detection & decode
                        options.inPreferQualityOverSpeed = false;
                        // Samsung galaxy S only , rotate to correct orientation
                        // ,and capture only the image within the guidance rectangle

                        rotationMatrix90CounterClockWise = new Matrix();
                        rotationMatrix90CounterClockWise.postRotate(90);
                        // early variable used by zxing to decode method
                        decodeHints = new Hashtable<DecodeHintType, Object>();
                        decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
                        decodeHints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
                        decodeHints.put(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT,
                                Boolean.TRUE);
                        reader = new MultiFormatReader();

                        turnOnFlashlight(globalCamera);

                        // pass surfaceView to CameraPreview
                        newCameraPreview = new CameraPreview(this, globalCamera) {

                            @Override
                            public boolean onTouchEvent(MotionEvent event) {
                                Log.d("ClassScanViewBarcodeActivity",
                                        " onTouchEvent(MotionEvent event) ");

                                onTouchEvent = true;
                                globalCamera
                                        .autoFocus(autoFocusCallbackForAutomaticScan);

                                return super.onTouchEvent(event);
                            }

                        };

                        // pass CameraPreview to Layout
                        RelativeLayoutBarcodeScanner.addView(newCameraPreview);


                        // give reference SurfaceView to camera object
                        globalCamera.setPreviewDisplay(surfaceViewBarcodeScanner
                                .getHolder());

                        // PREVIEW
                        if (cameraPreviewing != true) {
                            globalCamera.startPreview();
                        }

                        Log.d("ClassScanViewBarcodeActivity",
                                "camera opened & previewing");
                    }
                }// end else ,check for front camera
            }// end try
            catch (Exception exc) {

                // in case of exception release resources & cleanup
                if (globalCamera != null) {
                    globalCamera.stopPreview();
                    cameraPreviewing = false;
                    globalCamera.setPreviewCallback(null);
                    globalCamera.release();
                    globalCamera = null;
                    options = null;
                    rotationMatrix90CounterClockWise = null;
                    reader = null;

                }
                Log.d("ClassScanViewBarcodeActivity initializeGlobalCamera() exception:",
                        exc.getMessage());
                exc.printStackTrace();
            }// end catch

        }// end ini

        /* this method detect whether the camera flashlight a.k.a torch feature is available to be turned on then turns on the light*/
        public void turnOnFlashlight(Camera camera) {
            Log.d("ClassScanViewBarcodeActivity",
                    "turnOnFlashlight(Camera camera )");

            boolean flag = false;
            Context context  = null; 
            if (camera != null) {
                Log.d("ClassScanViewBarcodeActivity",
                        "turnOnFlashlight() , FEATURE_CAMERA_FLASH: " + flag);

                context = RelativeLayoutBarcodeScanner.getContext();
                if (context != null) {
                    flag = context.getPackageManager().hasSystemFeature(
                            PackageManager.FEATURE_CAMERA_FLASH);
                    if (flag) {
                        Flash = camera.getParameters();
                        Flash.setFlashMode("torch");

                        camera.setParameters(Flash);

                    }// end if camera feature is available

                    else {
                        Log.d("ClassScanViewBarcodeActivity",
                                "turnOnFlashlight() , FEATURE_CAMERA_FLASH: "
                                        + flag);
                    }
                }// end if context not null

            }// end camera not null

        }// end turnOnFlashlight(Camera camera )

        // onCreate, instantiates layouts & surfaceView used for video preview
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_barcode_vin_scanner);
            Log.d("ClassScanViewBarcodeActivity", "onCreate ");

            // create surfaceView for previewing of camera image
            RelativeLayoutBarcodeScanner = (LinearLayout) findViewById(R.id.LayoutForPreview);
            surfaceViewBarcodeScanner = (SurfaceView) findViewById(R.id.surfaceViewBarcodeScanner);
            barcodeVinScannerToolbar = (LinearLayout) findViewById(R.id.linearLayoutToolbar);



            initializeGlobalCamera();


            //*****TOOLBAR IS ADDED*****

            if (RelativeLayoutBarcodeScanner!=null && barcodeVinScannerToolbar!=null)
            {

                //surfaceViewBarcodeScanner.addChildrenForAccessibility(list);
               RelativeLayoutBarcodeScanner.addView(barcodeVinScannerToolbar);      

            }


            // instantiate orientationEventListener
            orientationEventListener = new OrientationEventListener(this,
                    SensorManager.SENSOR_DELAY_NORMAL) {

                @Override
                public void onOrientationChanged(int arg0) {


                    /*
                    latestScreenOrientation = ScreenUtility
                            .getScreenOrientation(RelativeLayoutBarcodeScanner.getContext());

                    Log.d("ClassScanViewBarcodeActivity",
                            "latestScreenOrientation: " + latestScreenOrientation);

                    if (orientationEventListener.canDetectOrientation()) {
                        orientationEventListener.enable();
                        Log.d("ClassScanViewBarcodeActivity",
                                "enabled orientationEventListener: "
                                        + String.valueOf(orientationEventListener
                                                .canDetectOrientation()));
                    } else {
                        Log.d("ClassScanViewBarcodeActivity",
                                "enabled orientationEventListener: "
                                        + String.valueOf(orientationEventListener
                                                .canDetectOrientation()));
                    }
    */
                }

            };



            handler = new Handler();




        }// end onCreate


        @Override
        protected void onResume() {

            Log.d("ClassScanViewBarcodeActivity, onResume() globalCamera:",
                    String.valueOf(globalCamera));

            initializeGlobalCamera();


            //*****TOOLBAR IS ADDED*****

            if (RelativeLayoutBarcodeScanner!=null && barcodeVinScannerToolbar!=null)
            {

                //surfaceViewBarcodeScanner.addChildrenForAccessibility(list);
               RelativeLayoutBarcodeScanner.addView(barcodeVinScannerToolbar);      

            }


            if (orientationEventListener != null) {
                orientationEventListener.enable();
            }

            super.onResume();
        }

        @Override
        protected void onStop() {

            if (globalCamera != null) {
                globalCamera.stopPreview();
                cameraPreviewing = false;
                globalCamera.setPreviewCallback(null);
                globalCamera.release();
                globalCamera = null;
            }

            if (orientationEventListener != null) {
                orientationEventListener.disable();
            }
            super.onStop();
        }

        @Override
        protected void onPause() {
            if (globalCamera != null) {
                globalCamera.stopPreview();
                cameraPreviewing = false;
                globalCamera.setPreviewCallback(null);
                globalCamera.release();
                globalCamera = null;
                options = null;
                rotationMatrix90CounterClockWise = null;
                reader = null;
            }
            if (orientationEventListener != null) {
                orientationEventListener.disable();
            }
            super.onPause();
        }// end onPause()

    //other irrelevant code was not included

    }//end activity

Attempt #3, result, screen freezes , no particular error or exception reported:

enter image description here

Error log:

enter image description here

**If the eclipse GUI tool shows the desired look , than why is the toolbar still missing??? I would like to have the toolbar in the bottom , preferably using RelativeLayout without any crashes or screen freezes. Any help will be appreciated.

I'm using Samsung Galaxy S3 for testing.

Thanks.**

like image 688
cyber101 Avatar asked Nov 23 '13 18:11

cyber101


People also ask

What are the advantages of setting a layout in Android?

Android provides a very flexible way to display layouts using XML-based layouts. This helps us create apps while keeping the layout and logic completely separate. This makes it very easy for us to change the layout even after the application is written, without having any changes in the programming logic.

What is the difference between relative layout and linear layout?

LinearLayout : is a ViewGroup that aligns all children in a single direction, vertically or horizontally. RelativeLayout : is a ViewGroup that displays child views in relative positions. AbsoluteLayout : allows us to specify the exact location of the child views and widgets.

What is XML used for in Android?

XML stands for eXtensible Markup Language, which is a way of describing data using a text-based document. Because XML is extensible and very flexible, it's used for many different things, including defining the UI layout of Android apps.


1 Answers

You wanted something like this?

enter image description here

the layout I used is:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:id="@+id/linearLayoutToolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        >
        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:src="@drawable/ic_launcher"
        />
        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:src="@drawable/ic_launcher"
        />
        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:src="@drawable/ic_launcher"
        />
    </LinearLayout>
    <SurfaceView
        android:id="@+id/surfaceViewBarcodeScanner"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/linearLayoutToolbar"
    />
</RelativeLayout>

Please note that, since I didn't have your images in my res/drawable folder, I replaced them with ic_launcher.

Also note that I used an ldpi device running Froyo (API level 2.2). This is why the image is smaller than yours and the UI differs slighthly (...). Anyway, it works at every resolution and with every os version.

like image 162
Phantômaxx Avatar answered Oct 19 '22 05:10

Phantômaxx