在setVisibility(View.INVISIBLE)之后,ImageView仍然可见

时间:2016-03-18 10:11:18

标签: java android android-layout imageview

我正在尝试制作一个在拍摄照片时显示叠加的相机应用程序。 显示此叠加层时,其他UI组件(显示图片的FrameLayout除外)应该不可见。 但似乎虽然我的2个图像按钮变得无形,但我的图像视图(ivCompass)并没有。

以下是拍摄照片时调用的代码

Camera.PictureCallback mPicture = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        //create a new intent...
        String path = createFile(data);
        intent = new Intent();
        intent.putExtra("path", path);

        mBearingProvider.updateBearing();
        bearing = mBearingProvider.getBearing();
        cardinalDirection = bearingToString(bearing);
        //((TextView) findViewById(R.id.tvPicDirection)).setText(cardinalDirection);
        Log.e("Direction", cardinalDirection + "," + bearing);
        findViewById(R.id.btnFlash).setVisibility(View.INVISIBLE);
        findViewById(R.id.btnCapture).setVisibility(View.INVISIBLE);
        findViewById(R.id.ivCompass).setVisibility(View.INVISIBLE);
        findViewById(R.id.pictureOverlay).setVisibility(View.VISIBLE);
    }
};

这是布局文件

<?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">

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

<ImageButton
    android:id="@+id/btnFlash"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerVertical="true"
    android:layout_margin="10dp"
    android:src="@drawable/camera_flash_on"
    android:background="@drawable/circle_flash"
    android:onClick="changeFlashMode"/>

<ImageButton
    android:id="@+id/btnCapture"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_margin="10dp"
    android:src="@drawable/icon_camera"
    android:background="@drawable/circle_camera"/>

<ImageView
    android:id="@+id/ivCompass"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_alignParentRight="true"
    android:src="@drawable/camera_compass"
    android:background="@android:color/transparent"/>

<RelativeLayout
    android:id="@+id/pictureOverlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    android:background="@color/alphaBlack"
    android:visibility="invisible">

</RelativeLayout>

我认为这只是一个错误的命名,语法或类似的东西,但我似乎无法找到它。

修改

这是整个活动

public class CameraActivity extends AppCompatActivity implements BearingToNorthProvider.ChangeEventListener {

private Camera mCamera;
private CameraView mCameraView;
private float mDist = 0f;
private String flashMode;
private ImageButton flashButton;
private Intent intent;
private BearingToNorthProvider mBearingProvider;
private double bearing;
private double currentBearing = 0d;
private String cardinalDirection = "?";

private final int REQUEST_CODE_ASK_PERMISSIONS = 2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);
    mCamera = getCameraInstance();
    mCameraView = new CameraView(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mCameraView);
    ImageButton captureButton = (ImageButton) findViewById(R.id.btnCapture);
    captureButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Camera.Parameters params = mCamera.getParameters();
            params.setFlashMode(flashMode);
            mCamera.setParameters(params);
            mCamera.takePicture(null, null, mPicture);
        }
    });
    SharedPreferences sharedPref = this.getSharedPreferences(getString(R.string.apiKey), Context.MODE_PRIVATE);
    flashMode = sharedPref.getString(getString(R.string.flashMode), Camera.Parameters.FLASH_MODE_OFF);
    flashButton = (ImageButton) findViewById(R.id.btnFlash);
    setFlashButton();
    mBearingProvider = new BearingToNorthProvider(this,this);
    mBearingProvider.setChangeEventListener(this);
    mBearingProvider.start();
}

@Override
protected void onPause() {
    super.onPause();
    mBearingProvider.stop();
}

/**
 * Helper method to access the camera returns null if it cannot get the
 * camera or does not exist
 *
 * @return the instance of the camera
 */
private Camera getCameraInstance() {
    Camera camera = null;
    try {
        camera = Camera.open();
    } catch (Exception e) {
        Log.e("CamException", e.toString());
    }
    return camera;
}

