jjzjj

java - Android:如何更改日期选择器分隔线的颜色?

coder 2023-05-15 原文

我的 Android 应用程序中有一个日期选择器,但现在我想将蓝色分隔线的颜色更改为绿色(请参见本文下方的图片)。有some other discussions在 Stackoverflow 上谈论相同的内容,但没有一个给出导致解决方案的答案。

所以我自己去寻找,发现实际上有一个 android:datePickerStyle 并且还有一个 android:divider。但是,我不知道分隔符是否实际上是指日期选择器中的分隔符。我尝试了这两者的多种组合,但我似乎没有让它发挥作用。所以我的第一个问题: android:divider 是否引用 datepicker 中的分隔符,我如何使用它来更改颜色?

所以另一种选择应该是创建一个全新的自定义日期选择器。如果这使我能够更改分隔线的颜色,我很喜欢它。所以我看了一下some of the tutorials在创建自定义日期选择器时,但它们似乎都没有定义分隔线的颜色。分隔符根本没有在 xml 文件或 java 文件中列出。

如果有某种样板代码来重新创建当前显示的日期选择器,包括设置分隔线颜色的代码,那就太好了。希望这能让我复制它并在某处简单地更改分隔线的颜色设置。所以我的第二个问题:有人知道任何样板代码,它只是像现在一样简单地实现日期选择器(包括分隔符的定义)?

最佳答案

不幸的是,这不是一项简单的任务。
DatePickers使用小部件 NumberPickerCalendarView内部。例如,您发布的图像使用 3 NumberPickers .您所说的分隔符来自 NumberPicker 的属性:selectionDivider .问题是这个属性不是公开的,numberPickerStyle 也不是。 ,通过它设置这个属性。

我最近将 CalendarView 和 NumberPicker 向后移植到 API 8,主要是为了好玩。由于代码很容易获得(在 android 的源代码中查找 android.widget.NumberPicker 和其他代码),所有这些任务都需要时间,并且需要深入研究 android 的源代码。例子:

  • 简单 ==> 您必须将私有(private)变量从 View 类更改为它们的访问器方法

    mLeft(View 类中的 protected 变量)==> getLeft()(公共(public)访问器方法)
  • 最耗时的任务是恢复辅助功能方法。

  • 在任何情况下,如果您决定编写 DatePicker 的自定义实现,您还必须为 NumberPicker 和 CalendarView(可选)编写它们。

    更简单的方法:

    向后移植的 DatePicker 在此处作为库提供:Android-DatePicker .如上所述,您将使用向后移植的 CalendarViewNumberPicker与此 DatePicker 一起使用。

    您需要更改的内容:

    使用{library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png作为模板,并将“蓝色”颜色更改为绿色(我使用了 pixlr )。如果您想完全使用蓝色分隔线,您可以使用相同的名称保存它,或者使用不同的名称并在 {library-numberpicker} / res / values / themes.xml 中进行更改.
    themes.xml 中所需的更改如果您选择其他名称:
    <style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
        ....
        <item name="selectionDivider">@drawable/new_nine_path_drawable_name</item>
        ....
    </style>
    

    就是这样。

    使用库输出:



    编辑:

    Does the android:divider refer to the divider in the datepicker, and how could I use it to change color?



    属性 divider实际上来自LinearLayout . NumberPicker继承此属性为 NumberPicker extends LinearLayout .但是这个divider服务于不同的目的。传递给该属性的drawable被放置在LinearLayout的 subview 之间。 .

    属性 android:showDividers用于更改此分隔线的位置,可能的值为:
  • none:不显示分隔线
  • 开始:分隔线显示在第一个 subview 之前
  • 中间:在每个 subview 之后显示分隔线,而不是在最后一个 subview 之后显示
  • end:分隔线显示在最后一个 subview 之后

  • 属性 android:dividerPadding是不言自明的。

    即使 NumberPicker 继承了这个属性,它也不会使用它。从您自己的研究和试验中可以看出这一点:I tried a multitude of combinations of the two, but I don't seem to get it to work.
    要查看有效的分隔符属性:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:divider="@android:drawable/ic_media_play"
        android:showDividers="middle" >
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="World," />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Again" />
    
    </LinearLayout>
    

    使用 java 反射的 Hack-ish 解决方法:

    这个答案here给了我这个想法。我一般讨厌使用反射,主要是因为这个答案中列出的原因:Link .虽然为了完整起见我在这里列出它,但我建议你不要使用它。
    public class CDP extends android.widget.DatePicker {
    
        public CDP(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            Class<?> internalRID = null;
            try {
                internalRID = Class.forName("com.android.internal.R$id");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
            Field month = null;
            try {
                month = internalRID.getField("month");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            NumberPicker npMonth = null;
            try {
                npMonth = (NumberPicker) findViewById(month.getInt(null));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            Field day = null;
            try {
                day = internalRID.getField("day");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            NumberPicker npDay = null;
            try {
                npDay = (NumberPicker) findViewById(day.getInt(null));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            Field year = null;
            try {
                year = internalRID.getField("year");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            NumberPicker npYear = null;
            try {
                npYear = (NumberPicker) findViewById(year.getInt(null));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            Class<?> numberPickerClass = null;
            try {
                numberPickerClass = Class.forName("android.widget.NumberPicker");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
            Field selectionDivider = null;
            try {
                selectionDivider = numberPickerClass.getDeclaredField("mSelectionDivider");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            try {
                selectionDivider.setAccessible(true);
                selectionDivider.set(npMonth, getResources().getDrawable(
                           R.drawable.np_numberpicker_selection_divider_green));
                selectionDivider.set(npDay, getResources().getDrawable(
                           R.drawable.np_numberpicker_selection_divider_green));
                selectionDivider.set(npYear, getResources().getDrawable(
                           R.drawable.np_numberpicker_selection_divider_green));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (NotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    

    我们在这里做什么:
  • 扩展 DatePicker
  • 如果你打开 date_picker.xmlsdk/platforms/android-xx/res/layout ,您会看到三个 NumberPicker 的 id 为 month , day , year .我们访问android.internal.R.id获取这些 NumberPickers 的资源 ID。
  • 我们使用这些带有 findViewById(int) 的 ID 创建了三个 NumberPicker 对象。方法。
  • 然后,访问并检索字段 mSelectionDivider使用重选。
  • 将该字段设置为可访问(作为其声明的最终字段),使用 Field#set(Object, Object) 设置其值方法。第一个参数是我们执行此操作的对象。第二个参数是我们要设置的对象。

  • 我使用的drawable可以从以下位置下载:here .

    关于java - Android:如何更改日期选择器分隔线的颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20148671/

    有关java - Android:如何更改日期选择器分隔线的颜色?的更多相关文章

    1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

      我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

    2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    3. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

      如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

    4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

      给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

    6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

      我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

    7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

      我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

    8. ruby - 如何指定 Rack 处理程序 - 2

      Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

    9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

      在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

    10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

      我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

    随机推荐