“千变万化”——神奇的Android图片规格调整器(dialog技术解析篇)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 上篇说道,构思这个app时发现了很多平时未注意的问题,其中以Dialog弹窗为第一拦路虎,一方面是自己的技术不够成熟,一方面是自己平时未多多深入阅读。

正篇

本文将对我的dialog代码进行分析,希望可以进一步理解这里面的机制,从而实现自己需要的dialog.

代码风暴

public class PopupDialogFragment extends DialogFragment {
  public static final String ARG_LAYOUT = "arg_layout";
  public static final String ARG_GRAVITY = "arg_gravity";
  int mLayout;
  int mGravity = Gravity.CENTER;
  protected View mView;
  public static DialogFragment newInstance(int layout, int gravity) {
    PopupDialogFragment fragment = new PopupDialogFragment();
    fragment.setArgs(layout, gravity);
    return fragment;
  }
  public void setArgs(int layout, int gravity) {
    Bundle bundle = new Bundle();
    bundle.putInt(ARG_LAYOUT, layout);
    bundle.putInt(ARG_GRAVITY, gravity);
    setArguments(bundle);
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
      Bundle bundle = getArguments();
      mLayout = bundle.getInt(ARG_LAYOUT, 0);
      mGravity = bundle.getInt(ARG_GRAVITY, 0);
    }
  }
  @NonNull
  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = getActivity().getLayoutInflater();
    mView = inflater.inflate(mLayout, null);
    Dialog dialog = new Dialog(getActivity());
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(mView);
    dialog.setCanceledOnTouchOutside(true);
    Window window = dialog.getWindow();
    if (window != null) {
      window.setBackgroundDrawableResource(R.color.transparent);
      WindowManager.LayoutParams wlp = window.getAttributes();
      wlp.gravity = mGravity;
      wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
      wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
      window.setAttributes(wlp);
    }
    return dialog;
  }
}

首先,我先用从而构建了PopupDialogFragment类继承了 DialogFragment类,从而构建了PopupDialogFragment此类用于底部弹窗的显示父类,然后我需要一个点击后能出现选择相机和相册的弹窗,所以实现了DialogSelectImage这个具体类:

public class DialogSelectImage extends PopupDialogFragment {
    private AppCompatTextView tvCamera, tvGallery, tvCancel;
    private View.OnClickListener mOnCameraClickListener;
    private View.OnClickListener mOnGalleryClickListener;
    public DialogSelectImage setOnCameraClickListener(View.OnClickListener onCameraClickListener) {
        mOnCameraClickListener = onCameraClickListener;
        return this;
    }
    public DialogSelectImage setOnGalleryClickListener(View.OnClickListener onGalleryClickListener) {
        mOnGalleryClickListener = onGalleryClickListener;
        return this;
    }
    public static DialogSelectImage newInstance() {
        DialogSelectImage fragment = new DialogSelectImage();
        fragment.setArgs(R.layout.layout_page_dialog_select_image, Gravity.BOTTOM);
        return fragment;
    }
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        tvCamera = mView.findViewById(R.id.tvCamera);
        tvGallery = mView.findViewById(R.id.tvGallery);
        tvCancel = mView.findViewById(R.id.tvCancel);
        tvCamera.setOnClickListener(new ThrottleClickEventAbstract() {
            @Override
            public void onThrottleClick(View v) {
                if (mOnCameraClickListener != null) {
                    mOnCameraClickListener.onClick(v);
                }
                dismiss();
            }
        });
        tvGallery.setOnClickListener(new ThrottleClickEventAbstract() {
            @Override
            public void onThrottleClick(View v) {
                if (mOnGalleryClickListener != null) {
                    mOnGalleryClickListener.onClick(v);
                }
                dismiss();
            }
        });
        tvCancel.setOnClickListener(new ThrottleClickEventAbstract() {
            @Override
            public void onThrottleClick(View v) {
                dismiss();
            }
        });
        return dialog;
    }
}

其中这个属性决定了在底部显示:fragment.setArgs(R.layout.layout_page_dialog_select_image, Gravity.BOTTOM);

而现在进入相机或相册需要权限允许,所以又设置了openCamera()方法,通过点击事件去跳转征求用户的权限允许:

if (!NetConnectUtil.checkHasValidNet(mFragmentActivity)) {
                    ToastUtil.show(mFragmentActivity, R.string.str_unable_conn_network);
                    return;
                }
                FragmentTransaction fragmentTransaction = mFragmentActivity.getSupportFragmentManager().beginTransaction();
                fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                DialogSelectImage.newInstance()
                        .setOnCameraClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                openCamera();
                            }
                        })
                        .setOnGalleryClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                openGallery();
                            }
                        }).show(fragmentTransaction, "selectAvatar");

goCamera方法实现了拍照后回调,从而获取相关地址,本处代码是外层逻辑,内部逻辑是创建文件去存手机拍照文件,但这里getBitmap方法已经丢弃,需要想新的方法去实现:

