Android调整第三方库PickerView宽高--回忆录

news2024/12/23 19:21:07

一、效果

  // 时间选择
    implementation 'com.contrarywind:Android-PickerView:4.1.9'

多年前,使用到事件选择器,但是PickerView默认宽度使满屏的,不太符合业务需求,当时为此花了许多时间,最终找到了解决方案,就是把PickerView添加到弹框中,可以任意调整PickerView的宽高,说干就干,下面使源码。

二、新建以一个对话框布局

1.文件名称custom_picker_dialog.xml,源代码如下

       修改布局的宽高如下

        android:layout_width="@dimen/dp_300"
        android:layout_height="@dimen/dp_160"

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/picker_container"
        android:layout_width="@dimen/dp_300"
        android:layout_height="@dimen/dp_160"
        android:background="@drawable/bg_alarm_dialog_sp"
        android:orientation="vertical">

</LinearLayout>

2.自定义样式

   <style name="CustomDialog" parent="Theme.AppCompat.Dialog">
        <item name="android:windowNoTitle">true</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowBackground">@drawable/bg_alarm_dialog_sp</item> <!-- 透明背景 -->
        <item name="android:windowIsFloating">true</item>
        <!-- 这里不能直接设置宽度,但可以通过Dialog的内容布局来控制 -->
    </style>

三、java代码部分

1.弹框与数据处理



    /**
     * 初始化
     * 数据
     */
    //日历上午下午数据集合
    private final List<String> options1Items = new ArrayList<>();
    //日历小时数据集合
    private final List<List<String>> options2Items = new ArrayList<>();
    //日历分钟数据集合
    private final List<List<List<String>>> options3Items = new ArrayList<>();

    private void initDateTimeData() {

        //加入第一个列表数据
        options1Items.add("上午");
        options1Items.add("下午");

        List<String> a = new ArrayList<>();
        List<String> b = new ArrayList<>();
        List<List<String>> c = new ArrayList<>();

        //创建最后一个列表数据(分)
        for (int i = 0; i < 60; i++) {
            if (i < 10) {
                a.add("0" + i + "分");
            } else {
                a.add(i + "分");
            }
        }

        //创建第二个列表数据(时),同时将最后一个列表数据加入c,加入次数为第二个列表的大小
        for (int i = 0; i <= 12; i++) {
            if (i < 10) {
                b.add("0" + i + "时");
            } else {
                b.add(i + "时");
            }
            c.add(a);
        }

        //将第二个列表数据加入options2Itmes,加入次数为options1Items的大小
        for (int j = 0; j < options1Items.size(); j++) {
            options2Items.add(b);
        }

        //将第三个列表数据加入options3Items,加入次数为第二个列表数据的长度
        for (int i = 0; i < b.size(); i++) {
            options3Items.add(c);
        }

    }

    /**
     * 显示时间选择对话框
     */
    private void showDialogTimePicker() {
        // 假设你已经有了上下文context、数据data等
        // 使用自定义的Dialog样式(如果需要)
        Dialog dialog = new Dialog(this, R.style.CustomDialog);
        OptionsPickerView pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int options2, int options3, View v) {
                String date = options1Items.get(options1) + " " + options2 + "时 " + options3 + "分";
                Logger.d("=======在此获取选择到的内容==111========");
                dialog.cancel();
            }
        })
                .setTitleText("")
                .setTitleSize(10)
                .addOnCancelClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.cancel();
                    }
                })
                .setContentTextSize(12)
                .build();

        pvOptions.setPicker(options1Items, options2Items, options3Items);

//        pvOptions.show();


        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.custom_picker_dialog);
        LinearLayout pickerContainer = dialog.findViewById(R.id.picker_container);
        // 将OptionsPickerView添加到容器中
        pickerContainer.addView(pvOptions.getDialogContainerLayout().getRootView());

        Window window = dialog.getWindow();
        window.setGravity(Gravity.BOTTOM);

        WindowManager.LayoutParams params = window.getAttributes();
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.y = 8;//设置与底部距离
        window.setAttributes(params);

        // 显示Dialog
        dialog.show();
    }

