web-dev-qa-db-ja.com

Android仕切りの色DatePickerダイアログ

ダイアログでDatePickerの青い仕切りの色を変更しようとしています。これは、DatePickerとButtonBarを備えた通常のDialogFragmentです。

誰かがこれらの仕切りを変更することを知っていますか、またはそれがDatePicker全体をカスタムのものに置き換えることなく可能であるかどうか。

Screenshot DatePicker

ミニラント

今、私は次のコードを示唆するあまりにも多くの答えを見てきました:

<style name="datePickerTheme" parent="@Android:style/Widget.DeviceDefault.DatePicker">
    <item name="Android:divider">**your @drawable/ or @color/ here**</item>
</style>

これは単に機能しません。このコードを提案する前に、これを試しましたか? shouldは完全に機能しますが、DatePickerでは機能しないようです。

11
Armadillo

次のアプローチがうまくいきました。これにより、すべてのフィールドの仕切りの色が設定されます(午前/午後も)

 private void applyStyLing(TimePickerDialog timePickerDialog){
    Resources system = Resources.getSystem();
    int hourNumberPickerId = system.getIdentifier("hour", "id", "Android");
    int minuteNumberPickerId = system.getIdentifier("minute", "id", "Android");
    int ampmNumberPickerId = system.getIdentifier("amPm", "id", "Android");

    NumberPicker hourNumberPicker = (NumberPicker) timePickerDialog.findViewById(hourNumberPickerId);
    NumberPicker minuteNumberPicker = (NumberPicker) timePickerDialog.findViewById(minuteNumberPickerId);
    NumberPicker ampmNumberPicker = (NumberPicker) timePickerDialog.findViewById(ampmNumberPickerId);

   setNumberPickerDividerColour(hourNumberPicker);
   setNumberPickerDividerColour(minuteNumberPicker);
   setNumberPickerDividerColour(ampmNumberPicker);
}

private void setNumberPickerDividerColour(NumberPicker number_picker){
    final int count = number_picker.getChildCount();

    for(int i = 0; i < count; i++){

        try{
            Field dividerField = number_picker.getClass().getDeclaredField("mSelectionDivider");
            dividerField.setAccessible(true);
                ColorDrawable colorDrawable = new ColorDrawable(mContext.getResources().getColor(R.color
                        .interactive_color));
            dividerField.set(number_picker,colorDrawable);

            number_picker.invalidate();
        }
        catch(NoSuchFieldException e){
            Log.w("setNumberPickerTxtClr", e);
        }
        catch(IllegalAccessException e){
            Log.w("setNumberPickerTxtClr", e);
        }
        catch(IllegalArgumentException e){
            Log.w("setNumberPickerTxtClr", e);
        }
    }
}
24
Ajit

私はこれを行うことでこれを解決しました:

DatePicker」を見つけて、mSelectionDividerディバイダーをreflectionに変更しました。次に、タイトルの仕切りがばかげているように見える問題があったので、3つのtextviewを含むLinearLayoutの上にdatepickersを追加し、newFragment.setTitle("");を使用してオリジナルのもの。

仕切りドローアブルの例:これを作った人へのクレジット! :)http://ge.tt/8wK7TZ71/v/0?c

結果画像<-私の結果

例:

    public DatePickerDialog makeDatePicker(OnDateSetListener listener, Calendar cal) {
    Calendar c;
    if (cal == null) {
        c = Calendar.getInstance();
    } else {
        c = cal;
    }
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);
    DatePickerDialog newFragment = new DatePickerDialog(this, listener, year, month, day);

    // removes the original topbar:
    newFragment.setTitle(""); 

    // Divider changing:
    DatePicker dpView = newFragment.getDatePicker(); 
    LinearLayout llFirst = (LinearLayout) dpView.getChildAt(0);
    LinearLayout llSecond = (LinearLayout) llFirst.getChildAt(0);
    for (int i = 0; i < llSecond.getChildCount(); i++) {
        NumberPicker picker = (NumberPicker) llSecond.getChildAt(i); // Numberpickers in llSecond
        // reflection - picker.setDividerDrawable(divider); << didn't seem to work.
        Field[] pickerFields = NumberPicker.class.getDeclaredFields();
        for (Field pf : pickerFields) {
            if (pf.getName().equals("mSelectionDivider")) {
                pf.setAccessible(true);
                try {
                    pf.set(picker, getResources().getDrawable(R.drawable.np_numberpicker_selection_divider_orange));
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (NotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
    // New top:
    int titleHeight = 90;
    // Container:
    LinearLayout llTitleBar = new LinearLayout(this);
    llTitleBar.setOrientation(LinearLayout.VERTICAL);
    llTitleBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, titleHeight));

    // TextView Title:
    TextView tvTitle = new TextView(this);
    tvTitle.setText("Select a date");
    tvTitle.setGravity(Gravity.CENTER);
    tvTitle.setPadding(10, 10, 10, 10);
    tvTitle.setTextSize(24);
    tvTitle.setTextColor(Color.BLACK);
    tvTitle.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, titleHeight-2));
    llTitleBar.addView(tvTitle);

    // View line:
    View vTitleDivider = new View(this);
    vTitleDivider.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 2));
    vTitleDivider.setBackgroundColor(getResources().getColor(R.color.crumblrOrange));
    llTitleBar.addView(vTitleDivider);

    dpView.addView(llTitleBar);
    FrameLayout.LayoutParams lp = (Android.widget.FrameLayout.LayoutParams) llFirst.getLayoutParams();
    lp.setMargins(0, titleHeight, 0, 0);
    return newFragment;
}
17
Mvj

このコードは Ajitの回答 に基づいていますが、DatePickerではなくTimePicker用に調整しました。さらに、安全を確保するためにnullチェックを追加しました。

