PopupWindow 以及拍照、裁剪
实现这样的效果

- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/pop_layout"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="@drawable/btn_style_alert_dialog_background"
- android:gravity="center_horizontal"
- android:orientation="vertical" >
- <Button
- android:id="@+id/btn_take_photo"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginTop="20dip"
- android:background="@drawable/btn_style_alert_dialog_button"
- android:text="拍照"
- android:textStyle="bold" />
- <Button
- android:id="@+id/btn_pick_photo"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginTop="5dip"
- android:background="@drawable/btn_style_alert_dialog_button"
- android:text="从相册选择"
- android:textStyle="bold" />
- <Button
- android:id="@+id/btn_cancel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="15dip"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginTop="15dip"
- android:background="@drawable/btn_style_alert_dialog_cancel"
- android:text="取消"
- android:textColor="#ffffff"
- android:textStyle="bold" />
- </LinearLayout>
activity_main:view是阴影
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/rl_root"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#fff"
- tools:context=".MainActivity" >
- <CheckBox
- android:id="@+id/cb"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="显示对话框的形式" />
- <de.hdodenhof.circleimageview.CircleImageView
- android:id="@+id/civ"
- android:layout_width="100dp"
- android:layout_height="100dp"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="10dp"
- android:src="@drawable/man"
- app:border_color="#ccc"
- app:border_width="2dp" >
- </de.hdodenhof.circleimageview.CircleImageView>
- <View
- android:id="@+id/viewMask"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#20000000"
- android:visibility="gone" >
- </View>
- </RelativeLayout>
push_bottom_in
- <!-- 上下滑入式 -->
- <set xmlns:android="http://schemas.android.com/apk/res/android" >
- <translate
- android:duration="200"
- android:fromYDelta="100%p"
- android:toYDelta="0"
- />
- <alpha
- android:fromAlpha="0.0"
- android:toAlpha="1.0"
- android:duration="200"
- />
- </set>
push_bottom_in2
- <!-- 上下滑入式 -->
- <set xmlns:android="http://schemas.android.com/apk/res/android" >
- <alpha
- android:startOffset="200"
- android:fromAlpha="0.0"
- android:toAlpha="1.0"
- android:duration="200"
- />
- </set>
push_bottom_out
- <!-- 上下滑入式 -->
- <set xmlns:android="http://schemas.android.com/apk/res/android" >
- <translate
- android:duration="200"
- android:fromYDelta="0"
- android:toYDelta="50%p" />
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="0.0"
- android:duration="200"
- />
- </set>
styles
- <resources>
- <style name="AppTheme" parent="android:Theme.Light" />
- <style name="AnimBottom" parent="@android:style/Animation">
- <item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
- <item name="android:windowExitAnimation">@anim/push_bottom_out</item>
- </style>
- <style name="PopupAnimation" parent="android:Animation">
- <item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
- <item name="android:windowExitAnimation">@anim/push_bottom_out</item>
- </style>
- </resources>
SelectPhotoPopupWindow
- public class SelectPhotoPopupWindow extends PopupWindow {
- private Button btn_take_photo, btn_pick_photo, btn_cancel;
- public SelectPhotoPopupWindow(Context context, OnClickListener onClickListener) {
- View contentView = View.inflate(context, R.layout.layout_pupup, null);
- /*
- * View contentView = View.inflate(MainActivity.this, R.layout.file_item_pop, null);
- int width = ViewGroup.LayoutParams.MATCH_PARENT;
- int height = itemView.getHeight();
- System.out.println("height:" + height);
- popupWindow = new PopupWindow(contentView, width, height);
- /*点击popupWindow范围以外的地方,让popupWindow消失*/
- // popupWindow.setOutsideTouchable(true);
- // popupWindow.setBackgroundDrawable(new BitmapDrawable());
- // */
- this.setContentView(contentView);
- this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
- this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
- /**点击popupWindow范围以外的地方,让popupWindow消失*/
- this.setOutsideTouchable(true);
- this.setBackgroundDrawable(new BitmapDrawable());
- //找到对应的控件
- btn_take_photo = (Button) contentView.findViewById(R.id.btn_take_photo);
- btn_pick_photo = (Button) contentView.findViewById(R.id.btn_pick_photo);
- btn_cancel = (Button) contentView.findViewById(R.id.btn_cancel);
- btn_take_photo.setOnClickListener(onClickListener);
- btn_pick_photo.setOnClickListener(onClickListener);
- btn_cancel.setOnClickListener(onClickListener);
- //加入动画
- this.setAnimationStyle(R.style.AnimBottom);
- }
- }
MainActivity
- public class MainActivity extends Activity implements OnClickListener {
- protected static final int CODE_TAKE_PHOTO = 100;
- protected static final int CODE_PICK_PHOTO = 101;
- private static final int CODE_ZOOM_PHOTOT = 102;
- private String sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
- private File tempFile = new File(sdCardPath + "/" + "tempFile.jpg");
- private View root;
- private SelectPhotoPopupWindow selectPhotoPopupWindow;
- private View viewMask;
- private CheckBox cb;
- private CircleImageView civ;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- viewMask = findViewById(R.id.viewMask);
- root = findViewById(R.id.rl_root);
- cb = (CheckBox) findViewById(R.id.cb);
- civ = (CircleImageView) findViewById(R.id.civ);
- civ.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (cb.isChecked()) {
- PhotoUtilChange.getPhotoDialog(MainActivity.this, CODE_TAKE_PHOTO, CODE_PICK_PHOTO, tempFile);
- } else {
- selectPhotoPopupWindow = PhotoUtilChange.getPicPopupWindow(MainActivity.this, MainActivity.this,
- root);
- AnimationUtils.showAlpha(viewMask);
- }
- }
- });
- viewMask.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (selectPhotoPopupWindow != null) {
- selectPhotoPopupWindow.dismiss();
- AnimationUtils.hideAlpha(viewMask);
- }
- }
- });
- }
- @Override
- public void onClick(View v) {
- selectPhotoPopupWindow.dismiss();
- switch (v.getId()) {
- case R.id.btn_cancel:
- Toast.makeText(getApplicationContext(), "cancle", 0).show();
- AnimationUtils.hideAlpha(viewMask);
- break;
- case R.id.btn_take_photo://拍照
- //1.发起拍照的intent
- PhotoUtilChange.takePhoto(MainActivity.this, CODE_TAKE_PHOTO, tempFile);
- break;
- case R.id.btn_pick_photo://从相册选择
- //1.发起从相册选择的intent
- PhotoUtilChange.pickPhoto(MainActivity.this, CODE_PICK_PHOTO, tempFile);
- break;
- default:
- break;
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case CODE_TAKE_PHOTO://拍照
- //2.处理拍照的结果-->去裁剪
- PhotoUtilChange.onPhotoFromCamera(MainActivity.this, CODE_ZOOM_PHOTOT, tempFile.getAbsolutePath(), 1, 1);
- break;
- case CODE_PICK_PHOTO://从相册选择
- //2.处理从相册选择的结果-->去裁剪
- PhotoUtilChange.onPhotoFromPick(MainActivity.this, CODE_ZOOM_PHOTOT, tempFile.getAbsolutePath(), data, 50,
- 50);
- break;
- case CODE_ZOOM_PHOTOT://裁剪
- //3.裁剪完成
- Bitmap zoomBitMap = PhotoUtilChange.getZoomBitMap(data, MainActivity.this);
- //4.修改头像
- civ.setImageBitmap(zoomBitMap);
- break;
- default:
- break;
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
PhotoUtilChange
- /***
- * billy修改版
- * 头像上传工具类 调用 getPhoto 在onactivityResult 调用
- * onPhotoFromCamera
- * onPhotoFromPick
- */
- public class PhotoUtilChange {
- /**
- * 因为处理不同
- *
- * @param takePhotoCode
- * Uri originalUri = data.getData();
- * image=ImageUtil.getBitmapFromUrl(originalUri.toString());
- **********************************************************************************
- * @param pickPhotoCode
- * Bundle extras = data.getExtras(); image = (Bitmap)
- * extras.get("data");
- * @param tempFile
- * 拍照时的临时文件 需要zoom时
- * **/
- public static boolean getPhotoDialog(final Activity activity, final int takePhotoCode, final int pickPhotoCode,
- final File tempFile) {
- final CharSequence[] items = { "相册", "拍照" };
- AlertDialog dlg = new AlertDialog.Builder(activity).setTitle("选择图片")
- .setItems(items, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- if (item == 1) {
- Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
- getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
- activity.startActivityForResult(getImageByCamera, takePhotoCode);
- } else {
- Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
- getImage.addCategory(Intent.CATEGORY_OPENABLE);
- getImage.setType("image/jpeg");
- activity.startActivityForResult(getImage, pickPhotoCode);
- }
- }
- }).create();
- dlg.show();
- return true;
- }
- public static SelectPhotoPopupWindow getPicPopupWindow(Context context, OnClickListener itemsOnClick,
- View viewAttach) {
- //实例化SelectPicPopupWindow
- SelectPhotoPopupWindow menuWindow = new SelectPhotoPopupWindow(context, itemsOnClick);
- //显示窗口
- menuWindow.showAtLocation(viewAttach, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); //设置layout在PopupWindow中显示的位置
- return menuWindow;
- }
- public static boolean takePhoto(Activity activity, int takePhotoCode, File tempFile) {
- Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
- getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
- activity.startActivityForResult(getImageByCamera, takePhotoCode);
- return true;
- }
- public static boolean pickPhoto(Activity activity, int imageCode, File tempFile) {
- Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
- getImage.addCategory(Intent.CATEGORY_OPENABLE);
- getImage.setType("image/jpeg");
- activity.startActivityForResult(getImage, imageCode);
- return true;
- }
- /**
- * 拍照获取图片的方式 用于切割的图片大小被限制在500,500
- *
- * @param context
- * @param zoomCode
- * @param temppath
- * 拍照前生成的临时路劲
- * @return 新的路劲
- */
- public static String onPhotoFromCamera(final Activity context, final int zoomCode, final String temppath,
- final int aspectX, final int aspectY) {
- try {
- Bitmap btp = getLocalImage(new File(temppath), 1000, 1000);
- compressImage(btp, new File(temppath + "temp.jpg"), 30);
- photoZoom(context, Uri.fromFile(new File(temppath + "temp.jpg")), Uri.fromFile(new File(temppath)),
- zoomCode, aspectX, aspectY);
- } catch (Exception e) {
- Toast.makeText(context, "图片加载失败", 1000).show();
- }
- return temppath;
- }
- /**
- * 图片切割完调用 如果还需要 Bitmap 调用getLocalImage
- *
- * @param path
- * @param rw
- * @param rh
- * @param compress
- * @return
- */
- public static File onPhotoZoom(String path, int rw, int rh, int compress) {
- File f = new File(path);
- Bitmap btp = PhotoUtilChange.getLocalImage(f, rw, rh);
- compressImage(btp, f, compress);
- return f;
- }
- /**
- * 相册获取图片,用于切割的图片大小被限制在500,500
- *
- * @param context
- * @param zoomCode
- * @param temppath
- * 希望生成的路劲
- * @param data
- */
- public static void onPhotoFromPick(final Activity context, final int zoomCode, final String temppath,
- final Intent data, final int aspectX, final int aspectY) {
- try {
- Bitmap btp = checkImage(context, data);
- compressImage(btp, new File(temppath + "temp.jpg"), 30);
- PhotoUtilChange.photoZoom(context, Uri.fromFile(new File(temppath + "temp.jpg")),
- Uri.fromFile(new File(temppath)), zoomCode, aspectX, aspectY);
- } catch (Exception e) {
- Toast.makeText(context, "图片加载失败", 1000).show();
- }
- }
- /**
- * data 中检出图片
- *
- * @param activity
- * @param data
- * @return
- */
- public static Bitmap checkImage(Activity activity, Intent data) {
- Bitmap bitmap = null;
- try {
- Uri originalUri = data.getData();
- String path = getRealPathFromURI(activity, originalUri);
- File f = activity.getExternalCacheDir();
- String pp = f.getAbsolutePath();
- if (path.indexOf(pp) != -1) {
- path = path.substring(path.indexOf(pp), path.length());
- }
- bitmap = getLocalImage(new File(path), 1000, 1000);
- } catch (Exception e) {
- } finally {
- return bitmap;
- }
- }
- /**
- * 通过URI 获取真实路劲
- *
- * @param activity
- * @param contentUri
- * @return
- */
- public static String getRealPathFromURI(Activity activity, Uri contentUri) {
- Cursor cursor = null;
- String result = contentUri.toString();
- String[] proj = { MediaStore.Images.Media.DATA };
- cursor = activity.managedQuery(contentUri, proj, null, null, null);
- if (cursor == null)
- throw new NullPointerException("reader file field");
- if (cursor != null) {
- int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
- cursor.moveToFirst();
- result = cursor.getString(column_index);
- if (Integer.parseInt(Build.VERSION.SDK) < 14) {
- cursor.close();
- }
- }
- return result;
- }
- /**
- * 图片压缩 上传图片时建议compress为30
- *
- * @param bm
- * @param f
- */
- public static void compressImage(Bitmap bm, File f, int compress) {
- if (bm == null)
- return;
- File file = f;
- try {
- if (file.exists()) {
- file.delete();
- }
- file.createNewFile();
- OutputStream outStream = new FileOutputStream(file);
- bm.compress(android.graphics.Bitmap.CompressFormat.JPEG, compress, outStream);
- outStream.flush();
- outStream.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 由本地文件获取希望大小的文件
- *
- * @param f
- * @return
- */
- public static Bitmap getLocalImage(File f, int swidth, int sheight) {
- File file = f;
- if (file.exists()) {
- try {
- file.setLastModified(System.currentTimeMillis());
- FileInputStream in = new FileInputStream(file);
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(in, null, options);
- int sWidth = swidth;
- int sHeight = sheight;
- int mWidth = options.outWidth;
- int mHeight = options.outHeight;
- int s = 1;
- while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2)) {
- s *= 2;
- }
- options = new BitmapFactory.Options();
- options.inSampleSize = s;
- options.inPreferredConfig = Bitmap.Config.RGB_565;
- options.inPurgeable = true;
- options.inInputShareable = true;
- try {
- // 4. inNativeAlloc 属性设置为true,可以不把使用的内存算到VM里
- BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options, true);
- } catch (Exception e) {
- }
- in.close();
- // 再次获取
- in = new FileInputStream(file);
- Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
- in.close();
- return bitmap;
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- } catch (Error e) {
- System.gc();
- return null;
- }
- }
- return null;
- }
- /**
- * aspectY Y对于X的比例 outputX X 的宽
- * **/
- public static void photoZoom(Activity activity, Uri uri, Uri outUri, int photoResoultCode, int aspectX, int aspectY) {
- Intent intent = new Intent("com.android.camera.action.CROP");
- intent.setDataAndType(uri, "image/*");
- intent.putExtra("crop", "true");
- // aspectX aspectY 是宽高的比例
- if (aspectY > 0) {
- intent.putExtra("aspectX", aspectX);
- intent.putExtra("aspectY", aspectY);
- }
- intent.putExtra("scale", aspectX == aspectY);
- intent.putExtra("return-data", true);
- intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
- intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);
- intent.putExtra("noFaceDetection", true); //
- activity.startActivityForResult(intent, photoResoultCode);
- }
- /**
- * 保存zoom之后的图片
- * @param data zoom后的intent
- * @param context 上下文
- * @return
- */
- public static Bitmap getZoomBitMap(Intent data, Context context) {
- try {
- Bundle extras = data.getExtras();
- if (extras != null) {
- Bitmap bitmap = extras.getParcelable("data");
- return bitmap;
- }
- } catch (Exception e) {
- e.printStackTrace();
- Toast.makeText(context, "出现未知异常,请尝试其他图片", Toast.LENGTH_SHORT).show();
- }
- return null;
- }
- }
PopupWindow 以及拍照、裁剪的更多相关文章
- Intent 常用场景 FileProvider 拍照 裁剪 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 3.PopupWindow 、拍照、裁剪
实现这样的效果 圆角图片的自定义控件直接拷进来,和com一个等级 想要弹出内容可以使用悬浮窗 layout_pupup <LinearLayout xmlns:android="htt ...
- Android调用系统拍照裁剪和选图功能
最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下. 调用系统拍照 private fun openCamera() { //调用相机拍照 // 创建File对象,用于存储拍照后的 ...
- 4.4系统,拍照-裁剪,resultCode返回0
问题描述: take photo -> 拍照 -> 确定 -> 截图 -> 保存,此时返回给onActivityResult的resultCode是0,截图无效.我查看图片储存 ...
- iOS自定义拍照框拍照&裁剪(一)
卡片机时代 很重要的一点是,相机本身是没有方向概念的,它不理解拍摄的内容,只会以相机自己的坐标系去保存数据,下图展示了相机对"F"进行四个角度拍摄时返回的图片数据. 最初的卡片机时 ...
- 手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。
1. 拍照裁剪后 点击EditText会弹出输入法,却不能输入.可是点击点一EdtiText就能够输入了,所以我就写了一个看不见的EdtiText,切换焦点,这样就攻克了这个奇怪的这问题,应该是and ...
- Android开发技巧——定制仿微信图片裁剪控件
拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...
- Android上传图片之调用系统拍照和从相冊选择图片
Android上传图片之调用系统拍照和从相冊选择图片 本篇文章已授权微信公众号 guolin_blog (郭霖)独家公布 前言: 万丈高楼平底起,万事起于微末.不知不觉距离上篇博文已近四个月,2015 ...
- 转--2014年最新810多套android源码2.46GB免费一次性打包下载
转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...
随机推荐
- 机器学习入门-BP神经网络模型及梯度下降法-2017年9月5日14:58:16
BP(Back Propagation)网络是1985年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一. B ...
- Java-Oracle数据库连接
Oracle数据库先创建一个表和添加一些数据,下面是连接数据库的具体实现.(导入jar包:ojdbc14.jar) import java.sql.Connection; import java.sq ...
- hbase-数据恢复流程
引用<https://blog.csdn.net/nigeaoaojiao/article/details/54909921> hlog介绍: hlog构建: 从图中可以看出,对于一个hl ...
- 配置GitHub的SSH key
配置GitHub的SSH key 生成密钥对 打开git bash工具(Windows环境),Linux则直接打开命令行,执行下面的命令生成密钥文件 ssh-Keygen -t rsa -C &quo ...
- 1,fiddler的工作原理和安装
1,工作原理就是通过设置代理监控客户端和服务端的协议 2,fiddler的安装 1,官方的下载地址:https://www.telerik.com/download/fiddler 一步步安装即可 2 ...
- 关于tomcat7配置maxPostSize=“0”时,后台无法接收前台参数的问题
Post提交参数时,如果参数值的长度太长,后台通过Map<String, String[]> requestParameterMap=request.getParameterMap();获 ...
- Mysql数据库每天定时执行备份方法
此数据库备份方法是简单的数据库备份方法,就是从Mysql的数据文件下,将数据库文件拷贝到指定的文件夹目录下 1.创建txt文件,添加脚本 net stop mysql xcopy D:\MySql\D ...
- HDU-4763 Theme Section KMP
题意:求最长的子串E,使母串满足EAEBE的形式,A.B可以任意,并且不能重叠. 题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4763 思 ...
- fiddler不能抓某些的包的原因
用fiddler抓某app的包时,死活抓不到,确定自己设置的没有错,并且让小A同事也看了一遍我的设置,确认没错后,又在小A同事那儿试了下还是抓不到 后来在网上找了很多资料,才发现是因为一些app使用了 ...
- 学习笔记整理之StringBuffer与StringBulider的线程安全与线程不安全
关于线程和线程不安全: 概述 编辑 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就 ...