How to display year only in date picker in android

前端 未结 6 1259
一整个雨季
一整个雨季 2020-12-03 21:59

Can anybody tell how to display year only in date picker in android

Thanks

相关标签:
6条回答
  • 2020-12-03 22:14

    You could also use some simple reflection to hide the day and month NumberPickers of a DatePicker widget. Do note that this may stop working if Google decides to rename the member field names. Also, this approach of course makes sense when using android:datePickerMode="spinner".

    // inflate DatePicker, or e.g. get it from a DatePickerDialog:
    DatePicker datepicker = ...
    
    // pre-Honeycomb fields: 
    findAndHideField(datepicker, "mDayPicker");
    findAndHideField(datepicker, "mMonthPicker");
    
    // Honeycomb(+) fields:
    findAndHideField(datepicker, "mDaySpinner");
    findAndHideField(datepicker, "mMonthSpinner");
    
    // Lollipop(+) fields (wrapped in a delegate):
    final Object mDatePickerDelegate = findFieldInstance(picker, "mDelegate");
    findAndHideField(mDatePickerDelegate, "mDaySpinner");
    findAndHideField(mDatePickerDelegate, "mMonthSpinner");
    
    
    /** find a member field by given name and hide it */
    private static void findAndHideField(Object object, String name) {
        try {
            final Field field = object.getClass().getDeclaredField(name);
            field.setAccessible(true);
            final View fieldInstance = (View) field.get(object);
            fieldInstance.setVisibility(View.GONE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /* find a member field by given name and return its instance value */
    private static Object findFieldInstance(DatePicker datepicker, String name) {
        try {
            final Field field = DatePicker.class.getDeclaredField(name);
            field.setAccessible(true);
            return field.get(datepicker);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    

    Update: Added code illustrating how to make this approach work with Android 'Lollipop' 5.0 (API 21+).


    Disclaimer: I cannot stress enough that this is hacky solution that may stop working with any framework update (as it did when Android 3.0 was first introduced, and again with Android 5.0).

    0 讨论(0)
  • 2020-12-03 22:16
    private void showBirthDayPicker() {
        int year = calendar.get(Calendar.YEAR);
    
        final Dialog birthDayDialog = new Dialog(this);
        birthDayDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        birthDayDialog.setContentView(R.layout.dialog_birthday);
    
        Button okBtn = birthDayDialog.findViewById(R.id.btn_ok);
        Button cancelBtn = birthDayDialog.findViewById(R.id.btn_cancel);
    
        final NumberPicker np = birthDayDialog.findViewById(R.id.birthdayPicker);
        np.setMinValue(year - 100);
        np.setMaxValue(year - 15);
        np.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
        setDivider(np, android.R.color.white);
        np.setWrapSelectorWheel(false);
        np.setValue(year-20);
        np.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker numberPicker, int i, int i1) {
    
            }
        });
    
        okBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                edtBirthDay.setText(String.valueOf(np.getValue()));
                birthDayDialog.dismiss();
            }
        });
    
        cancelBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                birthDayDialog.dismiss();
            }
        });
    
        birthDayDialog.show();
    }
    

    xml

       `enter code here`<?xml version="1.0" encoding="utf-8"?>
       <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            android:baselineAligned="false"
            android:orientation="vertical" >
    
            <TextView
                android:id="@+id/birthday_dialog_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:gravity="center"
                android:minHeight="42dp"
                android:text="Year lahir"
                android:textSize="14sp" />
    
            <NumberPicker
                android:id="@+id/birthdayPicker"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="center" >
    
                <Button
                    android:id="@+id/btn_cancel"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="Cancel" />
    
                <Button
                    android:id="@+id/btn_ok"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="OK" />
            </LinearLayout>
    
        </LinearLayout>
    
        </RelativeLayout>
    
    0 讨论(0)
  • 2020-12-03 22:26

    I have modified @agilanbu 's answer and it can be used as :

    private fun createDialogWithoutDateField() {
    
        val alertDialog: AlertDialog?
        val builder = AlertDialog.Builder(activity, R.style.AlertDialogStyle)
        val inflater = activity!!.layoutInflater
    
        val cal = Calendar.getInstance()
    
        val dialog = inflater.inflate(R.layout.month_year_picker_dialog, null)
        val monthPicker = dialog.findViewById(R.id.picker_month) as NumberPicker
        val yearPicker = dialog.findViewById(R.id.picker_year) as NumberPicker
    
        monthPicker.minValue = 1
        monthPicker.maxValue = 12
        monthPicker.value = cal.get(Calendar.MONTH) + 1
    
        val year = cal.get(Calendar.YEAR)
        yearPicker.minValue = 1900
        yearPicker.maxValue = 3500
        yearPicker.value = year
    
        builder.setView(dialog).setPositiveButton(Html.fromHtml("<font color='#FF4081'>Ok</font>")){dialogInterface, which ->
            //Toast.makeText(applicationContext,"clicked yes",Toast.LENGTH_LONG).show()
    
            val value = yearPicker.value
            dialogInterface.cancel()
        }
    
        builder.setNegativeButton(Html.fromHtml("<font color='#FF4081'>Cancel</font>")){dialogInterface, which ->
            dialogInterface.cancel()
        }
    
        alertDialog = builder.create()
        // Set other dialog properties
        alertDialog.setCancelable(true)
        alertDialog.show()
    }
    

    You can get the layout file and styles in @agilanbu 's answer.

    0 讨论(0)
  • 2020-12-03 22:27

    I just have the same problem and all solution I found doesn't works with new Android Versions because I can't get the Field of the Reflection of DatePicker

    Anyway I solve by doing a Dialog to pick a number, if you need the code:

    SingleNumberPickerDialog.java Code

    public class SingleNumberPickerDialog extends DialogFragment {
    
        public interface IOnNumberSelected {
            void onNumberSelected(int num, int requestCode);
        }
    
        private static final String TAG = SingleNumberPickerDialog.class.getSimpleName();
        private static final String KEY = TAG + ".key";
        // Arguments Keys
        private static final String KEY_LABEL = KEY + ".label";
        private static final String KEY_START_VALUE = KEY + ".startValue";
        private static final String KEY_MIN_VALUE = KEY + ".minValue";
        private static final String KEY_MAX_VALUE = KEY + ".maxValue";
        private static final String KEY_REQUEST_CODE = KEY + ".requestCode";
        // Int Values
        private static final int INT_UNDEFINED = -0x1;
    
        @BindView(R2.id.tv_label)
        protected TextView mtvLabel;
        @BindView(R2.id.np_number)
        protected NumberPicker mnpNumber;
    
        private IOnNumberSelected mCallback;
        private int mRequestCode;
    
        public static SingleNumberPickerDialog newInstance(String label, int startValue, int minValue, int maxValue, int requestCode){
            SingleNumberPickerDialog mInstance = new SingleNumberPickerDialog();
            Bundle args = new Bundle();
            args.putString(KEY_LABEL, label);
            args.putInt(KEY_START_VALUE, startValue);
            args.putInt(KEY_MIN_VALUE, minValue);
            args.putInt(KEY_MAX_VALUE, maxValue);
            args.putInt(KEY_REQUEST_CODE, requestCode);
            mInstance.setArguments(args);
            return mInstance;
        }
    
        /** Override Lifecycle Methods **/
        @Override
        public void onAttach(@NonNull Context context) {
            super.onAttach(context);
            try {
                mCallback = (IOnNumberSelected) context;
            } catch (ClassCastException ccE){
                Log.e(TAG, ccE);
            }
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            super.onCreateView(inflater, container, savedInstanceState);
            View view = inflater.inflate(R.layout.dialog_single_number_picker, container, false);
            ButterKnife.bind(this, view);
            initOnCreateView();
            return view;
        }
    
        /** Actions Methods **/
        @OnClick(R2.id.b_confirm)
        void onClickConfirm(View view){
            if(mCallback != null){
                mCallback.onNumberSelected(mnpNumber.getValue(), mRequestCode);
            }
        }
    
        /** Private Methods **/
        private void initOnCreateView(){
            if(getArguments() != null){
                initLabel();
                initStartValue();
                initMinValue();
                initMaxValue();
                initRequestCode();
            }
        }
    
        private void initLabel(){
            if(getArguments().containsKey(KEY_LABEL)){
                mtvLabel.setText(getArguments().getString(KEY_LABEL));
            }
        }
    
        private void initStartValue(){
            if(getArguments().containsKey(KEY_START_VALUE)){
                mnpNumber.setValue(getArguments().getInt(KEY_START_VALUE));
            }
        }
    
        private void initMinValue(){
            if(getArguments().containsKey(KEY_MIN_VALUE)){
                mnpNumber.setMinValue(getArguments().getInt(KEY_MIN_VALUE));
            }
        }
    
        private void initMaxValue(){
            if(getArguments().containsKey(KEY_MAX_VALUE)){
                mnpNumber.setMaxValue(getArguments().getInt(KEY_MAX_VALUE));
            }
        }
    
        private void initRequestCode(){
            if(getArguments().containsKey(KEY_REQUEST_CODE)){
                mRequestCode = getArguments().getInt(KEY_REQUEST_CODE);
            }
        }
    
    }
    

    dialog_single_number_picker.xml Code:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical"
        android:background="@color/black"
        android:padding="@dimen/padding_3dp">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@color/white"
            android:padding="@dimen/padding_22dp">
            <TextView
                android:id="@+id/tv_label"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:textColor="@color/black"
                android:textSize="@dimen/text_size_20sp"
                android:textStyle="bold"
                android:padding="@dimen/padding_25dp"/>
            <NumberPicker
                android:id="@+id/np_number"
                android:layout_width="wrap_content"
                android:layout_height="@dimen/height_200dp"
                android:layout_gravity="center"/>
            <Button
                android:id="@+id/b_confirm"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_confirm"
                android:paddingStart="@dimen/padding_15dp"
                android:paddingEnd="@dimen/padding_15dp"
                style="@style/ButtonAccentWhiteStyle"/>
        </LinearLayout>
    </LinearLayout>
    

    Usage sample (u need to implement the callback inside ur activity):

    int year = DateUtils.getCurrentYear();
                SingleNumberPickerDialog mDialog = SingleNumberPickerDialog.newInstance(getString(R.string.label_year), year, year - 50, year + 50, 0x0);
                mDialog.setStyle(DialogFragment.STYLE_NO_FRAME, R.style.NoBackgroundDialogStyle);
                mDialog.setCancelable(false);
                mDialog.show(getSupportFragmentManager(), TAG_DIALOG_YEAR_PICKER);
    
    0 讨论(0)
  • 2020-12-03 22:33

    you can hide day and month from custom datepicker like this:

    DatePicker datePicker = (DatePicker) datePickerDialogField.get(obj);
    DatePicker monPickerPicker = (DatePicker) datePickerDialogField.get(obj);
    
    Field datePickerFields[] = datePickerDialogField.getType().getDeclaredFields();
    for (Field datePickerField : datePickerFields) {
    //datePickerField
    //mMonthSpinner
    
    if (“mDayPicker”.equals(datePickerField.getName()) || “mDaySpinner”.equals(datePickerField
    .getName())) {
    datePickerField.setAccessible(true);
    Object dayPicker = new Object();
    dayPicker = datePickerField.get(datePicker);
    ((View) dayPicker).setVisibility(View.GONE);
    }
    if (“mMonthpicker”.equals(datePickerField.getName()) || “mMonthSpinner”.equals(datePickerField
    .getName())) {
    datePickerField.setAccessible(true);
    Object dayPicker = new Object();
    dayPicker = datePickerField.get(datePicker);
    ((View) dayPicker).setVisibility(View.GONE);
    }
    
    0 讨论(0)
  • 2020-12-03 22:37

    First, create MonthYearPickerDialog.java class extends with DialogFragment

    public class MonthYearPickerDialog extends DialogFragment {
    
    private static final int MAX_YEAR = 2099;
    private DatePickerDialog.OnDateSetListener listener;
    
    public void setListener(DatePickerDialog.OnDateSetListener listener) {
        this.listener = listener;
    }
    
    @SuppressLint("ResourceAsColor")
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogStyle);
        LayoutInflater inflater = getActivity().getLayoutInflater();
    
        Calendar cal = Calendar.getInstance();
    
        View dialog = inflater.inflate(R.layout.month_year_picker_dialog, null);
        final NumberPicker monthPicker = (NumberPicker) dialog.findViewById(R.id.picker_month);
        final NumberPicker yearPicker = (NumberPicker) dialog.findViewById(R.id.picker_year);
    
        monthPicker.setMinValue(1);
        monthPicker.setMaxValue(12);
        monthPicker.setValue(cal.get(Calendar.MONTH) + 1);
    
        int year = cal.get(Calendar.YEAR);
        yearPicker.setMinValue(1900);
        yearPicker.setMaxValue(3500);
        yearPicker.setValue(year);
    
        builder.setView(dialog).setPositiveButton(Html.fromHtml("<font color='#FF4081'>Ok</font>"), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0);
            }
        }).setNegativeButton(Html.fromHtml("<font color='#FF4081'>Cancel</font>"), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                MonthYearPickerDialog.this.getDialog().cancel();
            }
        });
        return builder.create();
       }
     }
    

    in styles.xml paste this code.

      <style name="AlertDialogStyle" parent="Theme.AppCompat.Light.Dialog">
        <item name="android:textColor">#FF4081</item>  // you can change the color of the yearPiker dialog
        <item name="android:textColorPrimary">#FF4081</item> // you can change the color of the yearPiker dialog
      </style>
    

    create month_year_picker_dialog.xml

    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="220dp"
    android:layout_height="300dp"
    android:layout_gravity="center"
    android:gravity="center"
    android:orientation="vertical">
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:background="@color/colorAccent"
            android:gravity="top">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:elevation="8dp"
                android:gravity="center"
                android:text="Year"
                android:textColor="#ffffff"
                android:textSize="22dp"
                android:textStyle="bold" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="horizontal">
    
            <NumberPicker
                android:id="@+id/picker_month"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="20dp"
                android:descendantFocusability="blocksDescendants"
                android:visibility="gone"
                tools:ignore="RtlCompat">
    
            </NumberPicker>
    
            <NumberPicker
                android:id="@+id/picker_year"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:descendantFocusability="blocksDescendants"
                >
    
            </NumberPicker>
    
          </LinearLayout>
    
       </LinearLayout>
    
    </LinearLayout>
    

    In your main class (activity)

     private DatePickerDialog createDialogWithoutDateField() {
        DatePickerDialog dpd = new DatePickerDialog(this, null, 2014, 1, 24);
        try {
            java.lang.reflect.Field[] datePickerDialogFields = dpd.getClass().getDeclaredFields();
            for (java.lang.reflect.Field datePickerDialogField : datePickerDialogFields) {
                if (datePickerDialogField.getName().equals("mDatePicker")) {
                    datePickerDialogField.setAccessible(true);
                    DatePicker datePicker = (DatePicker) datePickerDialogField.get(dpd);
                    java.lang.reflect.Field[] datePickerFields = datePickerDialogField.getType().getDeclaredFields();
                    for (java.lang.reflect.Field datePickerField : datePickerFields) {
                        Log.i("test", datePickerField.getName());
                        if ("mDaySpinner".equals(datePickerField.getName())) {
                            datePickerField.setAccessible(true);
                            Object dayPicker = datePickerField.get(datePicker);
                            ((View) dayPicker).setVisibility(View.GONE);
                        }
                    }
                }
            }
        }
        catch (Exception ex) {
        }
        return dpd;
    }
    

    Finally , call wherever you want

    createDialogWithoutDateField().show();
    

    0 讨论(0)
提交回复
热议问题