实现这样的效果

圆角图片的自定义控件直接拷进来,和com一个等级
想要弹出内容可以使用悬浮窗
layout_pupup

<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 、拍照、裁剪的更多相关文章

  1. Intent 常用场景 FileProvider 拍照 裁剪 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Android调用系统拍照裁剪和选图功能

    最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下. 调用系统拍照 private fun openCamera() { //调用相机拍照 // 创建File对象,用于存储拍照后的 ...

  3. 4.4系统,拍照-裁剪,resultCode返回0

    问题描述: take photo -> 拍照 -> 确定 -> 截图 -> 保存,此时返回给onActivityResult的resultCode是0,截图无效.我查看图片储存 ...

  4. iOS自定义拍照框拍照&裁剪(一)

    卡片机时代 很重要的一点是,相机本身是没有方向概念的,它不理解拍摄的内容,只会以相机自己的坐标系去保存数据,下图展示了相机对"F"进行四个角度拍摄时返回的图片数据. 最初的卡片机时 ...

  5. 转--2014年最新810多套android源码2.46GB免费一次性打包下载

    转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...

  6. 2014年最新720多套Android源码2.0GB免费一次性打包下载

    之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...

  7. ym——android源代码大放送(实战开发必备)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 目录 PATH 列表 卷序列号为 000A-8F50 E:. │  javaapk.c ...

  8. 手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。

    1. 拍照裁剪后 点击EditText会弹出输入法,却不能输入.可是点击点一EdtiText就能够输入了,所以我就写了一个看不见的EdtiText,切换焦点,这样就攻克了这个奇怪的这问题,应该是and ...

  9. Android开发技巧——定制仿微信图片裁剪控件

    拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...

  10. [deviceone开发]-do_Camera的简单示例

    一.简介 do_Camera组件是通过拍照裁剪来生成图片的组件,这个示例直观的展示组件基本的使用方式 二.效果图 三.相关下载 https://github.com/do-project/code4d ...

随机推荐

  1. C语言回调函数

    Callbacks have a wide variety of uses. For example, imagine a function that reads a configuration fi ...

  2. bootshrap会改变IE浏览器滚动条样式

    在某个小网站的开发中 客户一直抱怨在IE11中网页右边滚动条不一样 后来发现在IE11中,有2个页面滚动条会自动隐藏,一开始以为是浏览器默认行为,改了overflow:scroll后也没有用.仔细观察 ...

  3. ExtJS学习之路第六步:深入讨论组件Panel用法

    Panel加载页面 var myPanel=Ext.create('Ext.panel.Panel',{ bodyPadding: "15px 10px 0 10px", titl ...

  4. dedecms删除没有文章的标签

    要批量的删除织梦TAG标签,那我们就只能在数据库里做修改了. 登录数据库,在数据库里执行以下SQL语句: delete FROM dede_tagindex where typeid not in ( ...

  5. JVM<一>----------运行时数据区域

    参考:1.JVM Specification: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5 2.< ...

  6. Apache同时支持PHP和Python的配置方法

      一.http://www.oschina.net 网站中的一个问答内容: 原来把 WSGIScriptAlias / "D:/project/ddd/django.wsgi"  ...

  7. python __init__ __call__

    __call__ 和 __init__半毛钱的关系都没有. 后者是构造类的实例时会调用的方法,并不是构造方法. 前者是在实例上可以呼叫的方法.代码示例如下: >>> class fo ...

  8. Android 下载文件及写入SD卡

    Android 下载文件及写入SD卡,实例代码 <?xml version="1.0" encoding="utf-8"?> <LinearL ...

  9. Android Studio在线安装Android SDK注意事项

    由于使用的Android studio自带了sdk23,然而其它版本的sdk并没有安装:这些天由于需要用到低版本的sdk,因而使用Android SDK Manager进行相应的更新.开始的时候老是无 ...

  10. poj3904

    题意:给出n(n<10000)个数,这些数<=10000,要求选出四个数字且他们的最大公约数为1的(注意:不需要两两互质),有多少种选法. 分析: 容斥原理 假设平面上有一些圆,互相之间有 ...