Android的:如何更改日期选择器分压器的颜色? [英] Android: how to change the color of the datepicker divider?

查看:767
本文介绍了Android的:如何更改日期选择器分压器的颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的Andr​​oid应用程序一个日期选择器,但现在我想改变蓝色分隔线的颜色分为绿色(请参阅下面这段文字的图片)。有<一href="http://stackoverflow.com/questions/14849147/change-divider-color-android-datepicker-dialog">some <一href="http://stackoverflow.com/questions/12711212/how-to-change-android-datepicker-dialogs-dividers-colors">other <一href="http://stackoverflow.com/questions/11077530/how-to-change-the-default-color-of-datepicker-and-timepicker-dialog-in-android?rq=1">discussions在#1的谈论相同的,但没有人给出了导致解决方案的一个答案。

于是我去寻找我自己,发现居然还有一个机器人:datePickerStyle并且还有一个机器人:分频器。不知然而,分频器是否实际上是指分隔在日期选择器在所有。我尝试了许多两者的结合,但我似乎并没有得到它的工作。因此,我的第一个问题:是否在android:分指分在日期选择器,我怎么可以用它来改变颜色

那么另一个选择是大概是要创建一个完全新的自定义日期选择器。如果能让我只是改变了分我下来它的颜色。因此,我不得不看看一些 <一href="http://technet.weblineindia.com/mobile/how-to-implement-a-custom-datepicker-control-with-maximum-and-minimum-date-range-in-android-application/">of 教程中创建自定义日期选择器,但他们都不来定义分隔线的颜色。该分频器根本就不在XML文件或Java文件中列出。

这将是巨大的,如果会有某种形式的样板code重新创建日期选择器,因为它目前显示,包括code,用于设置分隔线的颜色。希望这将使我能够复制它,只是改变的地方分隔条的颜色设置。因此,我的第二个问题:?请问有人知道任何的样板code它只是实现了日期选择器,因为它是目前(包括分隔的定义)

解决方案

不幸的是,这不是一个简单的任务。

DatePickers NumberPicker CalendarView 内部使用的部件。例如,像您已发布使用3 NumberPickers 。而你所谈论的是来自NumberPicker的属性分频器: selectionDivider 。问题是,这个属性是不公开的,也不是 numberPickerStyle ,通过它,这个属性被设置。

我最近背移植CalendarView和NumberPicker到API 8,主要是为了好玩。由于code是现成的(查找 android.widget.NumberPicker 和其他Android的源代码),所有这些任务需要的时间,有的通过挖掘Android的源代码 - code。例如:

  1. 易==>你必须从View类的私有变量改变自己的存取方法

    MLEFT(在视图类保护变量)==> getLeft()(公共访问方法)

  2. 最耗时的任务是恢复辅助方法。

在任何情况下,如果你决定编写定制实现的DatePicker的,你必须写他们的NumberPicker和CalendarView(可选)为好。

更简单的方法:

开始,反向移植的DatePicker可以作为一个库在这里: Android系统的DatePicker 。正如上面提到的,你将使用回迁 CalendarView 和的在此的DatePicker一起NumberPicker

你需要改变什么:

使用 {库numberpicker} / RES /绘制-XXXX / np_numberpicker_selection_divider.9.png 为模板,并更改蓝的颜色为绿色(我用的 pixlr )。您可以将它保存使用相同的名称,如果你想用蓝色的分频器完全完成,或使用不同的名称,并在 {库numberpicker} / RES /价值/的themes.xml变化

如果你选择一个不同的名称的themes.xml 要求的变化:

 &LT;样式名称=NPWidget.Holo.NumberPicker父=NPWidget.NumberPicker&GT;
    ....
    &LT;项目名称=selectionDivider&GT; @可绘制/ new_nine_path_drawable_name&LT; /项目&GT;
    ....
&LT; /风格&GT;
 

这就是它。

输出使用的库:

编辑:

  

请问安卓分参考分频器的日期选择器,并   我怎么可以用它来改变颜色?

属性其实来自于的LinearLayout NumberPicker 继承这个属性为 NumberPicker扩展的LinearLayout 。但这种用于不同的目的。传递给这个属性的绘制放在了的LinearLayout 子视图之间。

