3.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; } }
3.PopupWindow 、拍照、裁剪的更多相关文章
- Intent 常用场景 FileProvider 拍照 裁剪 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android调用系统拍照裁剪和选图功能
最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下. 调用系统拍照 private fun openCamera() { //调用相机拍照 // 创建File对象,用于存储拍照后的 ...
- 4.4系统,拍照-裁剪,resultCode返回0
问题描述: take photo -> 拍照 -> 确定 -> 截图 -> 保存,此时返回给onActivityResult的resultCode是0,截图无效.我查看图片储存 ...
- iOS自定义拍照框拍照&裁剪(一)
卡片机时代 很重要的一点是,相机本身是没有方向概念的,它不理解拍摄的内容,只会以相机自己的坐标系去保存数据,下图展示了相机对"F"进行四个角度拍摄时返回的图片数据. 最初的卡片机时 ...
- 转--2014年最新810多套android源码2.46GB免费一次性打包下载
转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...
- 2014年最新720多套Android源码2.0GB免费一次性打包下载
之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...
- ym——android源代码大放送(实战开发必备)
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 目录 PATH 列表 卷序列号为 000A-8F50 E:. │ javaapk.c ...
- 手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。
1. 拍照裁剪后 点击EditText会弹出输入法,却不能输入.可是点击点一EdtiText就能够输入了,所以我就写了一个看不见的EdtiText,切换焦点,这样就攻克了这个奇怪的这问题,应该是and ...
- Android开发技巧——定制仿微信图片裁剪控件
拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...
- [deviceone开发]-do_Camera的简单示例
一.简介 do_Camera组件是通过拍照裁剪来生成图片的组件,这个示例直观的展示组件基本的使用方式 二.效果图 三.相关下载 https://github.com/do-project/code4d ...
随机推荐
- C语言回调函数
Callbacks have a wide variety of uses. For example, imagine a function that reads a configuration fi ...
- bootshrap会改变IE浏览器滚动条样式
在某个小网站的开发中 客户一直抱怨在IE11中网页右边滚动条不一样 后来发现在IE11中,有2个页面滚动条会自动隐藏,一开始以为是浏览器默认行为,改了overflow:scroll后也没有用.仔细观察 ...
- ExtJS学习之路第六步:深入讨论组件Panel用法
Panel加载页面 var myPanel=Ext.create('Ext.panel.Panel',{ bodyPadding: "15px 10px 0 10px", titl ...
- dedecms删除没有文章的标签
要批量的删除织梦TAG标签,那我们就只能在数据库里做修改了. 登录数据库,在数据库里执行以下SQL语句: delete FROM dede_tagindex where typeid not in ( ...
- JVM<一>----------运行时数据区域
参考:1.JVM Specification: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5 2.< ...
- Apache同时支持PHP和Python的配置方法
一.http://www.oschina.net 网站中的一个问答内容: 原来把 WSGIScriptAlias / "D:/project/ddd/django.wsgi" ...
- python __init__ __call__
__call__ 和 __init__半毛钱的关系都没有. 后者是构造类的实例时会调用的方法,并不是构造方法. 前者是在实例上可以呼叫的方法.代码示例如下: >>> class fo ...
- Android 下载文件及写入SD卡
Android 下载文件及写入SD卡,实例代码 <?xml version="1.0" encoding="utf-8"?> <LinearL ...
- Android Studio在线安装Android SDK注意事项
由于使用的Android studio自带了sdk23,然而其它版本的sdk并没有安装:这些天由于需要用到低版本的sdk,因而使用Android SDK Manager进行相应的更新.开始的时候老是无 ...
- poj3904
题意:给出n(n<10000)个数,这些数<=10000,要求选出四个数字且他们的最大公约数为1的(注意:不需要两两互质),有多少种选法. 分析: 容斥原理 假设平面上有一些圆,互相之间有 ...