Android 小技巧之调取拍照、相机弹窗
2021-12-10 本文已影响0人
Kevin_小飞象

这是一篇实用的调取相机拍照功能的前期准备工作---弹窗。
效果图

准备
- 准备进入和退出动画../res/anim
a. push_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fromYDelta="50%p"
android:toYDelta="0" />
</set>
b. push_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?><!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromYDelta="0"
android:toYDelta="50%p" />
</set>
c. 在 thems.xml 中使用
<style name="AnimUp" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
<item name="android:windowExitAnimation">@anim/push_bottom_out</item>
</style>
- layout 背景 dialog_bg_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp"/>
<solid android:color="@color/white"/>
<stroke android:color="#cbcbcb" android:width="1px"/>
</shape>
- 工具类 CommonUtil.java
/**
* Created on 2021/5/19 9:09
*
* @author Gong Youqiang
*/
public class CommonUtil {
/**
* 测量View的宽高
*
* @param view View
*/
public static void measureWidthAndHeight(View view) {
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(w, h);
}
public static String getJsonStringByEntity(Object o) {
String strJson = "";
Gson gson = new Gson();
strJson = gson.toJson(o);
return strJson;
}
}
实现
- 布局文件 popup_take_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<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:background="@drawable/dialog_bg_normal"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_avatar_photograph"
android:layout_width="match_parent"
android:layout_height="45dp"
android:textSize="16sp"
android:gravity="center"
android:textColor="@color/text_color"
android:text="拍照"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/divider"/>
<TextView
android:id="@+id/tv_avatar_photo"
android:layout_width="match_parent"
android:layout_height="45dp"
android:textSize="16sp"
android:gravity="center"
android:textColor="@color/text_color"
android:text="相册"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/divider"/>
<TextView
android:id="@+id/tv_avatar_cancel"
android:layout_width="match_parent"
android:layout_height="45dp"
android:textSize="16sp"
android:gravity="center"
android:textColor="@color/text_color"
android:text="取消"/>
</LinearLayout>
- PopupController.java
/**
* Created on 2021/5/19 9:10
*
* @author Gong Youqiang
*/
public class PopupController {
private int layoutResId;//布局id
private Context context;
private PopupWindow popupWindow;
public View mPopupView;//弹窗布局View
private View mView;
private Window mWindow;
public PopupController(Context context, PopupWindow popupWindow) {
this.context = context;
this.popupWindow = popupWindow;
}
public void setView(int layoutResId) {
mView = null;
this.layoutResId = layoutResId;
installContent();
}
public void setView(View view) {
mView = view;
this.layoutResId = 0;
installContent();
}
private void installContent() {
if (layoutResId != 0) {
mPopupView = LayoutInflater.from(context).inflate(layoutResId, null);
} else if (mView != null) {
mPopupView = mView;
}
popupWindow.setContentView(mPopupView);
}
/**
* 设置宽度
*
* @param width 宽
* @param height 高
*/
private void setWidthAndHeight(int width, int height) {
if (width == 0 || height == 0) {
//如果没设置宽高,默认是WRAP_CONTENT
popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
} else {
popupWindow.setWidth(width);
popupWindow.setHeight(height);
}
}
/**
* 设置背景灰色程度
*
* @param level 0.0f-1.0f
*/
public void setBackGroundLevel(float level) {
mWindow = ((Activity) context).getWindow();
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = level;
mWindow.setAttributes(params);
}
/**
* 设置动画
*/
private void setAnimationStyle(int animationStyle) {
popupWindow.setAnimationStyle(animationStyle);
}
/**
* 设置Outside是否可点击
*
* @param touchable 是否可点击
*/
private void setOutsideTouchable(boolean touchable) {
popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));//设置透明背景
popupWindow.setOutsideTouchable(touchable);//设置outside可点击
popupWindow.setFocusable(touchable);
}
public static class PopupParams {
public int layoutResId;//布局id
public Context mContext;
public int mWidth, mHeight;//弹窗的宽和高
public boolean isShowBg, isShowAnim;
public float bg_level;//屏幕背景灰色程度
public int animationStyle;//动画Id
public View mView;
public boolean isTouchable = true;
public PopupParams(Context mContext) {
this.mContext = mContext;
}
public void apply(PopupController controller) {
if (mView != null) {
controller.setView(mView);
} else if (layoutResId != 0) {
controller.setView(layoutResId);
} else {
throw new IllegalArgumentException("PopupView's contentView is null");
}
controller.setWidthAndHeight(mWidth, mHeight);
controller.setOutsideTouchable(isTouchable);//设置outside可点击
if (isShowBg) {
//设置背景
controller.setBackGroundLevel(bg_level);
}
if (isShowAnim) {
controller.setAnimationStyle(animationStyle);
}
}
}
}
- CommonPopupWindow.java
/**
* Created on 2021/5/19 9:08
*
* @author Gong Youqiang
*/
public class CommonPopupWindow extends PopupWindow {
private PopupController controller;
@Override
public int getWidth() {
return controller.mPopupView.getMeasuredWidth();
}
@Override
public int getHeight() {
return controller.mPopupView.getMeasuredHeight();
}
public interface ViewInterface {
void getChildView(View view, int layoutResId);
}
private CommonPopupWindow(Context context) {
controller = new PopupController(context, this);
}
@Override
public void dismiss() {
super.dismiss();
controller.setBackGroundLevel(1.0f);
}
public static class Builder {
private final PopupController.PopupParams params;
private ViewInterface listener;
public Builder(Context context) {
params = new PopupController.PopupParams(context);
}
/**
* @param layoutResId 设置PopupWindow 布局ID
* @return Builder
*/
public Builder setView(int layoutResId) {
params.mView = null;
params.layoutResId = layoutResId;
return this;
}
/**
* @param view 设置PopupWindow布局
* @return Builder
*/
public Builder setView(View view) {
params.mView = view;
params.layoutResId = 0;
return this;
}
/**
* 设置子View
*
* @param listener ViewInterface
* @return Builder
*/
public Builder setViewOnclickListener(ViewInterface listener) {
this.listener = listener;
return this;
}
/**
* 设置宽度和高度 如果不设置 默认是wrap_content
*
* @param width 宽
* @return Builder
*/
public Builder setWidthAndHeight(int width, int height) {
params.mWidth = width;
params.mHeight = height;
return this;
}
/**
* 设置背景灰色程度
*
* @param level 0.0f-1.0f
* @return Builder
*/
public Builder setBackGroundLevel(float level) {
params.isShowBg = true;
params.bg_level = level;
return this;
}
/**
* 是否可点击Outside消失
*
* @param touchable 是否可点击
* @return Builder
*/
public Builder setOutsideTouchable(boolean touchable) {
params.isTouchable = touchable;
return this;
}
/**
* 设置动画
*
* @return Builder
*/
public Builder setAnimationStyle(int animationStyle) {
params.isShowAnim = true;
params.animationStyle = animationStyle;
return this;
}
public CommonPopupWindow create() {
final CommonPopupWindow popupWindow = new CommonPopupWindow(params.mContext);
params.apply(popupWindow.controller);
if (listener != null && params.layoutResId != 0) {
listener.getChildView(popupWindow.controller.mPopupView, params.layoutResId);
}
CommonUtil.measureWidthAndHeight(popupWindow.controller.mPopupView);
return popupWindow;
}
}
}
- MainActivity.java
public class MainActivity extends AppCompatActivity {
private CommonPopupWindow popupWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPermissionRequest();
initWidget();
}
private void checkPermissionRequest() {
RxPermissions rxPermission = new RxPermissions(MainActivity.this);
rxPermission.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer<Permission>() {
@Override
public void accept(Permission permission) {
if (permission.granted) {// 用户已经同意该权限
//第一种方式,弹出选择和拍照的dialog
showPopupWindow();
//第二种方式,直接进入相册,但是 是有拍照得按钮的
// showAlbum();
} else {
Toast.makeText(MainActivity.this, "拒绝", Toast.LENGTH_SHORT).show();
}
}
});
}
private void showPopupWindow() {
if (popupWindow != null && popupWindow.isShowing()) {
return;
}
View popView = View.inflate(this,R.layout.popup_take_photo,null);
popupWindow = new CommonPopupWindow.Builder(this)
.setView(R.layout.popup_take_photo)
.setAnimationStyle(R.style.AnimUp)
.setBackGroundLevel(0.5f)
.setWidthAndHeight(980,400)
.setViewOnclickListener(new CommonPopupWindow.ViewInterface() {
@Override
public void getChildView(View view, int layoutResId) {
TextView photograph = view.findViewById(R.id.tv_avatar_photograph);
TextView selPhoto = view.findViewById(R.id.tv_avatar_photo);
TextView cancel = view.findViewById(R.id.tv_avatar_cancel);
photograph.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (popupWindow != null) {
popupWindow.dismiss();
}
//TODO拍照
}
});
selPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO相册
if (popupWindow != null) {
popupWindow.dismiss();
}
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (popupWindow != null) {
popupWindow.dismiss();
}
}
});
}
})
.setOutsideTouchable(true)
.create();
popupWindow.showAtLocation(popView, Gravity.BOTTOM,0,50);
}
}