From cd69904e59cd6216cd0394743a7a35da28716533 Mon Sep 17 00:00:00 2001 From: Florent CHAMPIGNY Date: Mon, 16 Jan 2017 11:39:34 +0100 Subject: [PATCH] Added buttons --- README.md | 10 +++- .../camerafragment/sample/MainActivity.java | 5 -- app/src/main/res/layout/activity_fragment.xml | 31 ++++++----- app/src/main/res/layout/sample.xml | 49 ++++++++++++++++++ .../configuration/Configuration.java | 11 ---- .../internal/manager/impl/Camera1Manager.java | 30 +++++------ .../internal/manager/impl/Camera2Manager.java | 47 +++++++++-------- .../widgets/CameraSettingsView.java | 15 +++++- .../widgets/CameraSwitchView.java | 2 + .../widgets/FlashSwitchView.java | 1 + .../widgets/MediaActionSwitchView.java | 2 + .../camerafragment/widgets/RecordButton.java | 2 + media/buttons.png | Bin 0 -> 20630 bytes 13 files changed, 134 insertions(+), 71 deletions(-) create mode 100644 app/src/main/res/layout/sample.xml create mode 100644 media/buttons.png diff --git a/README.md b/README.md index 165ce20..e632c95 100644 --- a/README.md +++ b/README.md @@ -115,4 +115,12 @@ cameraFragment.setStateListener(new CameraFragmentStateListener() { ## Text -CameraFragment can ping you with the current record duration with `CameraFragmentTextListener` \ No newline at end of file +CameraFragment can ping you with the current record duration with `CameraFragmentTextListener` + +# Widgets + +CameraFragment comes with some default views + +`RecordButton`, `MediaActionSwitchView`, `FlashSwitchView`, `CameraSwitchView`, `CameraSettingsView` + +[![png](https://raw.githubusercontent.com/florent37/CameraFragment/master/media/buttons.png)](https://github.com/florent37/CameraFragment) diff --git a/app/src/main/java/com/github/florent37/camerafragment/sample/MainActivity.java b/app/src/main/java/com/github/florent37/camerafragment/sample/MainActivity.java index b11812a..dae6bcc 100644 --- a/app/src/main/java/com/github/florent37/camerafragment/sample/MainActivity.java +++ b/app/src/main/java/com/github/florent37/camerafragment/sample/MainActivity.java @@ -302,11 +302,6 @@ public class MainActivity extends AppCompatActivity { } - - cameraSwitchView.displayBackCamera(); - flashSwitchView.displayFlashAuto(); - recordButton.displayPhotoState(); - mediaActionSwitchView.displayActionWillSwitchVideo(); } private CameraFragmentApi getCameraFragment() { diff --git a/app/src/main/res/layout/activity_fragment.xml b/app/src/main/res/layout/activity_fragment.xml index fc650d7..1a58d4e 100644 --- a/app/src/main/res/layout/activity_fragment.xml +++ b/app/src/main/res/layout/activity_fragment.xml @@ -15,6 +15,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="15dp" + tools:visibility="gone" android:text="Add camera" /> + /> + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true"> - - + + diff --git a/app/src/main/res/layout/sample.xml b/app/src/main/res/layout/sample.xml new file mode 100644 index 0000000..6c82f39 --- /dev/null +++ b/app/src/main/res/layout/sample.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/configuration/Configuration.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/configuration/Configuration.java index 7f861de..9d2fd34 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/configuration/Configuration.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/configuration/Configuration.java @@ -45,17 +45,6 @@ public final class Configuration implements Serializable { public static final int FLASH_MODE_OFF = 2; public static final int FLASH_MODE_AUTO = 3; - public interface Arguments { - String REQUEST_CODE = "io.memfis19.annca.request_code"; - String MEDIA_ACTION = "io.memfis19.annca.media_action"; - String MEDIA_QUALITY = "io.memfis19.annca.camera_media_quality"; - String VIDEO_DURATION = "io.memfis19.annca.video_duration"; - String MINIMUM_VIDEO_DURATION = "io.memfis19.annca.minimum.video_duration"; - String VIDEO_FILE_SIZE = "io.memfis19.annca.camera_video_file_size"; - String FLASH_MODE = "io.memfis19.annca.camera_flash_mode"; - String FILE_PATH = "io.memfis19.annca.camera_video_file_path"; - } - @IntDef({MEDIA_QUALITY_AUTO, MEDIA_QUALITY_LOWEST, MEDIA_QUALITY_LOW, MEDIA_QUALITY_MEDIUM, MEDIA_QUALITY_HIGH, MEDIA_QUALITY_HIGHEST}) @Retention(RetentionPolicy.SOURCE) public @interface MediaQuality { diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera1Manager.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera1Manager.java index 19a8895..7cc96ec 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera1Manager.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera1Manager.java @@ -230,7 +230,7 @@ public class Camera1Manager extends BaseCameraManager previewSizes = Size.fromList(camera.getParameters().getSupportedPreviewSizes()); - List pictureSizes = Size.fromList(camera.getParameters().getSupportedPictureSizes()); + final List previewSizes = Size.fromList(camera.getParameters().getSupportedPreviewSizes()); + final List pictureSizes = Size.fromList(camera.getParameters().getSupportedPictureSizes()); List videoSizes; if (Build.VERSION.SDK_INT > 10) videoSizes = Size.fromList(camera.getParameters().getSupportedVideoSizes()); @@ -360,11 +360,11 @@ public class Camera1Manager extends BaseCameraManager videoQualities = new ArrayList<>(); + final List videoQualities = new ArrayList<>(); if (configurationProvider.getMinimumVideoDuration() > 0) videoQualities.add(new VideoQualityOption(Configuration.MEDIA_QUALITY_AUTO, CameraHelper.getCamcorderProfile(Configuration.MEDIA_QUALITY_AUTO, getCurrentCameraId()), configurationProvider.getMinimumVideoDuration())); @@ -599,7 +599,7 @@ public class Camera1Manager extends BaseCameraManager photoQualities = new ArrayList<>(); + final List photoQualities = new ArrayList<>(); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_HIGHEST, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_HIGHEST))); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_HIGH, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_HIGH))); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_MEDIUM, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_MEDIUM))); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_LOWEST, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_LOWEST))); - CharSequence[] array = new CharSequence[photoQualities.size()]; + final CharSequence[] array = new CharSequence[photoQualities.size()]; photoQualities.toArray(array); return array; diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera2Manager.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera2Manager.java index 7050044..4674f92 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera2Manager.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/internal/manager/impl/Camera2Manager.java @@ -122,8 +122,7 @@ public final class Camera2Manager extends BaseCameraManager surfaces = new ArrayList<>(); + final List surfaces = new ArrayList<>(); - Surface previewSurface = workingSurface; + final Surface previewSurface = workingSurface; surfaces.add(previewSurface); previewRequestBuilder.addTarget(previewSurface); @@ -406,7 +405,7 @@ public final class Camera2Manager extends BaseCameraManager videoQualities = new ArrayList<>(); + final List videoQualities = new ArrayList<>(); if (configurationProvider.getMinimumVideoDuration() > 0) videoQualities.add(new VideoQualityOption(Configuration.MEDIA_QUALITY_AUTO, CameraHelper.getCamcorderProfile(Configuration.MEDIA_QUALITY_AUTO, getCurrentCameraId()), configurationProvider.getMinimumVideoDuration())); @@ -809,13 +810,13 @@ public final class Camera2Manager extends BaseCameraManager photoQualities = new ArrayList<>(); + final List photoQualities = new ArrayList<>(); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_HIGHEST, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_HIGHEST))); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_HIGH, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_HIGH))); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_MEDIUM, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_MEDIUM))); photoQualities.add(new PhotoQualityOption(Configuration.MEDIA_QUALITY_LOWEST, getPhotoSizeForQuality(Configuration.MEDIA_QUALITY_LOWEST))); - CharSequence[] array = new CharSequence[photoQualities.size()]; + final CharSequence[] array = new CharSequence[photoQualities.size()]; photoQualities.toArray(array); return array; diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSettingsView.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSettingsView.java index aa4e9ed..b0691cb 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSettingsView.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSettingsView.java @@ -6,25 +6,36 @@ import android.os.Build; import android.util.AttributeSet; import android.widget.ImageButton; +import com.github.florent37.camerafragment.R; + /** * Created by memfis on 8/23/16. */ public class CameraSettingsView extends ImageButton { + public CameraSettingsView(Context context) { - super(context); + this(context, null); } public CameraSettingsView(Context context, AttributeSet attrs) { - super(context, attrs); + this(context, attrs, 0); } public CameraSettingsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); + init(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public CameraSettingsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + private void init() { + setBackgroundResource(R.drawable.circle_frame_background_dark); + setImageResource(R.drawable.ic_settings_white_24dp); + setScaleType(ScaleType.CENTER); } @Override diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSwitchView.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSwitchView.java index c07797f..aa4ff37 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSwitchView.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/CameraSwitchView.java @@ -50,6 +50,8 @@ public class CameraSwitchView extends AppCompatImageButton { padding = Utils.convertDipToPixels(context, padding); setPadding(padding, padding, padding, padding); + + displayBackCamera(); } public void displayFrontCamera() { diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/FlashSwitchView.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/FlashSwitchView.java index fd1ef47..d6865e0 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/FlashSwitchView.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/FlashSwitchView.java @@ -37,6 +37,7 @@ public class FlashSwitchView extends ImageButton { private void init() { setBackgroundColor(Color.TRANSPARENT); + displayFlashAuto(); } public void displayFlashOff() { diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/MediaActionSwitchView.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/MediaActionSwitchView.java index 3a92f96..ba5de5b 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/MediaActionSwitchView.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/MediaActionSwitchView.java @@ -67,6 +67,8 @@ public class MediaActionSwitchView extends ImageButton { padding = Utils.convertDipToPixels(context, padding); setPadding(padding, padding, padding, padding); + + displayActionWillSwitchVideo(); } public void displayActionWillSwitchPhoto(){ diff --git a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/RecordButton.java b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/RecordButton.java index 8630bc3..ebdb85f 100644 --- a/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/RecordButton.java +++ b/camerafragment/src/main/java/com/github/florent37/camerafragment/widgets/RecordButton.java @@ -68,6 +68,8 @@ public class RecordButton extends ImageButton { }); setSoundEffectsEnabled(false); setIconPadding(iconPadding); + + displayPhotoState(); } //public void setup(@Configuration.MediaAction int mediaAction) { diff --git a/media/buttons.png b/media/buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..e8ed7c41297387c20df13fc116d105c08996b2d1 GIT binary patch literal 20630 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