“千变万化”——神奇的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仅讲述了一小部分逻辑,不过对于用户而言确实重要。

相关文章
|
7天前
|
安全 Android开发 iOS开发
安卓与iOS的较量:技术特性与用户体验的深度解析
在移动操作系统的战场上,安卓和iOS一直占据着主导地位。本文将深入探讨这两大平台的核心技术特性,以及它们如何影响用户的体验。我们将从系统架构、应用生态、安全性能和创新功能四个方面进行比较,帮助读者更好地理解这两个系统的异同。
34 3
|
2天前
|
机器学习/深度学习 人工智能 编解码
深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
【9月更文挑战第2天】深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
 深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
|
4天前
|
API 云计算 开发者
使用宜搭平台带来的便利:技术解析与实践
【9月更文第8天】随着企业信息化建设的不断深入,业务流程自动化的需求日益增长。宜搭平台作为一种高效的应用构建工具,为企业提供了快速搭建各类业务系统的可能。本文将探讨使用宜搭平台给企业和开发者带来的便利,并通过具体的代码示例展示其优势。
33 11
|
6天前
|
监控 网络协议 API
.NET WebSocket 技术深入解析,你学会了吗?
【9月更文挑战第4天】WebSocket 作为一种全双工协议,凭借低延迟和高性能特点,成为实时应用的首选技术。.NET 框架提供了强大的 WebSocket 支持,使实时通信变得简单。本文介绍 WebSocket 的基本概念、.NET 中的使用方法及编程模型,并探讨其在实时聊天、监控、在线游戏和协同编辑等场景的应用,同时分享最佳实践,帮助开发者构建高效实时应用。
44 12
|
4天前
|
定位技术 网络虚拟化 数据中心
VLAN与VXLAN技术解析:仅一字之差的深远区别
通过深入了解VLAN与VXLAN的技术细节和应用场景,网络工程师可以根据具体需求选择最合适的技术来优化网络架构。对于现代网络环境,尤其是大规模和多变的网络结构,理解并合理运用这些技术是提高网络效率和安全性的关键。
19 1
|
6天前
|
安全 Android开发 iOS开发
安卓与iOS的较量:技术特性与用户体验的深度剖析
在移动操作系统的战场上,安卓和iOS一直是两个重量级选手。本文将深入探讨两者的技术架构、安全性、应用生态以及用户体验等方面的差异,并尝试从用户和开发者的角度出发,分析这两个系统的优势与不足。通过比较,我们不仅能更好地理解各自的特点,还能洞察未来移动技术的发展趋势。
|
11天前
|
开发者 图形学 Java
揭秘Unity物理引擎核心技术:从刚体动力学到关节连接,全方位教你如何在虚拟世界中重现真实物理现象——含实战代码示例与详细解析
【8月更文挑战第31天】Unity物理引擎对于游戏开发至关重要,它能够模拟真实的物理效果,如刚体运动、碰撞检测及关节连接等。通过Rigidbody和Collider组件,开发者可以轻松实现物体间的互动与碰撞。本文通过具体代码示例介绍了如何使用Unity物理引擎实现物体运动、施加力、使用关节连接以及模拟弹簧效果等功能,帮助开发者提升游戏的真实感与沉浸感。
28 1
|
5天前
|
负载均衡 网络协议 安全
DNS解析中的Anycast技术:原理与优势
【9月更文挑战第7天】在互联网体系中,域名系统(DNS)将域名转换为IP地址,但网络规模的扩张使DNS解析面临高效、稳定与安全挑战。Anycast技术应运而生,通过将同一IP地址分配给多个地理分布的服务器,并依据网络状况自动选择最近且负载低的服务器响应查询请求,提升了DNS解析速度与效率,实现负载均衡,缓解DDoS攻击,增强系统高可用性。此技术利用动态路由协议如BGP实现,未来在网络发展中将扮演重要角色。
25 0
|
11天前
|
5G 网络架构
深入解析Wi-Fi中的MIMO技术及其优势
【8月更文挑战第31天】
44 0
|
11天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
61 0

热门文章

最新文章

推荐镜像

更多