New demo app (#53)
* New demo app * UI fixes * Refactor preview activities * Add gestures controlpull/54/head
parent
f8d38e3c8c
commit
5964080db4
@ -1,39 +0,0 @@ |
||||
package com.otaliastudios.cameraview.demo; |
||||
|
||||
import android.content.Context; |
||||
import android.support.v7.widget.AppCompatEditText; |
||||
import android.util.AttributeSet; |
||||
import android.view.KeyEvent; |
||||
import android.view.inputmethod.InputMethodManager; |
||||
|
||||
public class AutoUnfocusEditText extends AppCompatEditText { |
||||
|
||||
public AutoUnfocusEditText(Context context) { |
||||
super(context); |
||||
} |
||||
|
||||
public AutoUnfocusEditText(Context context, AttributeSet attrs) { |
||||
super(context, attrs); |
||||
} |
||||
|
||||
public AutoUnfocusEditText(Context context, AttributeSet attrs, int defStyleAttr) { |
||||
super(context, attrs, defStyleAttr); |
||||
} |
||||
|
||||
@Override |
||||
public boolean onKeyPreIme(int keyCode, KeyEvent event) { |
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { |
||||
closeKeyboard(); |
||||
clearFocus(); |
||||
return true; |
||||
} |
||||
|
||||
return super.dispatchKeyEvent(event); |
||||
} |
||||
|
||||
private void closeKeyboard() { |
||||
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); |
||||
imm.hideSoftInputFromWindow(getWindowToken(), 0); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,211 @@ |
||||
package com.otaliastudios.cameraview.demo; |
||||
|
||||
import android.content.Intent; |
||||
import android.content.pm.PackageManager; |
||||
import android.net.Uri; |
||||
import android.os.Bundle; |
||||
import android.support.annotation.NonNull; |
||||
import android.support.design.widget.BottomSheetBehavior; |
||||
import android.support.v7.app.AppCompatActivity; |
||||
import android.util.Log; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.view.ViewTreeObserver; |
||||
import android.widget.Toast; |
||||
|
||||
import com.otaliastudios.cameraview.Audio; |
||||
import com.otaliastudios.cameraview.CameraListener; |
||||
import com.otaliastudios.cameraview.CameraLogger; |
||||
import com.otaliastudios.cameraview.CameraOptions; |
||||
import com.otaliastudios.cameraview.CameraView; |
||||
import com.otaliastudios.cameraview.Flash; |
||||
import com.otaliastudios.cameraview.Grid; |
||||
import com.otaliastudios.cameraview.SessionType; |
||||
import com.otaliastudios.cameraview.Size; |
||||
import com.otaliastudios.cameraview.VideoQuality; |
||||
import com.otaliastudios.cameraview.WhiteBalance; |
||||
|
||||
import java.io.File; |
||||
|
||||
|
||||
public class CameraActivity extends AppCompatActivity implements View.OnClickListener, ControlView.Callback { |
||||
|
||||
private CameraView camera; |
||||
private ViewGroup controlPanel; |
||||
|
||||
private boolean mCapturingPicture; |
||||
private boolean mCapturingVideo; |
||||
|
||||
// To show stuff in the callback
|
||||
private Size mCaptureNativeSize; |
||||
private long mCaptureTime; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.activity_camera); |
||||
CameraLogger.setLogLevel(CameraLogger.LEVEL_VERBOSE); |
||||
|
||||
camera = findViewById(R.id.camera); |
||||
camera.addCameraListener(new CameraListener() { |
||||
public void onCameraOpened(CameraOptions options) { onOpened(); } |
||||
public void onPictureTaken(byte[] jpeg) { onPicture(jpeg); } |
||||
public void onVideoTaken(File video) { onVideo(video); } |
||||
}); |
||||
|
||||
findViewById(R.id.edit).setOnClickListener(this); |
||||
findViewById(R.id.capturePhoto).setOnClickListener(this); |
||||
findViewById(R.id.captureVideo).setOnClickListener(this); |
||||
findViewById(R.id.toggleCamera).setOnClickListener(this); |
||||
|
||||
controlPanel = findViewById(R.id.controls); |
||||
ViewGroup group = (ViewGroup) controlPanel.getChildAt(0); |
||||
Control[] controls = Control.values(); |
||||
for (Control control : controls) { |
||||
ControlView view = new ControlView(this, control, this); |
||||
group.addView(view, ViewGroup.LayoutParams.MATCH_PARENT, |
||||
ViewGroup.LayoutParams.WRAP_CONTENT); |
||||
} |
||||
|
||||
controlPanel.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { |
||||
@Override |
||||
public void onGlobalLayout() { |
||||
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel); |
||||
b.setState(BottomSheetBehavior.STATE_HIDDEN); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void message(String content, boolean important) { |
||||
int length = important ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT; |
||||
Toast.makeText(this, content, length).show(); |
||||
} |
||||
|
||||
private void onOpened() { |
||||
ViewGroup group = (ViewGroup) controlPanel.getChildAt(0); |
||||
for (int i = 0; i < group.getChildCount(); i++) { |
||||
ControlView view = (ControlView) group.getChildAt(i); |
||||
view.onCameraOpened(camera); |
||||
} |
||||
} |
||||
|
||||
private void onPicture(byte[] jpeg) { |
||||
mCapturingPicture = false; |
||||
long callbackTime = System.currentTimeMillis(); |
||||
if (mCapturingVideo) { |
||||
message("Captured while taking video. Size="+mCaptureNativeSize, false); |
||||
return; |
||||
} |
||||
|
||||
// This can happen if picture was taken with a gesture.
|
||||
if (mCaptureTime == 0) mCaptureTime = callbackTime - 300; |
||||
if (mCaptureNativeSize == null) mCaptureNativeSize = camera.getCaptureSize(); |
||||
|
||||
PicturePreviewActivity.setImage(jpeg); |
||||
Intent intent = new Intent(CameraActivity.this, PicturePreviewActivity.class); |
||||
intent.putExtra("delay", callbackTime - mCaptureTime); |
||||
intent.putExtra("nativeWidth", mCaptureNativeSize.getWidth()); |
||||
intent.putExtra("nativeHeight", mCaptureNativeSize.getHeight()); |
||||
startActivity(intent); |
||||
|
||||
mCaptureTime = 0; |
||||
mCaptureNativeSize = null; |
||||
} |
||||
|
||||
private void onVideo(File video) { |
||||
mCapturingVideo = false; |
||||
Intent intent = new Intent(CameraActivity.this, VideoPreviewActivity.class); |
||||
intent.putExtra("video", Uri.fromFile(video)); |
||||
startActivity(intent); |
||||
} |
||||
|
||||
@Override |
||||
public void onClick(View view) { |
||||
switch (view.getId()) { |
||||
case R.id.edit: edit(); break; |
||||
case R.id.capturePhoto: capturePhoto(); break; |
||||
case R.id.captureVideo: captureVideo(); break; |
||||
case R.id.toggleCamera: toggleCamera(); break; |
||||
} |
||||
} |
||||
|
||||
private void edit() { |
||||
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel); |
||||
b.setState(BottomSheetBehavior.STATE_COLLAPSED); |
||||
} |
||||
|
||||
private void capturePhoto() { |
||||
if (mCapturingPicture) return; |
||||
mCapturingPicture = true; |
||||
mCaptureTime = System.currentTimeMillis(); |
||||
mCaptureNativeSize = camera.getCaptureSize(); |
||||
message("Capturing picture...", false); |
||||
camera.capturePicture(); |
||||
} |
||||
|
||||
private void captureVideo() { |
||||
if (camera.getSessionType() != SessionType.VIDEO) { |
||||
message("Can't record video while session type is 'picture'.", false); |
||||
return; |
||||
} |
||||
if (mCapturingPicture || mCapturingVideo) return; |
||||
mCapturingVideo = true; |
||||
message("Recording for 8 seconds...", true); |
||||
camera.startCapturingVideo(null, 8000); |
||||
} |
||||
|
||||
private void toggleCamera() { |
||||
if (mCapturingPicture) return; |
||||
switch (camera.toggleFacing()) { |
||||
case BACK: |
||||
message("Switched to back camera!", false); |
||||
break; |
||||
|
||||
case FRONT: |
||||
message("Switched to front camera!", false); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onValueChanged(Control control, Object value, String name) { |
||||
control.applyValue(camera, value); |
||||
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel); |
||||
b.setState(BottomSheetBehavior.STATE_HIDDEN); |
||||
message("Changed " + control.getName() + " to " + name, false); |
||||
} |
||||
|
||||
//region Boilerplate
|
||||
|
||||
@Override |
||||
protected void onResume() { |
||||
super.onResume(); |
||||
camera.start(); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPause() { |
||||
super.onPause(); |
||||
camera.stop(); |
||||
} |
||||
|
||||
@Override |
||||
protected void onDestroy() { |
||||
super.onDestroy(); |
||||
camera.destroy(); |
||||
} |
||||
|
||||
@Override |
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { |
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults); |
||||
boolean valid = true; |
||||
for (int grantResult : grantResults) { |
||||
valid = valid && grantResult == PackageManager.PERMISSION_GRANTED; |
||||
} |
||||
if (valid && !camera.isStarted()) { |
||||
camera.start(); |
||||
} |
||||
} |
||||
|
||||
//endregion
|
||||
} |
@ -0,0 +1,176 @@ |
||||
package com.otaliastudios.cameraview.demo; |
||||
|
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
|
||||
import com.otaliastudios.cameraview.Audio; |
||||
import com.otaliastudios.cameraview.CameraOptions; |
||||
import com.otaliastudios.cameraview.CameraView; |
||||
import com.otaliastudios.cameraview.Flash; |
||||
import com.otaliastudios.cameraview.Gesture; |
||||
import com.otaliastudios.cameraview.GestureAction; |
||||
import com.otaliastudios.cameraview.Grid; |
||||
import com.otaliastudios.cameraview.SessionType; |
||||
import com.otaliastudios.cameraview.VideoQuality; |
||||
import com.otaliastudios.cameraview.WhiteBalance; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Controls that we want to display in a ControlView. |
||||
*/ |
||||
public enum Control { |
||||
|
||||
WIDTH("Width", false), |
||||
HEIGHT("Height", true), |
||||
SESSION("Session type", false), |
||||
CROP_OUTPUT("Crop output", true), |
||||
FLASH("Flash", false), |
||||
WHITE_BALANCE("White balance", false), |
||||
GRID("Grid", true), |
||||
VIDEO_QUALITY("Video quality", false), |
||||
AUDIO("Audio", true), |
||||
PINCH("Pinch gesture", false), |
||||
HSCROLL("Horizontal scroll gesture", false), |
||||
VSCROLL("Vertical scroll gesture", false), |
||||
TAP("Single tap gesture", false), |
||||
LONG_TAP("Long tap gesture", true); |
||||
|
||||
private String name; |
||||
private boolean last; |
||||
|
||||
Control(String n, boolean l) { |
||||
name = n; |
||||
last = l; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public boolean isSectionLast() { |
||||
return last; |
||||
} |
||||
|
||||
public Collection<?> getValues(CameraView view) { |
||||
CameraOptions options = view.getCameraOptions(); |
||||
switch (this) { |
||||
case WIDTH: |
||||
case HEIGHT: |
||||
View root = (View) view.getParent(); |
||||
ArrayList<Integer> list = new ArrayList<>(); |
||||
int boundary = this == WIDTH ? root.getWidth() : root.getHeight(); |
||||
if (boundary == 0) boundary = 1000; |
||||
int step = boundary / 10; |
||||
list.add(ViewGroup.LayoutParams.WRAP_CONTENT); |
||||
list.add(ViewGroup.LayoutParams.MATCH_PARENT); |
||||
for (int i = step; i < boundary; i += step) { |
||||
list.add(i); |
||||
} |
||||
return list; |
||||
case SESSION: return Arrays.asList(SessionType.values()); |
||||
case CROP_OUTPUT: return Arrays.asList(true, false); |
||||
case FLASH: return options.getSupportedFlash(); |
||||
case WHITE_BALANCE: return options.getSupportedWhiteBalance(); |
||||
case GRID: return Arrays.asList(Grid.values()); |
||||
case VIDEO_QUALITY: return Arrays.asList(VideoQuality.values()); |
||||
case AUDIO: return Arrays.asList(Audio.values()); |
||||
case PINCH: |
||||
case HSCROLL: |
||||
case VSCROLL: |
||||
ArrayList<GestureAction> list1 = new ArrayList<>(); |
||||
addIfSupported(options, list1, GestureAction.NONE); |
||||
addIfSupported(options, list1, GestureAction.ZOOM); |
||||
addIfSupported(options, list1, GestureAction.EXPOSURE_CORRECTION); |
||||
return list1; |
||||
case TAP: |
||||
case LONG_TAP: |
||||
ArrayList<GestureAction> list2 = new ArrayList<>(); |
||||
addIfSupported(options, list2, GestureAction.NONE); |
||||
addIfSupported(options, list2, GestureAction.CAPTURE); |
||||
addIfSupported(options, list2, GestureAction.FOCUS); |
||||
addIfSupported(options, list2, GestureAction.FOCUS_WITH_MARKER); |
||||
return list2; |
||||
|
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private void addIfSupported(CameraOptions options, List<GestureAction> list, GestureAction value) { |
||||
if (options.supports(value)) list.add(value); |
||||
} |
||||
|
||||
public Object getCurrentValue(CameraView view) { |
||||
switch (this) { |
||||
case WIDTH: return view.getLayoutParams().width; |
||||
case HEIGHT: return view.getLayoutParams().height; |
||||
case SESSION: return view.getSessionType(); |
||||
case CROP_OUTPUT: return view.getCropOutput(); |
||||
case FLASH: return view.getFlash(); |
||||
case WHITE_BALANCE: return view.getWhiteBalance(); |
||||
case GRID: return view.getGrid(); |
||||
case VIDEO_QUALITY: return view.getVideoQuality(); |
||||
case AUDIO: return view.getAudio(); |
||||
case PINCH: return view.getGestureAction(Gesture.PINCH); |
||||
case HSCROLL: return view.getGestureAction(Gesture.SCROLL_HORIZONTAL); |
||||
case VSCROLL: return view.getGestureAction(Gesture.SCROLL_VERTICAL); |
||||
case TAP: return view.getGestureAction(Gesture.TAP); |
||||
case LONG_TAP: return view.getGestureAction(Gesture.LONG_TAP); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void applyValue(CameraView camera, Object value) { |
||||
switch (this) { |
||||
case WIDTH: |
||||
camera.getLayoutParams().width = (int) value; |
||||
camera.setLayoutParams(camera.getLayoutParams()); |
||||
break; |
||||
case HEIGHT: |
||||
camera.getLayoutParams().height = (int) value; |
||||
camera.setLayoutParams(camera.getLayoutParams()); |
||||
break; |
||||
case SESSION: |
||||
camera.setSessionType((SessionType) value); |
||||
break; |
||||
case CROP_OUTPUT: |
||||
camera.setCropOutput((boolean) value); |
||||
break; |
||||
case FLASH: |
||||
camera.setFlash((Flash) value); |
||||
break; |
||||
case WHITE_BALANCE: |
||||
camera.setWhiteBalance((WhiteBalance) value); |
||||
break; |
||||
case GRID: |
||||
camera.setGrid((Grid) value); |
||||
break; |
||||
case VIDEO_QUALITY: |
||||
camera.setVideoQuality((VideoQuality) value); |
||||
break; |
||||
case AUDIO: |
||||
camera.setAudio((Audio) value); |
||||
break; |
||||
case PINCH: |
||||
camera.mapGesture(Gesture.PINCH, (GestureAction) value); |
||||
break; |
||||
case HSCROLL: |
||||
camera.mapGesture(Gesture.SCROLL_HORIZONTAL, (GestureAction) value); |
||||
break; |
||||
case VSCROLL: |
||||
camera.mapGesture(Gesture.SCROLL_VERTICAL, (GestureAction) value); |
||||
break; |
||||
case TAP: |
||||
camera.mapGesture(Gesture.TAP, (GestureAction) value); |
||||
break; |
||||
case LONG_TAP: |
||||
camera.mapGesture(Gesture.LONG_TAP, (GestureAction) value); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,103 @@ |
||||
package com.otaliastudios.cameraview.demo; |
||||
|
||||
|
||||
import android.annotation.SuppressLint; |
||||
import android.content.Context; |
||||
import android.text.TextUtils; |
||||
import android.util.Log; |
||||
import android.util.TypedValue; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.widget.AdapterView; |
||||
import android.widget.ArrayAdapter; |
||||
import android.widget.LinearLayout; |
||||
import android.widget.RelativeLayout; |
||||
import android.widget.Spinner; |
||||
import android.widget.SpinnerAdapter; |
||||
import android.widget.TextView; |
||||
|
||||
import com.otaliastudios.cameraview.CameraOptions; |
||||
import com.otaliastudios.cameraview.CameraView; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
|
||||
public class ControlView<Value> extends LinearLayout implements Spinner.OnItemSelectedListener { |
||||
|
||||
interface Callback { |
||||
void onValueChanged(Control control, Object value, String name); |
||||
} |
||||
|
||||
private Value value; |
||||
private ArrayList<Value> values; |
||||
private ArrayList<String> valuesStrings; |
||||
private Control control; |
||||
private Callback callback; |
||||
private Spinner spinner; |
||||
|
||||
public ControlView(Context context, Control control, Callback callback) { |
||||
super(context); |
||||
this.control = control; |
||||
this.callback = callback; |
||||
setOrientation(VERTICAL); |
||||
|
||||
inflate(context, R.layout.control_view, this); |
||||
TextView title = findViewById(R.id.title); |
||||
title.setText(control.getName()); |
||||
View divider = findViewById(R.id.divider); |
||||
divider.setVisibility(control.isSectionLast() ? View.VISIBLE : View.GONE); |
||||
|
||||
ViewGroup content = findViewById(R.id.content); |
||||
spinner = new Spinner(context, Spinner.MODE_DROPDOWN); |
||||
content.addView(spinner); |
||||
} |
||||
|
||||
public Value getValue() { |
||||
return value; |
||||
} |
||||
|
||||
@SuppressWarnings("all") |
||||
public void onCameraOpened(CameraView view) { |
||||
values = new ArrayList(control.getValues(view)); |
||||
value = (Value) control.getCurrentValue(view); |
||||
valuesStrings = new ArrayList<>(); |
||||
for (Value value : values) { |
||||
valuesStrings.add(stringify(value)); |
||||
} |
||||
|
||||
if (values.isEmpty()) { |
||||
spinner.setOnItemSelectedListener(null); |
||||
spinner.setEnabled(false); |
||||
spinner.setAlpha(0.8f); |
||||
spinner.setAdapter(new ArrayAdapter(getContext(), |
||||
R.layout.spinner_text, new String[]{ "Not supported." })); |
||||
spinner.setSelection(0, false); |
||||
} else { |
||||
spinner.setEnabled(true); |
||||
spinner.setAlpha(1f); |
||||
spinner.setAdapter(new ArrayAdapter(getContext(), |
||||
R.layout.spinner_text, valuesStrings)); |
||||
spinner.setSelection(values.indexOf(value), false); |
||||
spinner.setOnItemSelectedListener(this); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { |
||||
if (values.get(i) != value) { |
||||
Log.e("ControlView", "curr: " + value + " new: " + values.get(i)); |
||||
callback.onValueChanged(control, values.get(i), valuesStrings.get(i)); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onNothingSelected(AdapterView<?> adapterView) {} |
||||
|
||||
private String stringify(Value value) { |
||||
if (value instanceof Integer) { |
||||
if ((Integer) value == ViewGroup.LayoutParams.MATCH_PARENT) return "match parent"; |
||||
if ((Integer) value == ViewGroup.LayoutParams.WRAP_CONTENT) return "wrap content"; |
||||
} |
||||
return String.valueOf(value).replace("_", " ").toLowerCase(); |
||||
} |
||||
} |
@ -1,375 +0,0 @@ |
||||
package com.otaliastudios.cameraview.demo; |
||||
|
||||
import android.content.Intent; |
||||
import android.location.Location; |
||||
import android.net.Uri; |
||||
import android.os.Bundle; |
||||
import android.support.v7.app.AppCompatActivity; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.view.ViewTreeObserver; |
||||
import android.widget.Button; |
||||
import android.widget.EditText; |
||||
import android.widget.RadioGroup; |
||||
import android.widget.TextView; |
||||
import android.widget.Toast; |
||||
|
||||
import com.otaliastudios.cameraview.CameraListener; |
||||
import com.otaliastudios.cameraview.CameraLogger; |
||||
import com.otaliastudios.cameraview.CameraView; |
||||
import com.otaliastudios.cameraview.Grid; |
||||
import com.otaliastudios.cameraview.SessionType; |
||||
import com.otaliastudios.cameraview.Size; |
||||
import com.otaliastudios.cameraview.VideoQuality; |
||||
|
||||
import java.io.File; |
||||
|
||||
import butterknife.BindView; |
||||
import butterknife.ButterKnife; |
||||
import butterknife.OnClick; |
||||
|
||||
public class MainActivity extends AppCompatActivity implements View.OnLayoutChangeListener { |
||||
|
||||
@BindView(R.id.activity_main) |
||||
ViewGroup parent; |
||||
|
||||
@BindView(R.id.camera) |
||||
CameraView camera; |
||||
|
||||
// Capture Mode:
|
||||
@BindView(R.id.sessionTypeRadioGroup) |
||||
RadioGroup sessionTypeRadioGroup; |
||||
|
||||
// Crop Mode:
|
||||
@BindView(R.id.cropModeRadioGroup) |
||||
RadioGroup cropModeRadioGroup; |
||||
|
||||
// Video Quality:
|
||||
@BindView(R.id.videoQualityRadioGroup) |
||||
RadioGroup videoQualityRadioGroup; |
||||
|
||||
// Grid mode:
|
||||
@BindView(R.id.gridModeRadioGroup) |
||||
RadioGroup gridModeRadioGroup; |
||||
|
||||
// Width:
|
||||
@BindView(R.id.screenWidth) |
||||
TextView screenWidth; |
||||
@BindView(R.id.width) |
||||
EditText width; |
||||
@BindView(R.id.widthUpdate) |
||||
Button widthUpdate; |
||||
@BindView(R.id.widthModeRadioGroup) |
||||
RadioGroup widthModeRadioGroup; |
||||
|
||||
// Height:
|
||||
@BindView(R.id.screenHeight) |
||||
TextView screenHeight; |
||||
@BindView(R.id.height) |
||||
EditText height; |
||||
@BindView(R.id.heightUpdate) |
||||
Button heightUpdate; |
||||
@BindView(R.id.heightModeRadioGroup) |
||||
RadioGroup heightModeRadioGroup; |
||||
|
||||
private boolean mCapturingPicture; |
||||
private boolean mCapturingVideo; |
||||
|
||||
// To show stuff in the callback
|
||||
private Size mCaptureNativeSize; |
||||
private long mCaptureTime; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.activity_main); |
||||
ButterKnife.bind(this); |
||||
CameraLogger.setLogLevel(CameraLogger.LEVEL_VERBOSE); |
||||
|
||||
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { |
||||
@Override |
||||
public void onGlobalLayout() { |
||||
screenWidth.setText("screen: " + parent.getWidth() + "px"); |
||||
screenHeight.setText("screen: " + parent.getHeight() + "px"); |
||||
} |
||||
}); |
||||
|
||||
sessionTypeRadioGroup.setOnCheckedChangeListener(sessionTypeChangedListener); |
||||
cropModeRadioGroup.setOnCheckedChangeListener(cropModeChangedListener); |
||||
widthModeRadioGroup.setOnCheckedChangeListener(widthModeChangedListener); |
||||
heightModeRadioGroup.setOnCheckedChangeListener(heightModeChangedListener); |
||||
videoQualityRadioGroup.setOnCheckedChangeListener(videoQualityChangedListener); |
||||
gridModeRadioGroup.setOnCheckedChangeListener(gridModeChangedListener); |
||||
|
||||
camera.addOnLayoutChangeListener(this); |
||||
camera.addCameraListener(new CameraListener() { |
||||
@Override |
||||
public void onPictureTaken(byte[] jpeg) { |
||||
super.onPictureTaken(jpeg); |
||||
mCapturingPicture = false; |
||||
long callbackTime = System.currentTimeMillis(); |
||||
if (mCapturingVideo) { |
||||
message("Captured while taking video. Size="+mCaptureNativeSize, false); |
||||
return; |
||||
} |
||||
PicturePreviewActivity.setImage(jpeg); |
||||
Intent intent = new Intent(MainActivity.this, PicturePreviewActivity.class); |
||||
intent.putExtra("delay", callbackTime - mCaptureTime); |
||||
intent.putExtra("nativeWidth", mCaptureNativeSize.getWidth()); |
||||
intent.putExtra("nativeHeight", mCaptureNativeSize.getHeight()); |
||||
startActivity(intent); |
||||
} |
||||
|
||||
@Override |
||||
public void onVideoTaken(File video) { |
||||
super.onVideoTaken(video); |
||||
mCapturingVideo = false; |
||||
Intent intent = new Intent(MainActivity.this, VideoPreviewActivity.class); |
||||
intent.putExtra("video", Uri.fromFile(video)); |
||||
startActivity(intent); |
||||
} |
||||
}); |
||||
|
||||
// Debug location.
|
||||
/* camera.postDelayed(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
message("set Location", false); |
||||
camera.setLocation(-20, 40.12345); |
||||
} |
||||
}, 4500); */ |
||||
} |
||||
|
||||
private void message(String content, boolean important) { |
||||
int length = important ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT; |
||||
Toast.makeText(this, content, length).show(); |
||||
} |
||||
|
||||
@Override |
||||
protected void onResume() { |
||||
super.onResume(); |
||||
camera.start(); |
||||
} |
||||
|
||||
@Override |
||||
protected void onPause() { |
||||
super.onPause(); |
||||
camera.stop(); |
||||
} |
||||
|
||||
@Override |
||||
protected void onDestroy() { |
||||
super.onDestroy(); |
||||
camera.destroy(); |
||||
} |
||||
|
||||
|
||||
@OnClick(R.id.capturePhoto) |
||||
void capturePhoto() { |
||||
if (mCapturingPicture) return; |
||||
mCapturingPicture = true; |
||||
mCaptureTime = System.currentTimeMillis(); |
||||
mCaptureNativeSize = camera.getCaptureSize(); |
||||
message("Capturing picture...", false); |
||||
camera.capturePicture(); |
||||
} |
||||
|
||||
@OnClick(R.id.captureVideo) |
||||
void captureVideo() { |
||||
if (camera.getSessionType() != SessionType.VIDEO) { |
||||
message("Can't record video while session type is 'picture'.", false); |
||||
return; |
||||
} |
||||
if (mCapturingPicture || mCapturingVideo) return; |
||||
mCapturingVideo = true; |
||||
message("Recording for 8 seconds...", true); |
||||
camera.startCapturingVideo(null, 8000); |
||||
} |
||||
|
||||
@OnClick(R.id.toggleCamera) |
||||
void toggleCamera() { |
||||
if (mCapturingPicture) return; |
||||
switch (camera.toggleFacing()) { |
||||
case BACK: |
||||
message("Switched to back camera!", false); |
||||
break; |
||||
|
||||
case FRONT: |
||||
message("Switched to front camera!", false); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
@OnClick(R.id.toggleFlash) |
||||
void toggleFlash() { |
||||
if (mCapturingPicture) return; |
||||
switch (camera.toggleFlash()) { |
||||
case ON: |
||||
message("Flash on!", false); |
||||
break; |
||||
|
||||
case OFF: |
||||
message("Flash off!", false); |
||||
break; |
||||
|
||||
case AUTO: |
||||
message("Flash auto!", false); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
RadioGroup.OnCheckedChangeListener sessionTypeChangedListener = new RadioGroup.OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(RadioGroup group, int checkedId) { |
||||
if (mCapturingPicture) return; |
||||
boolean pic = checkedId == R.id.sessionTypePicture; |
||||
camera.setSessionType(pic ? SessionType.PICTURE : SessionType.VIDEO); |
||||
message("Session type set to" + (pic ? " picture!" : " video!"), true); |
||||
} |
||||
}; |
||||
|
||||
RadioGroup.OnCheckedChangeListener cropModeChangedListener = new RadioGroup.OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(RadioGroup group, int checkedId) { |
||||
if (mCapturingPicture) return; |
||||
camera.setCropOutput(checkedId == R.id.modeCropVisible); |
||||
message("Picture cropping is" + (checkedId == R.id.modeCropVisible ? " on!" : " off!"), false); |
||||
} |
||||
}; |
||||
|
||||
RadioGroup.OnCheckedChangeListener videoQualityChangedListener = new RadioGroup.OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(RadioGroup group, int checkedId) { |
||||
if (mCapturingVideo) return; |
||||
VideoQuality videoQuality = VideoQuality.HIGHEST; |
||||
switch (checkedId) { |
||||
case R.id.videoQualityLowest: videoQuality = VideoQuality.LOWEST; break; |
||||
case R.id.videoQualityQvga: videoQuality = VideoQuality.MAX_QVGA; break; |
||||
case R.id.videoQuality480p: videoQuality = VideoQuality.MAX_480P; break; |
||||
case R.id.videoQuality720p: videoQuality = VideoQuality.MAX_720P; break; |
||||
case R.id.videoQuality1080p: videoQuality = VideoQuality.MAX_1080P; break; |
||||
case R.id.videoQuality2160p: videoQuality = VideoQuality.MAX_2160P; break; |
||||
case R.id.videoQualityHighest: videoQuality = VideoQuality.HIGHEST; break; |
||||
} |
||||
camera.setVideoQuality(videoQuality); |
||||
message("Video quality changed!", false); |
||||
} |
||||
}; |
||||
|
||||
|
||||
RadioGroup.OnCheckedChangeListener gridModeChangedListener = new RadioGroup.OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(RadioGroup group, int checkedId) { |
||||
Grid grid = Grid.OFF; |
||||
switch (checkedId) { |
||||
case R.id.gridModeOff: grid = Grid.OFF; break; |
||||
case R.id.gridMode3x3: grid = Grid.DRAW_3X3; break; |
||||
case R.id.gridMode4x4: grid = Grid.DRAW_4X4; break; |
||||
case R.id.gridModeGolden: grid = Grid.DRAW_PHI; break; |
||||
} |
||||
camera.setGrid(grid); |
||||
message("Grid mode changed!", false); |
||||
} |
||||
}; |
||||
|
||||
|
||||
@OnClick(R.id.widthUpdate) |
||||
void widthUpdateClicked() { |
||||
if (mCapturingPicture) return; |
||||
if (widthUpdate.getAlpha() >= 1) { |
||||
updateCamera(true, false); |
||||
} |
||||
} |
||||
|
||||
RadioGroup.OnCheckedChangeListener widthModeChangedListener = new RadioGroup.OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(RadioGroup group, int checkedId) { |
||||
if (mCapturingPicture) return; |
||||
widthUpdate.setEnabled(checkedId == R.id.widthCustom); |
||||
widthUpdate.setAlpha(checkedId == R.id.widthCustom ? 1f : 0.3f); |
||||
width.clearFocus(); |
||||
width.setEnabled(checkedId == R.id.widthCustom); |
||||
width.setAlpha(checkedId == R.id.widthCustom ? 1f : 0.5f); |
||||
|
||||
updateCamera(true, false); |
||||
} |
||||
}; |
||||
|
||||
@OnClick(R.id.heightUpdate) |
||||
void heightUpdateClicked() { |
||||
if (mCapturingPicture) return; |
||||
if (heightUpdate.getAlpha() >= 1) { |
||||
updateCamera(false, true); |
||||
} |
||||
} |
||||
|
||||
RadioGroup.OnCheckedChangeListener heightModeChangedListener = new RadioGroup.OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(RadioGroup group, int checkedId) { |
||||
if (mCapturingPicture) return; |
||||
heightUpdate.setEnabled(checkedId == R.id.heightCustom); |
||||
heightUpdate.setAlpha(checkedId == R.id.heightCustom ? 1f : 0.3f); |
||||
height.clearFocus(); |
||||
height.setEnabled(checkedId == R.id.heightCustom); |
||||
height.setAlpha(checkedId == R.id.heightCustom ? 1f : 0.5f); |
||||
|
||||
updateCamera(false, true); |
||||
} |
||||
}; |
||||
|
||||
private void updateCamera(boolean updateWidth, boolean updateHeight) { |
||||
if (mCapturingPicture) return; |
||||
ViewGroup.LayoutParams cameraLayoutParams = camera.getLayoutParams(); |
||||
int width = cameraLayoutParams.width; |
||||
int height = cameraLayoutParams.height; |
||||
|
||||
if (updateWidth) { |
||||
switch (widthModeRadioGroup.getCheckedRadioButtonId()) { |
||||
case R.id.widthCustom: |
||||
String widthInput = this.width.getText().toString(); |
||||
try { width = Integer.valueOf(widthInput); } catch (Exception e) {} |
||||
break; |
||||
case R.id.widthWrapContent: |
||||
width = ViewGroup.LayoutParams.WRAP_CONTENT; |
||||
break; |
||||
case R.id.widthMatchParent: |
||||
width = ViewGroup.LayoutParams.MATCH_PARENT; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (updateHeight) { |
||||
switch (heightModeRadioGroup.getCheckedRadioButtonId()) { |
||||
case R.id.heightCustom: |
||||
String heightInput = this.height.getText().toString(); |
||||
try { height = Integer.valueOf(heightInput); } catch (Exception e) {} |
||||
break; |
||||
case R.id.heightWrapContent: |
||||
height = ViewGroup.LayoutParams.WRAP_CONTENT; |
||||
break; |
||||
case R.id.heightMatchParent: |
||||
// We are in a vertically scrolling container, match parent would not work at all.
|
||||
height = parent.getHeight(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
cameraLayoutParams.width = width; |
||||
cameraLayoutParams.height = height; |
||||
camera.addOnLayoutChangeListener(this); |
||||
camera.setLayoutParams(cameraLayoutParams); |
||||
|
||||
String what = (updateWidth && updateHeight ? "Width and height" : updateWidth ? "Width" : "Height"); |
||||
message(what + " updated! Internal preview size: " + camera.getPreviewSize(), false); |
||||
} |
||||
|
||||
@Override |
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { |
||||
int mCameraWidth = right - left; |
||||
int mCameraHeight = bottom - top; |
||||
width.setText(String.valueOf(mCameraWidth)); |
||||
height.setText(String.valueOf(mCameraHeight)); |
||||
camera.removeOnLayoutChangeListener(this); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,50 @@ |
||||
package com.otaliastudios.cameraview.demo; |
||||
|
||||
|
||||
import android.content.Context; |
||||
import android.support.annotation.Nullable; |
||||
import android.util.AttributeSet; |
||||
import android.util.Log; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.widget.AdapterView; |
||||
import android.widget.ArrayAdapter; |
||||
import android.widget.LinearLayout; |
||||
import android.widget.Spinner; |
||||
import android.widget.TextView; |
||||
|
||||
import com.otaliastudios.cameraview.CameraView; |
||||
|
||||
import java.util.ArrayList; |
||||
|
||||
public class MessageView extends LinearLayout { |
||||
|
||||
private TextView message; |
||||
private TextView title; |
||||
|
||||
public MessageView(Context context) { |
||||
this(context, null); |
||||
} |
||||
|
||||
public MessageView(Context context, @Nullable AttributeSet attrs) { |
||||
this(context, attrs, 0); |
||||
} |
||||
|
||||
public MessageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
||||
super(context, attrs, defStyleAttr); |
||||
setOrientation(VERTICAL); |
||||
inflate(context, R.layout.control_view, this); |
||||
ViewGroup content = findViewById(R.id.content); |
||||
inflate(context, R.layout.spinner_text, content); |
||||
title = findViewById(R.id.title); |
||||
message = (TextView) content.getChildAt(0); |
||||
} |
||||
|
||||
public void setTitle(String title) { |
||||
this.title.setText(title); |
||||
} |
||||
|
||||
public void setMessage(String message) { |
||||
this.message.setText(message); |
||||
} |
||||
} |
@ -1,6 +1,6 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<solid android:color="@color/colorPrimary"/> |
||||
<corners android:radius="4dp"/> |
||||
<shape |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:shape="oval"> |
||||
<solid android:color="@color/colorAccent"/> |
||||
</shape> |
@ -0,0 +1,100 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<android.support.design.widget.CoordinatorLayout |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:id="@+id/root" |
||||
android:background="#FF444444" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<!-- Camera --> |
||||
<com.otaliastudios.cameraview.CameraView |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:id="@+id/camera" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center" |
||||
android:keepScreenOn="true" |
||||
app:cameraGrid="off" |
||||
app:cameraCropOutput="false" |
||||
app:cameraFacing="back" |
||||
app:cameraFlash="off" |
||||
app:cameraAudio="on" |
||||
app:cameraGestureTap="focusWithMarker" |
||||
app:cameraGestureLongTap="none" |
||||
app:cameraGesturePinch="zoom" |
||||
app:cameraGestureScrollHorizontal="exposureCorrection" |
||||
app:cameraGestureScrollVertical="none" |
||||
app:cameraJpegQuality="100" |
||||
app:cameraSessionType="picture" /> |
||||
|
||||
<!-- Controls --> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="bottom" |
||||
android:padding="16dp" |
||||
android:orientation="horizontal" |
||||
android:weightSum="3"> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/edit" |
||||
android:layout_width="56dp" |
||||
android:layout_height="56dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_edit" /> |
||||
|
||||
<Space |
||||
android:layout_width="0dp" |
||||
android:layout_height="1dp" |
||||
android:layout_weight="1" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/capturePhoto" |
||||
android:layout_width="56dp" |
||||
android:layout_height="56dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_photo" /> |
||||
|
||||
<Space |
||||
android:layout_width="0dp" |
||||
android:layout_height="1dp" |
||||
android:layout_weight="1" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/captureVideo" |
||||
android:layout_width="56dp" |
||||
android:layout_height="56dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_video" /> |
||||
|
||||
<Space |
||||
android:layout_width="0dp" |
||||
android:layout_height="1dp" |
||||
android:layout_weight="1" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/toggleCamera" |
||||
android:layout_width="56dp" |
||||
android:layout_height="56dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_switch" /> |
||||
</LinearLayout> |
||||
|
||||
<!-- Edit --> |
||||
<android.support.v4.widget.NestedScrollView |
||||
android:id="@+id/controls" |
||||
android:background="@android:color/white" |
||||
app:layout_behavior="@string/bottom_sheet_behavior" |
||||
app:behavior_hideable="true" |
||||
app:behavior_peekHeight="300dp" |
||||
app:behavior_skipCollapsed="false" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"> |
||||
<LinearLayout |
||||
android:orientation="vertical" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"/> |
||||
</android.support.v4.widget.NestedScrollView> |
||||
|
||||
</android.support.design.widget.CoordinatorLayout> |
@ -1,555 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:id="@+id/activity_main" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="@android:color/white" |
||||
android:descendantFocusability="beforeDescendants" |
||||
android:focusable="true" |
||||
android:focusableInTouchMode="true"> |
||||
<LinearLayout |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="vertical"> |
||||
|
||||
<!-- Camera --> |
||||
<RelativeLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"> |
||||
<com.otaliastudios.cameraview.CameraView |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:id="@+id/camera" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="400dp" |
||||
android:layout_gravity="center_horizontal" |
||||
android:keepScreenOn="true" |
||||
app:cameraGrid="off" |
||||
app:cameraCropOutput="false" |
||||
app:cameraFacing="back" |
||||
app:cameraFlash="off" |
||||
app:cameraAudio="on" |
||||
app:cameraGestureTap="focusWithMarker" |
||||
app:cameraGestureLongTap="none" |
||||
app:cameraGesturePinch="zoom" |
||||
app:cameraGestureScrollHorizontal="exposureCorrection" |
||||
app:cameraGestureScrollVertical="none" |
||||
app:cameraJpegQuality="100" |
||||
app:cameraSessionType="picture" /> |
||||
</RelativeLayout> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="vertical" |
||||
android:padding="16dp"> |
||||
|
||||
<!-- Controls --> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal" |
||||
android:weightSum="4"> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/capturePhoto" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="10dp" |
||||
android:layout_weight="1" |
||||
android:padding="8dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_photo" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/captureVideo" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="10dp" |
||||
android:layout_weight="1" |
||||
android:padding="8dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_video" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/toggleFlash" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="10dp" |
||||
android:layout_weight="1" |
||||
android:padding="8dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_flash" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/toggleCamera" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="10dp" |
||||
android:layout_weight="1" |
||||
android:padding="8dp" |
||||
android:background="@drawable/background" |
||||
app:srcCompat="@drawable/ic_switch" /> |
||||
|
||||
</LinearLayout> |
||||
|
||||
<!-- Session type --> |
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="16dp"> |
||||
|
||||
<View |
||||
android:layout_width="2.5dp" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorPrimary" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="SESSION TYPE" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
<RadioGroup |
||||
android:id="@+id/sessionTypeRadioGroup" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="4dp" |
||||
android:checkedButton="@+id/sessionTypePicture" |
||||
android:orientation="horizontal"> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/sessionTypePicture" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="Picture" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/sessionTypeVideo" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="Video" /> |
||||
|
||||
</RadioGroup> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<!-- Crop output --> |
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="16dp"> |
||||
|
||||
<View |
||||
android:layout_width="2.5dp" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorPrimary" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="CROP OUTPUT" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
<RadioGroup |
||||
android:id="@+id/cropModeRadioGroup" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="4dp" |
||||
android:checkedButton="@+id/modeCropFullSize" |
||||
android:orientation="horizontal"> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/modeCropFullSize" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="Off" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/modeCropVisible" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="On" /> |
||||
|
||||
</RadioGroup> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<!-- Width --> |
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="16dp"> |
||||
|
||||
<View |
||||
android:layout_width="2.5dp" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorPrimary" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:descendantFocusability="beforeDescendants" |
||||
android:focusable="true" |
||||
android:focusableInTouchMode="true" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="WIDTH" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/screenWidth" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="screen: 1080px" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="11sp" /> |
||||
|
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"> |
||||
|
||||
<com.otaliastudios.cameraview.demo.AutoUnfocusEditText |
||||
android:id="@+id/width" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginRight="120dp" |
||||
android:hint="pixels" |
||||
android:inputType="number" /> |
||||
|
||||
<Button |
||||
android:id="@+id/widthUpdate" |
||||
android:layout_width="90dp" |
||||
android:layout_height="40dp" |
||||
android:layout_gravity="center_vertical|right" |
||||
android:layout_marginRight="15dp" |
||||
android:background="@drawable/background" |
||||
android:gravity="center" |
||||
android:text="UPDATE" |
||||
android:stateListAnimator="@null" |
||||
android:textColor="@android:color/white" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<RadioGroup |
||||
android:id="@+id/widthModeRadioGroup" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="3dp" |
||||
android:checkedButton="@+id/widthCustom" |
||||
android:orientation="horizontal"> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/widthCustom" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="Custom" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/widthWrapContent" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="wrap_content" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/widthMatchParent" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="match_parent" /> |
||||
|
||||
</RadioGroup> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<!-- Height --> |
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="16dp"> |
||||
|
||||
<View |
||||
android:layout_width="2.5dp" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorPrimary" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:descendantFocusability="beforeDescendants" |
||||
android:focusable="true" |
||||
android:focusableInTouchMode="true" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="HEIGHT" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/screenHeight" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="screen: 1920px" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="11sp" /> |
||||
|
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"> |
||||
|
||||
<com.otaliastudios.cameraview.demo.AutoUnfocusEditText |
||||
android:id="@+id/height" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginRight="120dp" |
||||
android:hint="pixels" |
||||
android:inputType="number" /> |
||||
|
||||
<Button |
||||
android:id="@+id/heightUpdate" |
||||
android:layout_width="90dp" |
||||
android:layout_height="40dp" |
||||
android:layout_gravity="center_vertical|right" |
||||
android:layout_marginRight="15dp" |
||||
android:background="@drawable/background" |
||||
android:gravity="center" |
||||
android:text="UPDATE" |
||||
android:stateListAnimator="@null" |
||||
android:textColor="@android:color/white" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<RadioGroup |
||||
android:id="@+id/heightModeRadioGroup" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="3dp" |
||||
android:checkedButton="@+id/heightCustom" |
||||
android:orientation="horizontal"> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/heightCustom" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="Custom" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/heightWrapContent" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="wrap_content" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/heightMatchParent" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="match_parent" /> |
||||
|
||||
</RadioGroup> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<!-- Video Quality --> |
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="16dp"> |
||||
|
||||
<View |
||||
android:layout_width="2.5dp" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorPrimary" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="VIDEO QUALITY" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
<HorizontalScrollView |
||||
android:layout_marginTop="4dp" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"> |
||||
<RadioGroup |
||||
android:id="@+id/videoQualityRadioGroup" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:checkedButton="@+id/videoQuality480p" |
||||
android:orientation="horizontal"> |
||||
<RadioButton |
||||
android:id="@+id/videoQualityLowest" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="low" /> |
||||
<RadioButton |
||||
android:id="@+id/videoQualityQvga" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="QVGA" /> |
||||
<RadioButton |
||||
android:id="@+id/videoQuality480p" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="480p" /> |
||||
<RadioButton |
||||
android:id="@+id/videoQuality720p" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="720p" /> |
||||
<RadioButton |
||||
android:id="@+id/videoQuality1080p" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="1080p" /> |
||||
<RadioButton |
||||
android:id="@+id/videoQuality2160p" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="2160p" /> |
||||
<RadioButton |
||||
android:id="@+id/videoQualityHighest" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="high" /> |
||||
</RadioGroup> |
||||
</HorizontalScrollView> |
||||
|
||||
|
||||
</LinearLayout> |
||||
|
||||
</FrameLayout> |
||||
|
||||
<!-- Grid --> |
||||
<FrameLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="16dp"> |
||||
|
||||
<View |
||||
android:layout_width="2.5dp" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorPrimary" /> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="3dp" |
||||
android:text="GRID MODE" |
||||
android:textColor="@android:color/black" |
||||
android:textSize="14sp" |
||||
android:textStyle="bold" /> |
||||
|
||||
<RadioGroup |
||||
android:id="@+id/gridModeRadioGroup" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="4dp" |
||||
android:checkedButton="@+id/gridModeOff" |
||||
android:orientation="horizontal"> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/gridModeOff" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="Off" /> |
||||
|
||||
<RadioButton |
||||
android:id="@+id/gridMode3x3" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="3X3" /> |
||||
|
||||
|
||||
<RadioButton |
||||
android:id="@+id/gridMode4x4" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="4x4" /> |
||||
|
||||
|
||||
<RadioButton |
||||
android:id="@+id/gridModeGolden" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="10dp" |
||||
android:text="Golden ratio" /> |
||||
|
||||
</RadioGroup> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</FrameLayout> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</LinearLayout> |
||||
</ScrollView> |
@ -0,0 +1,31 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<merge |
||||
xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<TextView |
||||
style="@style/TextAppearance.AppCompat.Subhead" |
||||
android:id="@+id/title" |
||||
android:layout_marginTop="16dp" |
||||
android:paddingLeft="16dp" |
||||
android:paddingRight="16dp" |
||||
android:textStyle="bold" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" /> |
||||
|
||||
<FrameLayout |
||||
android:id="@+id/content" |
||||
android:paddingTop="4dp" |
||||
android:paddingLeft="8dp" |
||||
android:paddingRight="8dp" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"/> |
||||
|
||||
<View |
||||
android:id="@+id/divider" |
||||
android:layout_marginTop="8dp" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="1dp" |
||||
android:background="#44AAAAAA" /> |
||||
|
||||
|
||||
</merge> |
@ -0,0 +1,8 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<TextView |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
style="@style/TextAppearance.AppCompat.Medium" |
||||
android:padding="12dp" |
||||
android:textColor="@android:color/black" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"/> |
Loading…
Reference in new issue