核心方法,就是在这里把OptionsPickerView加载到对话框当中

   // 将OptionsPickerView添加到容器中
        pickerContainer.addView(pvOptions.getDialogContainerLayout().getRootView());

  由于时间选择对话框位于dialog里面,故本身的取消与确定无法关闭dialog,故需要在以下方法中调用  dialog.cancel();关闭弹框。

 public void onOptionsSelect(int options1, int options2, int options3, View v) {
                String date = options1Items.get(options1) + " " + options2 + "时 " + options3 + "分";
                Logger.d("=======在此获取选择到的内容==111========");
                dialog.cancel();
            }
        })
                .setTitleText("")
                .setTitleSize(10)
                .addOnCancelClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.cancel();
                    }
                })

2.调用方式

 /**
     * 事件处理
     */
    private void initEventListener() {

        mDataBinding.fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialogTimePicker();
            }
        });
    }

四、附上dialog各种弹出动画

1.从上往下弹出: (包含了2种实现方式一种是基于放大效果的,一种是基于平移方式的,可以自己放开注释看效果;需要在res下新建anim文件夹用于存放动画文件)

<style name="AnimTop" parent="@android:style/Animation">
    <!--进入动画-->
    <item name="android:windowEnterAnimation">@anim/dialog_top_in</item>
    <!--退出动画-->
    <item name="android:windowExitAnimation">@anim/dialog_top_out</item>
</style>
进入动画:dialog_top_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fillAfter="true">
    <!-- 自上向下滑入 -->
<!--    pivotY 原点y坐标加上自身高度的百分之百 的位置-->
<!-- 放大动画实现-->
    <scale
        android:fromXScale="1"
        android:toXScale="1"
        android:fromYScale="0"
        android:toYScale="1"
        android:pivotX="0"
        android:pivotY="0"/>
<!--平移动画实现-->
<!--    <translate-->
<!--        android:fromXDelta="1"-->
<!--        android:fromYDelta="-100%p"-->
<!--        android:toXDelta="1"-->
<!--        android:toYDelta="0" />-->

</set>
退出动画:dialog_top_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fillAfter="false">
    <!-- 自下向上滑出 -->
<!-- 放大动画-->
        <scale
            android:fromXScale="1"
            android:toXScale="1"
            android:fromYScale="1"
            android:toYScale="0"
            android:pivotX="0"
            android:pivotY="0" />
<!--平移动画-->
<!--    <translate-->
<!--        android:fromXDelta="1"-->
<!--        android:fromYDelta="0"-->
<!--        android:toXDelta="1"-->
<!--        android:toYDelta="-100%p" />-->

</set>
2.从下往上弹出:

 <style name="AnimBottom" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/dialog_bottom_in</item>
        <item name="android:windowExitAnimation">@anim/dialog_bottom_out</item>
    </style>
底部弹出进入动画: dialog_bottom_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200">
    <!-- 自下向上滑入 -->
<!--        <translate-->
<!--            android:fromYDelta="100%p"-->
<!--            android:toYDelta="0" />-->

    <!--    fromYScale、pivotY 和Y坐标无关只是单纯的缩放-->
    <scale
        android:fromXScale="1"
        android:fromYScale="0"
        android:pivotX="0"
        android:pivotY="100%"
        android:toXScale="1"
        android:toYScale="1" />

</set>
底部弹出退出动画: dialog_bottom_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200">
    <!-- 自下向上滑出 -->
<!--        <translate-->
<!--            android:fromYDelta="0"-->
<!--            android:toYDelta="100%p" />-->

    <scale
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="0"
        android:pivotY="100%"
        android:toXScale="1"
        android:toYScale="0" />
</set>
 

3.从左往右弹出:

 <style name="AnimLeft" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/dialog_left_in</item>
        <item name="android:windowExitAnimation">@anim/dialog_left_out</item>
    </style>
进入动画:dialog_left_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:fromXDelta="-100%p"
            android:toXDelta="0"
            android:duration="300"/>

    <!-- pivotX 可以是   -->
<!--    <scale-->
<!--        android:fromXScale="0"-->
<!--        android:fromYScale="1"-->
<!--        android:pivotX="0"-->
<!--        android:pivotY="0"-->
<!--        android:toXScale="1"-->
<!--        android:toYScale="1" />-->

</set>
退出动画:dialog_left_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300">

        <translate
            android:fromXDelta="0"
            android:toXDelta="-100%p" />

