如何更改DatePickerDialog中NumberPickers的顺序

时间:2015-11-10 07:27:59

标签: android

enter image description here

我想交换月份和日期(旋转器)。我想将Date列(Spinner)发送到左侧,将Month列(Spinner)发送到中间。可能吗?

2 个答案:

答案 0 :(得分:3)

根据来源中的注释,这些NumberPicker的顺序由用户选择的系统范围的日期格式决定,并根据用户的最佳顺序确定语言环境。没有公共方法可以轻松改变这一点。但是,无论如何,我都想出了改变订单的方法。

在以下示例中,我们从系统资源中获取DatePickerDialog' NumberPicker的ID。我通过检查DatePicker类的the layout file找到了这些标识符的名称。

我们获得了ID后,我们会在对话框中找到NumberPicker及其父LinearLayout,就像我们对其他任何View一样。然后我们可以从布局中移除微调器,并以任何所需的顺序添加它们。 DatePicker类使用相同的方法重新排序微调器,下面的一些代码是从其源代码中提取的。

在添加回每个微调器后,我们需要使用它调用setImeOptions()及其新的索引。这将纠正旋转器的焦点链和键盘反馈。输入TextView s。

这一切都有点笨拙,所以我用几种方法把它包起来。只需在显示对话框后调用orderDate()方法,并使用char数组指示所需的日期顺序。例如:

DatePickerDialog dialog = new DatePickerDialog(...);
...
dialog.show();

orderDate(dialog, new char[]{'d', 'm', 'y'});

我们为微调器的数量保持int常量,简化了从源中提取的一些代码:

private static final int SPINNER_COUNT = 3;

private void orderDate(DatePickerDialog dialog, char[] ymdOrder) {
    if(!dialog.isShowing()) {
        throw new IllegalStateException("Dialog must be showing");
    }

    final int idYear = Resources.getSystem().getIdentifier("year", "id", "android");
    final int idMonth = Resources.getSystem().getIdentifier("month", "id", "android");
    final int idDay = Resources.getSystem().getIdentifier("day", "id", "android");
    final int idLayout = Resources.getSystem().getIdentifier("pickers", "id", "android");

    final NumberPicker spinnerYear = (NumberPicker) dialog.findViewById(idYear);
    final NumberPicker spinnerMonth = (NumberPicker) dialog.findViewById(idMonth);
    final NumberPicker spinnerDay = (NumberPicker) dialog.findViewById(idDay);
    final LinearLayout layout = (LinearLayout) dialog.findViewById(idLayout);

    layout.removeAllViews();
    for (int i = 0; i < SPINNER_COUNT; i++) {
        switch (ymdOrder[i]) {
            case 'y':
                layout.addView(spinnerYear);
                setImeOptions(spinnerYear, i);                  
                break;
            case 'm':
                layout.addView(spinnerMonth);
                setImeOptions(spinnerMonth, i);
                break;
            case 'd':
                layout.addView(spinnerDay);
                setImeOptions(spinnerDay, i);
                break;
            default:
                throw new IllegalArgumentException("Invalid char[] ymdOrder");
        }
    }
}

private void setImeOptions(NumberPicker spinner, int spinnerIndex) {
    final int imeOptions;
    if (spinnerIndex < SPINNER_COUNT - 1) {
        imeOptions = EditorInfo.IME_ACTION_NEXT;
    }
    else {
        imeOptions = EditorInfo.IME_ACTION_DONE;
    }
    int idPickerInput = Resources.getSystem().getIdentifier("numberpicker_input", "id", "android");
    TextView input = (TextView) spinner.findViewById(idPickerInput);
    input.setImeOptions(imeOptions);
}

答案 1 :(得分:3)

基于@Mike M.解决方案,我在Kotlin中编写了一个扩展功能。

示例:

datePicker.formatDate("dmy") // show picker in Day, Month, Year format

Kotlin扩展功能:

import android.content.res.Resources
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.DatePicker
import android.widget.LinearLayout
import android.widget.NumberPicker
import android.widget.TextView

private const val SPINNER_COUNT = 3

/**
 * Changes the [DatePicker] date format.
 * Example: dmy will show the date picker in day, month, year order
 * */
fun DatePicker.formatDate(ymdOrder: String) {
  val system = Resources.getSystem()
  val idYear = system.getIdentifier("year", "id", "android")
  val idMonth = system.getIdentifier("month", "id", "android")
  val idDay = system.getIdentifier("day", "id", "android")
  val idLayout = system.getIdentifier("pickers", "id", "android")
  val spinnerYear = findViewById<View>(idYear) as NumberPicker
  val spinnerMonth = findViewById<View>(idMonth) as NumberPicker
  val spinnerDay = findViewById<View>(idDay) as NumberPicker
  val layout = findViewById<View>(idLayout) as LinearLayout
  layout.removeAllViews()
  for (i in 0 until SPINNER_COUNT) {
    when (ymdOrder[i]) {
      'y' -> {
        layout.addView(spinnerYear)
        setImeOptions(spinnerYear, i)
      }
      'm' -> {
        layout.addView(spinnerMonth)
        setImeOptions(spinnerMonth, i)
      }
      'd' -> {
        layout.addView(spinnerDay)
        setImeOptions(spinnerDay, i)
      }
      else -> throw IllegalArgumentException("Invalid char[] ymdOrder")
    }
  }
}

private fun setImeOptions(spinner: NumberPicker, spinnerIndex: Int) {
  val imeOptions: Int = if (spinnerIndex < SPINNER_COUNT - 1) {
    EditorInfo.IME_ACTION_NEXT
  } else {
    EditorInfo.IME_ACTION_DONE
  }
  val idPickerInput: Int = Resources.getSystem().getIdentifier("numberpicker_input", "id", "android")
  val input = spinner.findViewById<View>(idPickerInput) as TextView
  input.imeOptions = imeOptions
}