private void goCamera(){
        final String path = BizFileUtil.getAccountImgPath(mFragmentActivity, userName) + System.currentTimeMillis() + ".jpg";
        ComponentSysUtil.goCamera((ActivityBase) mFragmentActivity, path, new IOnActivityResult() {
            @Override
            public void onActivityResult(int requestCode, int resultCode, final Intent data) {
                File file = new File(path);
                if (!file.exists()) {
                    XLog.d("onActivityResult: file not exist" + file);
                    return;
                }
                Bitmap bitmap = null;
                try {
                    XLog.d("get Camera bitmap ");
                    bitmap = MediaStore.Images.Media.getBitmap(mFragmentActivity.getContentResolver(), Uri.fromFile(new File(path)));
                } catch (IOException e) {
                    XLog.e("onActivityResult: E");
                    e.printStackTrace();
                }
                if (bitmap == null) {
                    XLog.d("Camera bitmap: null ");
                    return;
                }
            }
        });
    }

这个地方获取图片的地址或者URI,而MediaStore.Images.Media.getBitmap方法容易导致OOM,所以还是推荐使用图片压缩后展示。

小结

本节讲述了相机权限获取和相关弹窗的逻辑代码,下一节将继续分析代码,讲述图片坐标变化的使用,通过坐标更好的缩放bitmap。至此,本APP仅讲述了一小部分逻辑,不过对于用户而言确实重要。

相关文章
|
6天前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
37 20
Android经典面试题之图片Bitmap怎么做优化
|
3天前
|
机器学习/深度学习 算法
概率分布深度解析:PMF、PDF和CDF的技术指南
本文将深入探讨概率分布,详细阐述概率质量函数(PMF)、概率密度函数(PDF)和累积分布函数(CDF)这些核心概念,并通过实际示例进行说明。
32 15
概率分布深度解析:PMF、PDF和CDF的技术指南
|
10天前
|
机器学习/深度学习 人工智能 编解码
深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
【9月更文挑战第2天】深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
 深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
|
4天前
|
存储 关系型数据库 MySQL
技术解析:MySQL中取最新一条重复数据的方法
以上提供的两种方法都可以有效地从MySQL数据库中提取每个类别最新的重复数据。选择哪种方法取决于具体的使用场景和MySQL版本。子查询加分组的方法兼容性更好,适用于所有版本的MySQL;而窗口函数方法代码更简洁,执行效率可能更高,但需要MySQL 8.0及以上版本。在实际应用中,应根据数据量大小、查询性能需求以及MySQL版本等因素综合考虑,选择最合适的实现方案。
24 6
|
2天前
|
负载均衡 5G 网络性能优化
深入解析LTE(长期演进技术)的基本架构及其关键组件
深入解析LTE(长期演进技术)的基本架构及其关键组件
17 2
|
12天前
|
API 云计算 开发者
使用宜搭平台带来的便利:技术解析与实践
【9月更文第8天】随着企业信息化建设的不断深入,业务流程自动化的需求日益增长。宜搭平台作为一种高效的应用构建工具,为企业提供了快速搭建各类业务系统的可能。本文将探讨使用宜搭平台给企业和开发者带来的便利,并通过具体的代码示例展示其优势。
48 11
|
6天前
|
API Android开发 iOS开发
掌握安卓与iOS应用开发中的依赖注入技术
本文探讨了在安卓和iOS应用开发中,如何有效利用依赖注入技术来提升代码的模块化、可测试性和可维护性。通过对比分析两种平台下依赖注入的实现方式与工具,本文旨在为开发者提供一套清晰、实用的依赖管理策略,助力打造高质量软件产品。
|
8天前
|
存储 负载均衡 Java
Jetty技术深度解析及其在Java中的实战应用
【9月更文挑战第3天】Jetty,作为一款开源的、轻量级、高性能的Java Web服务器和Servlet容器,自1995年问世以来,凭借其卓越的性能、灵活的配置和丰富的扩展功能,在Java Web应用开发中占据了举足轻重的地位。本文将详细介绍Jetty的背景、核心功能点以及在Java中的实战应用,帮助开发者更好地理解和利用Jetty构建高效、可靠的Web服务。
22 2
|
2天前
|
搜索推荐 Linux Android开发
深入解析安卓与iOS系统架构设计差异
本文旨在探讨Android和iOS两大主流操作系统在架构设计上的根本差异。通过分析两种系统的设计理念、核心组件以及实际应用表现,揭示它们如何反映不同的开发哲学和用户体验策略。我们将从系统层级结构、内存管理机制、用户界面设计三个方面入手,逐一对比Android的开放性和灵活性如何与其对手iOS的封闭性和一致性相互辉映。
|
3天前
|
Android开发 Swift iOS开发
掌握安卓与iOS应用开发:关键技术与市场趋势
本文深入探讨了安卓和iOS平台的应用开发,通过分析关键技术如Kotlin、Swift及Flutter,并结合当前市场趋势,为开发者提供全面的技术指南。同时,比较了两大平台的优劣势,帮助开发者做出更明智的决策。

热门文章

最新文章

推荐镜像

更多