Camera.PictureCallback mPicture = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        //create a new intent...
        String path = createFile(data);
        intent = new Intent();
        intent.putExtra("path", path);

        mBearingProvider.updateBearing();
        bearing = mBearingProvider.getBearing();
        cardinalDirection = bearingToString(bearing);
        //((TextView) findViewById(R.id.tvPicDirection)).setText(cardinalDirection);
        Log.e("Direction", cardinalDirection + "," + bearing);
        findViewById(R.id.btnFlash).setVisibility(View.INVISIBLE);
        findViewById(R.id.btnCapture).setVisibility(View.INVISIBLE);
        findViewById(R.id.ivCompass).setVisibility(View.INVISIBLE);
        findViewById(R.id.pictureOverlay).setVisibility(View.VISIBLE);
    }
};

private void confirmPicture(View v) {
    /*String direction = String.valueOf(((TextView) findViewById(R.id.tvPicDirection)).getText());
    String description = String.valueOf(((EditText) findViewById(R.id.tvPicDescription)).getText());
    intent.putExtra("direction", direction);
    intent.putExtra("description", description);*/

    //close this Activity...
    setResult(Activity.RESULT_OK, intent);
    finish();
}

//region File Methods

/**
 * Method that creates a file from the given byte array and saves the file in the Pictures Directory
 * @param data is the array of bytes that represent the picture taken by the camera
 * @return the path of created file
 */
private String createFile(byte[] data){
    checkFilePermissions();
    File picFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "tempPic.jpg" + File.separator);
    String path = picFile.getPath();
    try {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(picFile));
        bos.write(data);
        bos.flush();
        bos.close();
        return path;
    } catch (IOException e) {
        e.printStackTrace();
        return "";
    }
}

/**
 * Checks the permission for reading to and writing from the external storage
 */
private void checkFilePermissions() {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        int hasWriteExternalStoragePermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (hasWriteExternalStoragePermission != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_CODE_ASK_PERMISSIONS);
            return;
        }
    }
}

//endregion

//region Zoom Methods

@Override
public boolean onTouchEvent(MotionEvent event) {
    // Get the pointer ID
    Camera.Parameters params = mCamera.getParameters();
    int action = event.getAction();


    if (event.getPointerCount() > 1) {
        // handle multi-touch events
        if (action == MotionEvent.ACTION_POINTER_DOWN) {
            mDist = getFingerSpacing(event);
        } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
            mCamera.cancelAutoFocus();
            handleZoom(event, params);
        }
    } else {
        // handle single touch events
        if (action == MotionEvent.ACTION_UP) {
            handleFocus(event, params);
        }
    }
    return true;
}

private void handleZoom(MotionEvent event, Camera.Parameters params) {
    int maxZoom = params.getMaxZoom();
    int zoom = params.getZoom();
    float newDist = getFingerSpacing(event);
    if (newDist > mDist) {
        //zoom in
        if (zoom < maxZoom)
            zoom++;
    } else if (newDist < mDist) {
        //zoom out
        if (zoom > 0)
            zoom--;
    }
    mDist = newDist;
    params.setZoom(zoom);
    mCamera.setParameters(params);
}

public void handleFocus(MotionEvent event, Camera.Parameters params) {
    int pointerId = event.getPointerId(0);
    int pointerIndex = event.findPointerIndex(pointerId);
    // Get the pointer's current position
    float x = event.getX(pointerIndex);
    float y = event.getY(pointerIndex);

    List<String> supportedFocusModes = params.getSupportedFocusModes();
    if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean b, Camera camera) {
                // currently set to auto-focus on single touch
            }
        });
    }
}

/** Determine the space between the first two fingers */
private float getFingerSpacing(MotionEvent event) {
    double x = event.getX(0) - event.getX(1);
    double y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
}

//endregion

//region Flash Methods