属性安卓showDividers 来改变这个位置分的,可能的值是:

  • 无:无显示分频器
  • 开头:分频器的第一个子视图之前显示
  • 在中间:分频器每个子视图后表示,不是不是最后一个子视图后,
  • 结束:分频器的最后一个子视图后,显示

属性机器人:dividerPadding 是不言自明的。

尽管NumberPicker继承了这个属性,它不使用它。这是你自己的研究与明显;试验:我尝试了许多两者的结合,但我似乎并没有得到它的工作

要看到分隔属性在行动:

 &LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:方向=横向
    机器人:分隔=@机器人:可绘制/ ic_media_play
    机器人:showDividers =中间&GT;

    &LT;的TextView
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:文本=你好/&GT;

    &LT;的TextView
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:文字=世界/&GT;

    &LT;的TextView
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:文本=再次/&GT;

&LT; / LinearLayout中&GT;
 

砍十岁上下的解决方法使用Java反射:

这答案 给了我的想法。我讨厌使用恢复体力一般,多为在这个回答中列出的原因:链接。尽管我列出在这里为了完整起见,我的提示的你不使用它。

 公共类CDP扩展android.widget.DatePicker {

    公共CDP(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);

        类&LT;&GT; internalRID = NULL;
        尝试 {
            internalRID =的Class.forName(com.android.internal.R的$ id);
        }赶上(ClassNotFoundException异常E){
            e.printStackTrace();
        }

        实地月= NULL;
        尝试 {
            月= internalRID.getField(月);
        }赶上(NoSuchFieldException E){
            e.printStackTrace();
        }

        NumberPicker npMonth = NULL;
        尝试 {
            npMonth =(NumberPicker)findViewById(month.getInt(空));
        }赶上(抛出:IllegalArgumentException E){
            e.printStackTrace();
        }赶上(IllegalAccessException E){
            e.printStackTrace();
        }

        现场天= NULL;
        尝试 {
            天= internalRID.getField(天);
        }赶上(NoSuchFieldException E){
            e.printStackTrace();
        }

        NumberPicker npDay = NULL;
        尝试 {
            npDay =(NumberPicker)findViewById(day.getInt(空));
        }赶上(抛出:IllegalArgumentException E){
            e.printStackTrace();
        }赶上(IllegalAccessException E){
            e.printStackTrace();
        }

        实地年= NULL;
        尝试 {
            年= internalRID.getField(年);
        }赶上(NoSuchFieldException E){
            e.printStackTrace();
        }

        NumberPicker npYear = NULL;
        尝试 {
            npYear =(NumberPicker)findViewById(year.getInt(空));
        }赶上(抛出:IllegalArgumentException E){
            e.printStackTrace();
        }赶上(IllegalAccessException E){
            e.printStackTrace();
        }

        类&LT;&GT; numberPickerClass = NULL;
        尝试 {
            numberPickerClass =的Class.forName(android.widget.NumberPicker);
        }赶上(ClassNotFoundException异常E){
            e.printStackTrace();
        }

        现场selectionDivider = NULL;
        尝试 {
            selectionDivider = numberPickerClass.getDeclaredField(mSelectionDivider);
        }赶上(NoSuchFieldException E){
            e.printStackTrace();
        }

        尝试 {
            selectionDivider.setAccessible(真正的);
            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));
        }赶上(抛出:IllegalArgumentException E){
            e.printStackTrace();
        }赶上(NotFoundException E){
            e.printStackTrace();
        }赶上(IllegalAccessException E){
            e.printStackTrace();
        }
    }
}
 

我们在这里做的:

  • 扩展的DatePicker
  • 如果您打开 date_picker.xml SDK /平台/ Android的-XX / RES /布局,你'会看到这三个NumberPickers有ID 。我们访问 android.internal.R.id 来获得资源ID为这些NumberPickers。
  • 我们创建 findViewById(INT)方法使用这些ID 3 NumberPicker对象。
  • 然后,访问和检索字段 mSelectionDivider 利用云南财贸。
  • 将字段访问(作为其声明为final),使用字段号组(对象,对象)方法,将其值设置。第一个参数是我们进行此项操作对象。第二个参数是我们要设置的对象。
这里

我已经使用的绘制可以从以下网址下载

