自定义dialog弹出布局,并保存到相册,并适当裁剪

项目近期上线,现在有时间来进行简单的整理。这里记录一下在项目中用到的一个功能---保存bitmap并裁剪后保存到相册。

需求如下:点击分享链接底部的分享二维码,弹出一个带二维码的窗口。然后点击下面保存图片到相册,保存图片到相册。

自动截取上部分,文字不保存。


布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <FrameLayout
        android:layout_width="900px"
        android:layout_height="1200px"
        >

        <RelativeLayout

            android:layout_width="wrap_content"
            android:background="#fff"
            android:layout_height="wrap_content">
            <RelativeLayout
                android:id="@+id/rl_logo_title"
                android:layout_width="match_parent"
                android:background="@mipmap/home_titlebar_background"
                android:layout_height="400px">
                <com.shop718.guozhen.wd.weiget.ZQImageViewRoundOval
                    android:id="@+id/iv_shop_pop_logo"
                    android:layout_width="180px"
                    android:layout_height="180px"
                    android:layout_marginTop="60px"
                    android:layout_centerHorizontal="true"
                    android:elevation="20px"
                    android:src="@mipmap/category_avatar" />
                <TextView
                    android:layout_marginTop="20px"
                    android:id="@+id/tv_shop_user_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/iv_shop_pop_logo"
                    android:layout_centerHorizontal="true"
                    android:textColor="#fff"
                    android:gravity="center"
                    android:text="张晓玲的店"/>
                <TextView
                    android:layout_marginTop="20px"
                    android:id="@+id/tv_shop_user_wel"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_below="@+id/tv_shop_user_name"
                    android:layout_centerHorizontal="true"
                    android:textColor="#fff"
                    android:text="欢迎光临我的云店"/>
            </RelativeLayout>
            <ImageView
                android:id="@+id/iv_bg_suspend"
                android:layout_width="400px"
                android:layout_height="400px"
                android:src="@mipmap/category_avatar"
                android:layout_marginTop="100px"
                android:layout_centerHorizontal="true"
                android:layout_below="@+id/rl_logo_title"
                android:scaleType="fitXY"/>
            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="#000000"
                android:layout_below="@+id/iv_bg_suspend"
                android:layout_marginTop="100px"/>
            <TextView
                android:id="@+id/btn_suspend"
                android:layout_width="wrap_content"
                android:layout_height="80px"
                android:layout_marginTop="200px"
                android:textSize="20sp"
                android:layout_below="@+id/iv_bg_suspend"
                android:text="保存图片到相册"
                android:textColor="@color/colorPrimaryDark"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true" />
        </RelativeLayout>

    </FrameLayout>

</FrameLayout>

接下来就是功能实现了。分为俩部分,一个是生成二维码。对应生成二维码的点击事件,还有一个是保存图片到相册的点击事件。

 //生成二维码布局
    public void getXmlToBitmap(String url) {
        Resources res = MainActivity.this.getResources();
        Bitmap bmp = BitmapFactory.decodeResource(res, R.mipmap.youxuan_icon);
        //TODO 生成二维码 商品的链接
        final Bitmap invoker = EncodingHandler.enCodeStringWithLogo(url, this, bmp, 500);
        //加载xml布局文件
        final Dialog dia = new Dialog(this, R.style.edit_AlertDialog_style);
        LayoutInflater factory = LayoutInflater.from(this);
        final View view = factory.inflate(R.layout.pop_active_home, null);
        dia.setContentView(view);
        //获得布局文件中的TextView
        final TextView btnStart = (TextView) view.findViewById(R.id.btn_suspend);
        final TextView tvShopUserName = (TextView) view.findViewById(R.id.tv_shop_user_name);
        final TextView tbShopUserWel = (TextView) view.findViewById(R.id.tv_shop_user_wel);
        final ImageView shopLogo = (ImageView) view.findViewById(R.id.iv_shop_pop_logo);
        final ImageView ivbg = (ImageView) view.findViewById(R.id.iv_bg_suspend);

        if (manager != null && manager.getF_shop_name() != null) {
            tvShopUserName.setText(manager.getF_shop_name());
            tbShopUserWel.setText(manager.getF_welcome_inf());
            Glide.with(this)
                    .load(UrlUtils.getImageUrl(manager.getF_logo()))
                    .asBitmap()
                    .error(R.mipmap.category_avatar)
                    .into(new SimpleTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                            shopLogo.setImageBitmap(resource);
                            ivbg.setImageBitmap(invoker);
                            //启用绘图缓存
                            view.setDrawingCacheEnabled(true);
                            //调用下面这个方法非常重要,如果没有调用这个方法,得到的bitmap为null
                            view.measure(View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.UNSPECIFIED),
                                    View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED));
                            //这个方法也非常重要,设置布局的尺寸和位置
                            view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
                            //获得绘图缓存中的Bitmap
                            view.buildDrawingCache();
                            final Bitmap bitmap = view.getDrawingCache();
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                                bitmap.setHeight(bitmap.getHeight() - (bitmap.getHeight() / 6));
                            }
                            btnStart.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    btnStart.setVisibility(View.GONE);
                                    saveImageToGallery(MainActivity.this, bitmap);
                                    dia.cancel();// 关闭弹出框
                                }
                            });
                        }

                        @Override
                        public void onLoadFailed(Exception e, Drawable errorDrawable) {
                            super.onLoadFailed(e, errorDrawable);
//                            Toast.makeText(MainActivity.this,  e.getMessage(), Toast.LENGTH_SHORT).show();
                            Intent intent = new Intent(MainActivity.this, MainActivity.class);
                            startActivity(intent);
                            ToastUtils.showShort(MainActivity.this, "请先设置头像");
                        }
                    });

        }
        dia.show();
        dia.setCanceledOnTouchOutside(true);
        Window w = dia.getWindow();
        WindowManager.LayoutParams lp = w.getAttributes();
        lp.x = 0;
        lp.y = 40;
        dia.onWindowAttributesChanged(lp);
    }