public void changeFlashMode(View v) {
    switch (flashMode) {
        case Camera.Parameters.FLASH_MODE_ON :
            flashMode = Camera.Parameters.FLASH_MODE_AUTO;
            break;
        case Camera.Parameters.FLASH_MODE_AUTO :
            flashMode = Camera.Parameters.FLASH_MODE_OFF;
            break;
        case Camera.Parameters.FLASH_MODE_OFF :
            flashMode = Camera.Parameters.FLASH_MODE_ON;;
            break;
    }
    SharedPreferences sharedPref = getSharedPreferences(getString(R.string.flashMode), Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putString(getString(R.string.flashMode), flashMode);
    editor.commit();
    setFlashButton();
}

public void setFlashButton() {
    switch (flashMode) {
        case Camera.Parameters.FLASH_MODE_ON :
            flashButton.setImageDrawable(getResources().getDrawable(R.drawable.camera_flash_on));
            break;
        case Camera.Parameters.FLASH_MODE_AUTO :
            flashButton.setImageDrawable(getResources().getDrawable(R.drawable.camera_flash_auto));
            break;
        case Camera.Parameters.FLASH_MODE_OFF :
            flashButton.setImageDrawable(getResources().getDrawable(R.drawable.camera_flash_off));
            break;
    }
}

//endregion

//region Bearing Methods

/**
 * Method that gives a cardinal direction based on the current bearing to the true north
 * @param bearing is the bearing to the true north
 * @return cardinal direction that belongs to the bearing
 */
private String bearingToString(Double bearing) {
    String strHeading = "?";
    if (isBetween(bearing,-180.0,-157.5)) { strHeading = "South"; }
    else if (isBetween(bearing,-157.5,-112.5)) { strHeading = "SouthWest"; }
    else if (isBetween(bearing,-112.5,-67.5)) { strHeading = "West"; }
    else if (isBetween(bearing,-67.5,-22.5)) { strHeading = "NorthWest"; }
    else if (isBetween(bearing,-22.5,22.5)) { strHeading = "North"; }
    else if (isBetween(bearing,22.5,67.5)) { strHeading = "NorthEast"; }
    else if (isBetween(bearing,67.5,112.5)) { strHeading = "East"; }
    else if (isBetween(bearing,112.5,157.5)) { strHeading = "SouthEast"; }
    else if (isBetween(bearing,157.5,180.0)) { strHeading = "South"; }
    return strHeading;
}

/**
 * Method that checks if a certain number is in a certain range of numbers
 * @param x is the number to check
 * @param lower is the number that defines the lower boundary of the number range
 * @param upper is the number that defines the upper boundary of the number range
 * @return true if the number is between the other numbers, false otherwise
 */
private boolean isBetween(double x, double lower, double upper) {
    return lower <= x && x <= upper;
}

/*
Method that triggers when the bearing changes, it sets the current bearing and sends an updated context to the provider
 */
@Override
public void onBearingChanged(double bearing) {
    this.bearing = bearing;
    mBearingProvider.setContext(this);

    ImageView image = (ImageView) findViewById(R.id.ivCompass);

    // create a rotation animation (reverse turn degree degrees)
    if (bearing < 0) {
        bearing += 360;
    }
    RotateAnimation ra = new RotateAnimation((float)currentBearing,(float)-bearing, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f);

    // how long the animation will take place
    ra.setDuration(210);

    // set the animation after the end of the reservation status
    ra.setFillAfter(true);

    // Start the animation
    image.startAnimation(ra);
    currentBearing = -bearing;
    mBearingProvider.setContext(this);
}

//endregion
}

编辑2:

我对onBearingChanged方法进行了一些小改动,现在指南针仍然可见,但认为它是不可见的,因为我的新if语句不能移动

@Override
public void onBearingChanged(double bearing) {
    this.bearing = bearing;
    mBearingProvider.setContext(this);

    ImageView image = (ImageView) findViewById(R.id.ivCompass);
    if (image.getVisibility() == View.VISIBLE) {

        // create a rotation animation (reverse turn degree degrees)
        if (bearing < 0) {
            bearing += 360;
        }
        RotateAnimation ra = new RotateAnimation((float) currentBearing, (float) -bearing, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        // how long the animation will take place
        ra.setDuration(210);

        // set the animation after the end of the reservation status
        ra.setFillAfter(true);

        // Start the animation
        image.startAnimation(ra);
        currentBearing = -bearing;
    }
    mBearingProvider.setContext(this);
}

1 个答案:

答案 0 :(得分:2)

如果你有某种动画,那么动画可能会对调用隐身进行干预。在调用INVISIBLE之前尝试使用它:

findViewById(R.id.ivCompass).clearAnimation();

希望它有所帮助。