I've got a datepicker in my Android app, but now I want to change the color of the blue dividers into green (see the image below this text). There are some other discussions on Stackoverflow that talk about the same, but none of them gives an answer which leads to a solution.

So I went looking myself and found there is actually an android:datePickerStyle and there is also an android:divider. I don't know however, whether the divider is actually referring to the divider in the datepicker at all. I tried a multitude of combinations of the two, but I don't seem to get it to work. So my first question: Does the android:divider refer to the divider in the datepicker, and how could I use it to change color?

So another option is supposedly to create a fully new custom datepicker. If that enables me to just change the color of the divider I'm down for it. So I had a look at some of the tutorials on creating a custom datepicker, but none of them seem to define the color of the dividers. The dividers are simply not listed in the xml files or in the java files.

It would be great if there would be some kind of boilerplate code to recreate the datepicker as it currently displays, including the code that sets the color of the dividers. Hopefully that would enable me to copy it and simply change the color setting of the divider somewhere. So my second question: Would anybody know any boilerplate code which simply implements the datepicker as it is now (including a definition of the dividers)?

解决方案

Unfortunately, this is not a trivial task.

DatePickers use widgets NumberPicker and CalendarView internally. For instance, the image you have posted is using 3 NumberPickers. And the dividers you are talking about come from NumberPicker's attribute: selectionDivider. The problem is that this attribute is not public, and neither is numberPickerStyle, through which, this attribute is set.

I recently back-ported CalendarView and NumberPicker to API 8, mostly for fun. Since the code is readily available(look up android.widget.NumberPicker and others in android's source), all this task takes is time, and some digging through android's source-code. Examples:

  1. Easy ==> You'll have to change the private variable from View class to their accessor methods

    mLeft (protected variable in View class) ==> getLeft() (public accessor method)

  2. The most time-consuming task was restoring the Accessibility methods.

In any case, if you do decide on writing custom implementation of DatePicker, you'll have to write them for NumberPicker and CalendarView (optionally) as well.

Easier way:

Backported DatePicker is available as a library here: Android-DatePicker. As mentioned above, you'll be using backported CalendarView and NumberPicker in conjunction with this DatePicker.

What you need to change:

Use {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png as a template, and change the 'bluish' color to green (I used pixlr). You can either save it with the same name, if you want to be done with the blue divider altogether, or use a different name and make changes in {library-numberpicker} / res / values / themes.xml.

The changes required in themes.xml if you choose a different name:

<style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
    ....
    <item name="selectionDivider">@drawable/new_nine_path_drawable_name</item>
    ....
</style>

And that's it.

Output using the libraries:

Edit:

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

The attribute divider actually comes from LinearLayout. NumberPicker inherits this attribute as NumberPicker extends LinearLayout. But this divider serves a different purpose. The drawable passed to this attribute is placed between child views of LinearLayout.

The attribute android:showDividers is used to change the placement of this divider, possible values being:

  • none: No dividers shown
  • beginning: Divider is shown before the first child view
  • middle: Divider is shown after each child view, not not after the last child view
  • end: Divider is shown after the last child view

The attribute android:dividerPadding is self-explanatory.

Even though NumberPicker inherits this attribute, it does not use it. This is evident from your own research & trials: I tried a multitude of combinations of the two, but I don't seem to get it to work.

To see the divider attribute in action:

<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>

Hack-ish workaround using java reflection:

This answer here gave me the idea. I hate using refection in general, mostly for reasons listed in this answer: Link. Although I'm listing it here for completeness sake, I suggest you don't use it.

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();
        }
    }
}

What we do here:

  • Extend DatePicker
  • If you open date_picker.xml in sdk/platforms/android-xx/res/layout, you'll see that the three NumberPickers have ids month, day, year. We access android.internal.R.id to get resource ids for these NumberPickers.
  • We create three NumberPicker objects using these ids with findViewById(int) method.
  • Then, access and retrieve the Field mSelectionDivider using relection.
  • Set the field to accessible (as its declared final), set its value using Field#set(Object, Object) method. The first argument is the Object that we perform this operation on. Second argument is the Object that we want to set.

The drawable I have used can be downloaded from: here.

这篇关于Android的:如何更改日期选择器分压器的颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