因为本人属于菜鸟,所以写的有点啰嗦。能看懂就行。也遇到了不少问题

f (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                                bitmap.setHeight(bitmap.getHeight() - (bitmap.getHeight() / 6));
                            }

这段代码是进行裁剪。首先判断版本。然后对最终生成的布局的bitmap进行高度设置。这样写起来,他会更好的适应不同手机屏幕。。算是百分比来的?

最后一步保存图片到相册。也是写好的方法。

 //保存文件到系统相册
    public static boolean saveImageToGallery(Context context, Bitmap bmp) {
        // 首先保存图片
        String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "guozhen";
        File appDir = new File(storePath);
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            //通过io流的方式来压缩保存图片
            boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
            fos.flush();
            fos.close();

            //把文件插入到系统图库
            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
            //保存图片后发送广播通知更新数据库
            Uri uri = Uri.fromFile(file);
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
            if (isSuccess) {
                ToastUtils.showShort(context, "二维码图片已保存在手机相册");
                return true;
            } else {
                ToastUtils.showShort(context, "保存失败");
                return false;
            }
        } catch (IOException e) {
            ToastUtils.showShort(context, "保存失败");
            e.printStackTrace();
        }
        return false;
    }
注释的都很细。io流读取,然通知广播更新图库,这个方法是在网上找的,自己稍加改动,很好用。
安卓可以通过继承 Dialog 类,自定义底部选择器的样式和内容,然后在 Dialog 中实现底部弹出的效果。以下是一个简单的示例: 1. 首先,在 res/layout 目录下新建一个布局文件(例如:custom_picker_layout.xml),用来定义选择器的样式和内容; 2. 创建一个继承自 Dialog 类的自定义 Dialog 对象(例如:CustomPickerDialog),并在其中实现底部弹出的效果; 3. 在 CustomPickerDialog 中加载布局文件,并设置 Dialog 的宽度和高度,以及弹出的位置(例如:底部居中); 4. 显示 CustomPickerDialog。 示例代码如下: ```java public class CustomPickerDialog extends Dialog { public CustomPickerDialog(Context context) { super(context, R.style.BottomDialogStyle); // 加载自定义布局文件 View view = LayoutInflater.from(context).inflate(R.layout.custom_picker_layout, null); // 设置 Dialog 的内容 setContentView(view); // 设置 Dialog 的属性 Window window = getWindow(); if (window != null) { // 设置 Dialog 的宽度和高度 WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; window.setAttributes(layoutParams); // 设置 Dialog弹出位置(底部居中) window.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); // 设置 Dialog 的动画效果 window.setWindowAnimations(R.style.BottomDialogAnimation); } } } ``` 注意:上述示例代码中的 BottomDialogStyle 和 BottomDialogAnimation 分别是自定义Dialog 样式和动画效果,可以根据实际情况替换为对应的样式和动画。另外,弹出底部的选择器也可以使用 PopupWindow 实现,具体实现方式类似。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值