您的位置:首页 > 移动开发 > Android开发

Android从屏幕底部弹出popupWindow

2017-03-25 17:35 567 查看

Android从屏幕底部弹出popupWindow

先看一下效果,看看是不是你想要的效果,免得浪费大家的时间,有一点说明,由于我录制的gif是用的模拟器,所以没有屏幕变暗的效果和加速的弹起的效果,实际效果以真机测试为准。



如果是你要的效果就可以继续向下看了…

1.首先是布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@drawable/popupwindow_shape"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/tvTakePhoto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="30dp"
android:background="@color/white"
android:gravity="center"
android:padding="10dp"
android:text="拍照"
android:textSize="18sp" />

<TextView
android:id="@+id/tvSelectPhoto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@color/white"
android:gravity="center"
android:padding="10dp"
android:text="选择相册"
android:textSize="18sp" />
</LinearLayout>

</LinearLayout>


2.代码部分

我此处用的是一个加速的平移动画,从屏幕底部弹出,然后将屏幕的亮度变暗,让popupwindow获取焦点,就可以实现了popupwindow从手机屏幕底部弹出的效果,代码中注释已经写的很清楚了,直接看代码即可

2.1设置触发popupwindow的点击事件

public void onClick(View view) {
switch (view.getId()) {
case R.id.rlIcon:
// TODO 弹出popupwind选择拍照或者从相册选择
changeIcon(view);
lightoff();
break;
}


2.2定义3个属性变量

// 声明PopupWindow
private PopupWindow popupWindow;
// 声明PopupWindow对应的视图
private View popupView;

// 声明平移动画
private TranslateAnimation animation;


2.3弹起popupWindow

/**
* 弹出popupWindow更改头像
*/
private void changeIcon() {
if (popupWindow == null) {
popupView = View.inflate(this, R.layout.item_change_icon, null);
// 参数2,3:指明popupwindow的宽度和高度
popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);

popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
lighton();
}
});

// 设置背景图片, 必须设置,不然动画没作用
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setFocusable(true);

// 设置点击popupwindow外屏幕其它地方消失
popupWindow.setOutsideTouchable(true);

// 平移动画相对于手机屏幕的底部开始,X轴不变,Y轴从1变0
animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 1, Animation.RELATIVE_TO_PARENT, 0);
animation.setInterpolator(new AccelerateInterpolator());
animation.setDuration(200);

popupView.findViewById(R.id.tvTakePhoto).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 打开系统拍照程
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera, CAMERA);
popupWindow.dismiss();
lighton();
}
});
popupView.findViewById(R.id.tvSelectPhoto).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 打开系统图库选择图片
Intent picture = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(picture, PICTURE);
popupWindow.dismiss();
lighton();
}
});
}

// 在点击之后设置popupwindow的销毁
if (popupWindow.isShowing()) {
popupWindow.dismiss();
lighton();
}

// 设置popupWindow的显示位置,此处是在手机屏幕底部且水平居中的位置
popupWindow.showAtLocation(SettingActivity.this.findViewById(R.id.setting), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
popupView.startAnimation(animation);
}


2.4设置手机屏幕亮度的2个方法

/**
* 设置手机屏幕亮度变暗
*/
private void lightoff() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 0.3f;
getWindow().setAttributes(lp);
}

/**
* 设置手机屏幕亮度显示正常
*/
private void lighton() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1f;
getWindow().setAttributes(lp);
}


3.我做的是手机拍照和相册选择的功能,在此也附上拍照和选择相册的代码,希望能帮到大家

//Bimap:对应图片在内存中的对象
//掌握:存储--->内存:BitmapFactory.decodeFile(String filePath)
//                  BitmapFactory.decodeStream(InputStream is)
//     内存--->存储:bitmap.compress(Bitmap.CompressFormat.PNG,100,OutputStream os);
// 带回调的启动新的acitivity之后的回调方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == CAMERA && resultCode == RESULT_OK && data != null) {

// 拍照
Bundle bundle = data.getExtras();
// 获取相机返回的数据,并转换为图片格式
Bitmap bitmap = (Bitmap) bundle.get("data");
// bitmap圆形裁剪
bitmap = BitmapUtils.zoom(bitmap, DensityUtil.dp2px(this, 62), DensityUtil.dp2px(this, 62));
Bitmap circleBitmap = BitmapUtils.circleBitmap(bitmap);

//TODO 将图片上传到服务器的
ivIcon.setImageBitmap(circleBitmap);
// 将图片保存在本地
try {
saveImage(circleBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else if (requestCode == PICTURE && resultCode == RESULT_OK && data != null) {
//图库
Uri selectedImage = data.getData();
//这里返回的uri情况就有点多了
//**:在4.4.2之前返回的uri是:content://media/external/images/media/3951或者file://....在4.4.2返回的是content://com.android.providers.media.documents/document/image:3951或者
//总结:uri的组成,eg:content://com.example.project:200/folder/subfolder/etc
//content:--->"scheme"
//com.example.project:200-->"host":"port"--->"authority"[主机地址+端口(省略) =authority]
//folder/subfolder/etc-->"path" 路径部分
//android各个不同的系统版本,对于获取外部存储上的资源,返回的Uri对象都可能各不一样,所以要保证无论是哪个系统版本都能正确获取到图片资源的话
//就需要针对各种情况进行一个处理了
String pathResult = getPath(selectedImage);

Bitmap decodeFile = BitmapFactory.decodeFile(pathResult);
Bitmap zoomBitmap = BitmapUtils.zoom(decodeFile, DensityUtil.dp2px(this, 62), DensityUtil.dp2px(this, 62));
// bitmap圆形裁剪p
Bitmap circleImage = BitmapUtils.circleBitmap(zoomBitmap);
// 真实项目当中,是需要上传到服务器的..这步我们就不做了。
ivIcon.setImageBitmap(circleImage);
try {
// 保存图片到本地
saveImage(circleImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

// 将修改后的图片保存在本地存储中:storage/sdcard/Android/data/应用包名/files/xxx.png
private void saveImage(Bitmap bitmap) throws FileNotFoundException {

String path = this.getCacheDir() + "/tx.png";
Log.e("TAG", "path = " + path);
try {
FileOutputStream fos = new FileOutputStream(path);
// bitmap压缩(压缩格式、质量、压缩文件保存的位置)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

} catch (FileNotFoundException e) {
e.printStackTrace();
}

//        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//
//            File externalFilesDir = this.getExternalFilesDir(null);
//            File file = new File(externalFilesDir, "icon.png");
//            // 将Bitmap持久化
//            circleBitmap.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(file));
//        }
}

// 根据系统相册选择的文件获取路径
@SuppressLint("NewApi")
private String getPath(Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
// 高于4.4.2的版本
if (sdkVersion >= 19) {
Log.e("TAG", "uri auth: " + uri.getAuthority());
if (isExternalStorageDocument(uri)) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(this, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];

Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(this, contentUri, selection, selectionArgs);
} else if (isMedia(uri)) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor actualimagecursor = this.managedQuery(uri, proj, null, null, null);
int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
actualimagecursor.moveToFirst();
return actualimagecursor.getString(actual_image_column_index);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(this, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}

private String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}

private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}

public static boolean isMedia(Uri uri) {
return "media".equals(uri.getAuthority());
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}


欢迎大家批评指正,如果对你有帮助的话请给我小小的点个赞也算是对我的鼓励…
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android