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

简介: 上篇说道,构思这个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仅讲述了一小部分逻辑,不过对于用户而言确实重要。

相关文章
|
2天前
|
Java Android开发
android 下载图片的问题
android 下载图片的问题
13 3
|
2天前
|
Android开发
Android通过手势(多点)缩放和拖拽图片
Android通过手势(多点)缩放和拖拽图片
13 4
|
2天前
|
Java Android开发
Android12 双击power键启动相机源码解析
Android12 双击power键启动相机源码解析
28 0
|
2天前
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
|
1天前
|
监控 Java 测试技术
【企业场景】常见技术场景解析
【企业场景】常见技术场景解析
9 0
|
2天前
|
安全 程序员 网络安全
解析编程中的技术迷题:常见挑战与应对策略
解析编程中的技术迷题:常见挑战与应对策略
6 1
|
2天前
|
人工智能 IDE Devops
通义灵码技术解析,打造 AI 原生开发新范式
本文第一部分先介绍 AIGC 对软件研发的根本性影响,从宏观上介绍当下的趋势;第二部分将介绍 Copilot 模式,第三部分是未来软件研发 Agent 产品的进展。
|
2天前
|
机器学习/深度学习 人工智能 算法
构建高效AI系统:深度学习优化技术解析
【5月更文挑战第12天】 随着人工智能技术的飞速发展,深度学习已成为推动创新的核心动力。本文将深入探讨在构建高效AI系统中,如何通过优化算法、调整网络结构及使用新型硬件资源等手段显著提升模型性能。我们将剖析先进的优化策略,如自适应学习率调整、梯度累积技巧以及正则化方法,并讨论其对模型训练稳定性和效率的影响。文中不仅提供理论分析,还结合实例说明如何在实际项目中应用这些优化技术。
|
2天前
|
负载均衡 关系型数据库 MySQL
MySQL读写分离技术深度解析
在高并发、大数据量的互联网应用环境中,数据库作为数据存储的核心组件,其性能直接影响着整个系统的运行效率。MySQL作为最常用的开源关系型数据库之一,虽然功能强大,但在处理大量并发读写请求时,单点服务器的性能瓶颈逐渐显现。为了解决这一问题,MySQL读写分离技术应运而生,成为提升数据库性能、实现负载均衡的有效手段。
|
2天前
|
存储 SQL 自然语言处理
RAG技术全解析:打造下一代智能问答系统
一、RAG简介 大型语言模型(LLM)已经取得了显著的成功,尽管它们仍然面临重大的限制,特别是在特定领域或知识密集型任务中,尤其是在处理超出其训练数据或需要当前信息的查询时,常会产生“幻觉”现象。为了克服这些挑战,检索增强生成(RAG)通过从外部知识库检索相关文档chunk并进行语义相似度计算,增强了LLM的功能。通过引用外部知识,RAG有效地减少了生成事实不正确内容的问题。RAG目前是基于LLM系统中最受欢迎的架构,有许多产品基于RAG构建,使RAG成为推动聊天机器人发展和增强LLM在现实世界应用适用性的关键技术。 二、RAG架构 2.1 RAG实现过程 RAG在问答系统中的一个典型
49 2

推荐镜像

更多