<!--    <scale-->
<!--        android:fromXScale="1"-->
<!--        android:fromYScale="1"-->
<!--        android:toXScale="0"-->
<!--        android:toYScale="1"-->
<!--        android:pivotX="0"-->
<!--        android:pivotY="0"/>-->
</set>
 

4.从右往左弹出:

  <style name="AnimRight" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/dialog_right_in</item>
        <item name="android:windowExitAnimation">@anim/dialog_right_out</item>
    </style>
进入动画:dialog_right_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:fromXDelta="100%p"
            android:toXDelta="0"
            android:duration="300"/>

    <!-- pivotX 可以是数字、百分比
    50px表示原点坐标加上50即是控件的x位置
    50%表示原点坐标加上控件自身的50%
    50%p 表示原点位置加上父控件的50%  -->
<!--    <scale-->
<!--        android:fromXScale="0"-->
<!--        android:fromYScale="1"-->
<!--        android:pivotX="100%"-->
<!--        android:pivotY="0"-->
<!--        android:toXScale="1"-->
<!--        android:toYScale="1" />-->

</set>
退出动画:dialog_right_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

        <translate
            android:fromXDelta="0"
            android:toXDelta="100%p"
            android:duration="300"/>

<!--    <scale-->
<!--        android:fromXScale="1"-->
<!--        android:fromYScale="1"-->
<!--        android:toXScale="0"-->
<!--        android:toYScale="1"-->
<!--        android:pivotX="100%"-->
<!--        android:pivotY="0"/>-->
</set>
5.从中间弹出:

    <style name="AnimCenter" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/dialog_center_in</item>
        <item name="android:windowExitAnimation">@anim/dialog_center_out</item>
    </style>
进入动画:dialog_center_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200">
    <!--    若均为 0% 或 0.0 ,起始点为 View 左上角;
            均为 50% 或 0.5 ,起始点为控件中心点;
            均为100% 或 1.0 ,起始点是 View 右下角。-->
    <!--    100%p会下移一个单位-->
    <scale
        android:fromXScale="0"
        android:fromYScale="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1" />
</set>
退出动画:dialog_center_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200">
    <scale
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0"
        android:toYScale="0" />
</set>

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2108762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二维高斯函数的两种形式

第一种形式很常见 多元正态分布 多元正态分布&#xff08;Multivariate Normal Distribution&#xff09;&#xff0c;也称为多变量正态分布或多维正态分布&#xff0c;是统计学中一种重要的概率分布&#xff0c;用于描述多个随机变量的联合分布。 假设有 n n n 个随机变量…

自己设计的QT系统,留个档

注册登录 主界面展示 天气预报 音乐播放

卷积神经网络与小型全连接网络在MNIST数据集上的对比

卷积神经网络&#xff08;CNN&#xff09; 深度卷积神经网络中&#xff0c;有如下特性 很多层&#xff08;Compositionality&#xff0c;组合性&#xff09;: 深度卷积神经网络通常由多层卷积和非线性激活函数组成。这种多层结构使得网络能够逐步提取和组合低层次的特征&…

shell 学习笔记:数组

目录 1. 定义数组 2. 读取数组元素值 3. 关联数组 4. 在数组前加一个感叹号 ! 可以获取数组的所有键 5. 在数组前加一个井号 # 获取数组的长度 6. 数组初始化的时候&#xff0c;也可以用变量 7. 循环输出数组的方法 7.1 for循环输出 7.2 while循环输出 7.2.1 …

大数据-120 - Flink Window 窗口机制-滑动时间窗口、会话窗口-基于时间驱动基于事件驱动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Redis实战宝典:开发规范与最佳实践

目录标题 Key命名设计&#xff1a;可读性、可管理性、简介性Value设计&#xff1a;拒绝大key控制Key的生命周期&#xff1a;设定过期时间时间复杂度为O(n)的命令需要注意N的数量禁用命令&#xff1a;KEYS、FLUSHDB、FLUSHALL等不推荐使用事务删除大key设置合理的内存淘汰策略使…

Java | Leetcode Java题解之第387题字符串中的第一个唯一字符

题目&#xff1a; 题解&#xff1a; class Solution {public int firstUniqChar(String s) {Map<Character, Integer> position new HashMap<Character, Integer>();Queue<Pair> queue new LinkedList<Pair>();int n s.length();for (int i 0; i …