public static void colorizeDatePicker(DatePicker datePicker) {
    Resources system = Resources.getSystem();
    int dayId = system.getIdentifier("day", "id", "Android");
    int monthId = system.getIdentifier("month", "id", "Android");
    int yearId = system.getIdentifier("year", "id", "Android");

    NumberPicker dayPicker = (NumberPicker) datePicker.findViewById(dayId);
    NumberPicker monthPicker = (NumberPicker) datePicker.findViewById(monthId);
    NumberPicker yearPicker = (NumberPicker) datePicker.findViewById(yearId);

    setDividerColor(dayPicker);
    setDividerColor(monthPicker);
    setDividerColor(yearPicker);
}

private static void setDividerColor(NumberPicker picker) {
    if (picker == null)
        return;

    final int count = picker.getChildCount();
    for (int i = 0; i < count; i++) {
        try {
            Field dividerField = picker.getClass().getDeclaredField("mSelectionDivider");
            dividerField.setAccessible(true);
            ColorDrawable colorDrawable = new ColorDrawable(picker.getResources().getColor(R.color.colorAccent));
            dividerField.set(picker, colorDrawable);
            picker.invalidate();
        } catch (Exception e) {
            Log.w("setDividerColor", e);
        }
    }
}

出力

colored dividers

14

これにより、アプリのテーマスタイルに以下のコード行を追加する際の問題が修正されました。

<item name="colorControlNormal">@color/colorAccent</item>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/blue</item> 
</style>
10
Jaishree Rathod

考慮する:

新しいR.drawable.dividerは必要ありません

あなたは書ける:

 pf.set(number_picker, new ColorDrawable(getResources().getColor(R.color.red)));
4
toni

このバージョンは、DatePickerで特定の用途に合わせて調整されています。 Andrea Lazzarottoのバージョンは正常に機能しますが、不要なループを使用しているため、複数のアプライアンスの色が変化します。マイナーなコードの改善に加えて、私のバージョンでは、アプリのテーマの原色を使用して仕切りの色と一致させています( アプリのテーマから原色を取得するにはどうすればよいですか? を参照)。 Android 6.0および8.0でテスト済み:

private void colorizeDatePicker(final DatePicker datePicker) {
    final Resources system = Resources.getSystem();
    final String defType = "id";
    final String defPackage = "Android";

    final int dayId = system.getIdentifier("day", defType, defPackage);
    final int monthId = system.getIdentifier("month", defType, defPackage);
    final int yearId = system.getIdentifier("year", defType, defPackage);

    final NumberPicker dayPicker = (NumberPicker) datePicker.findViewById(dayId);
    final NumberPicker monthPicker = (NumberPicker) datePicker.findViewById(monthId);
    final NumberPicker yearPicker = (NumberPicker) datePicker.findViewById(yearId);

    setDividerColor(dayPicker);
    setDividerColor(monthPicker);
    setDividerColor(yearPicker);
}

private void setDividerColor(final NumberPicker picker) {
    if (picker == null) {
        return;
    }

    try {
        final Field dividerField = picker.getClass().getDeclaredField("mSelectionDivider");
        dividerField.setAccessible(true);

        final TypedValue outValue = new TypedValue();
        getContext().getTheme().resolveAttribute(R.attr.colorPrimary, outValue, true);
        final int dividerColor = outValue.data;

        dividerField.set(picker, new ColorDrawable(dividerColor));
        picker.invalidate();
    } catch (Exception e) {
    }
}
2
Michael Troger

問題を解決してくれたMvjに感謝します!タイムピッカーの仕切りにあなたのソリューションの実装も示したいと思っただけです。

    TimePickerDialog ptd = new TimePickerDialog(getActivity(), R.style.PickerStyler, this, hour, minute,DateFormat.is24HourFormat(getActivity()));
    ptd.setTitle("");

    //Needs to be try catched
    Field mTimePickerField = ptd.getClass().getDeclaredField("mTimePicker");
    mTimePickerField.setAccessible(true);
    TimePicker mTimePickerInstance = (TimePicker) mTimePickerField.get(ptd);    

    LinearLayout llFirst = (LinearLayout) mTimePickerInstance.getChildAt(0);
    LinearLayout llSecond = (LinearLayout) llFirst.getChildAt(0);
    boolean continiue = false;
    NumberPicker picker = null;
    for (int i = 0; i < llSecond.getChildCount(); i++) {            
        continiue = true;
        try{picker = (NumberPicker) llSecond.getChildAt(i);
            }catch(Exception e){continiue = false;}

        if(continiue){
            Field[] pickerFields = NumberPicker.class.getDeclaredFields();
            for (Field pf : pickerFields) {
                if (pf.getName().equals("mSelectionDivider")) {
                    pf.setAccessible(true);
                    try {
                        pf.set(picker, getResources().getDrawable(R.drawable.divider));
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (NotFoundException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }   
1
user3532232

はい、もちろんできます。たとえば、次の属性を使用できます。

<NumberPicker
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            selectionDivider="@color/black" //The divider for making the selection area
            selectionDividerHeight="1px"//The height of the selection divider
            selectionDividersDistance="3dp"//The distance between the two selection dividers
            internalLayout="@layout/something"//The layout of the number picker.
            internalMaxHeight="5dp"//The max height of the NumberPicker (also check other variations)
            internalMinWidth="5dp" // The max width of the NumberPicker (also check other variations)
            virtualButtonPressedDrawable="@drawable/something"//The drawable for pressed virtual (increment/decrement) buttons.
            />

更新:

これを使用できます カスタムdatepicker 。それは高度にカスタマイズ可能で、後方競争力があります。基本的にnumberpickerを使用し、上記の属性を使用して除算器を設定できます。

1
bugraoral