【python因果推断库8】工具变量回归与使用 pymc 验证工具变量1

目录 工具变量回归与使用 pymc 验证工具变量 回归机制与局部平均处理效应 旁白&#xff1a;从多元正态分布中采样 import arviz as az import daft import matplotlib.pyplot as plt import numpy as np import pandas as pd import pymc as pm import scipy from matplotli…

如何阅读PyTorch文档及常见PyTorch错误

如何阅读PyTorch文档及常见PyTorch错误 文章目录 如何阅读PyTorch文档及常见PyTorch错误阅读PyTorch文档示例常见Pytorch错误Tensor在不同设备上维度不匹配cuda内存不足张量类型不匹配 参考 PyTorch文档查看https://pytorch.org/docs/stable/ torch.nn -> 定义神经网络 torc…

红队攻防 | 利用GitLab nday实现帐户接管

在一次红队任务中&#xff0c;目标是一家提供VoIP服务的公司。该目标拥有一些重要的客户&#xff0c;如政府组织&#xff0c;银行和电信提供商。该公司要求外部参与&#xff0c;资产测试范围几乎是公司拥有的每一项互联网资产。 第一天是对目标进行信息收集。这一次&#xff0…

结构开发笔记(七):solidworks软件(六):装配摄像头、摄像头座以及螺丝,完成摄像头结构示意图

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/141931518 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

成功之路:如何获得机器学习和数据科学实习机会

一年内获得两份实习机会的数据科学家的建议和技巧 欢迎来到雲闪世界。在当今竞争激烈的就业市场中&#xff0c;获得数据科学实习机会可以成为您在科技领域取得成功的门票。 但申请者如此之多&#xff0c;你该如何脱颖而出呢&#xff1f; 无论您是学生、应届毕业生还是想要转行…

IDEA2024.2最新工具下载

​软件使用 1、解压缩包 2、打开如图第三个 3、运行过十来秒等待提示以下信息即可

Ubuntu 无法全局安装 node 包

Anchor: $: cat /etc/lsb* DISTRIB_IDUbuntu DISTRIB_RELEASE22.04 DISTRIB_CODENAMEjammy DISTRIB_DESCRIPTION"Ubuntu 22.04.4 LTS" $: node -v v20.17.0 $: npm -v 10.8.2Question: $: npm install -g docsify-cli结果&#xff1a;超时或者如下图 Answer: 有…

【Python 千题 —— 算法篇】字符串替换

Python 千题持续更新中 …… 脑图地址 &#x1f449;&#xff1a;⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 在日常编程中&#xff0c;我们经常会遇到需要对字符串中的特定字符或子串进行替换的需求。比如&#xff0c;替换文本中的敏感词汇、…

html初体验标准标签

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title> </head> <body><input type"text"> </body> </html> 内容展示

C和Java实现杨辉三角

C: #include <stdio.h> #define N 15 int main() {int arr[N][N] { 0 }; //初始化int i 0;//行数int j 0;//列数for (i 0; i < N; i){arr[i][0] 1; //每行首元素是 1for (j 0; j < i; j)//为啥j<i呢&#xff1f;因为每一行的个数&#xff08;每一列多少个…

爵士编曲:如何编写爵士钢琴

排列&#xff08;Voicing&#xff09; 由于爵士和声组成音较为复杂&#xff0c;故此衍声排列内容 密集排列&#xff1a;直接堆一起或者左手低音右手和弦音 。 开放排列&#xff1a;各个声部大于等于纯四度&#xff0c;小于八度&#xff0c;符合两只手能弹的情况 混合排列&a…

Python | Leetcode Python题解之第388题文件的最长绝对路径

题目&#xff1a; 题解&#xff1a; class Solution:def lengthLongestPath(self, input: str) -> int:ans, i, n 0, 0, len(input)level [0] * (n 1)while i < n:# 检测当前文件的深度depth 1while i < n and input[i] \t:depth 1i 1# 统计当前文件名的长度l…

深入CSS 布局——WEB开发系列29

CSS 页面布局技术允许我们拾取网页中的元素&#xff0c;并且控制它们相对正常布局流、周边元素、父容器或者主视口/窗口的位置。 一、正常布局流&#xff08;Normal Flow&#xff09; CSS的布局基础是“正常流”&#xff0c;也就是页面元素在没有特别指定布局方式时的默认排列…