Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide Day, Month, or Year from DatePicker in Android 5.0+ Lollipop

I've been searching for a solution to hide any one of the following spinners from the DatePicker. For Android 5.0 the internal variables were changed and, in my case, the Day and Month spinners were visible again after the update to my device.

Android 4.4 and Kitkat Solution

DatePicker dpDate = (DatePicker) findViewById(R.id.dpDate);

    // Initialize Date Picker
    int year    = dpDate.getYear();
    int month   = dpDate.getMonth();
    int day     = dpDate.getDayOfMonth();
    dpDate.init(year, month, day, this);

Field f[] = dpDate.getClass().getDeclaredFields();
            for (Field field : f) 
            {
                // Hides the DAY spinner
                if(field.getName().equals("mDayPicker") || field.getName().equals("mDaySpinner")) 
                {
                    field.setAccessible(true);
                    Object dayPicker = new Object();
                    dayPicker = field.get(dpDate);
                    ((View) dayPicker).setVisibility(View.GONE);
                }

                // Hides the MONTH spinner
                if(field.getName().equals("mMonthPicker") || field.getName().equals("mMonthSpinner")) 
                {
                    field.setAccessible(true);
                    Object monthPicker = new Object();
                    monthPicker = field.get(dpDate);
                    ((View) monthPicker).setVisibility(View.GONE);
                }

                // Hides the YEAR spinner
                if(field.getName().equals("mYearPicker") || field.getName().equals("mYearSpinner")) 
                {
                    field.setAccessible(true);
                    Object yearPicker = new Object();
                    yearPicker = field.get(dpDate);
                    ((View) myearPicker).setVisibility(View.GONE);
                }
            }

Android 5.0+ Lollipop Solution

    DatePicker dpDate = (DatePicker) findViewById(R.id.dpDate);

    // Initialize Date Picker
    int year    = dpDate.getYear();
    int month   = dpDate.getMonth();
    int day     = dpDate.getDayOfMonth();
    dpDate.init(year, month, day, this);

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
            {
                int daySpinnerId = Resources.getSystem().getIdentifier("day", "id", "android");
                if (daySpinnerId != 0) 
                {
                    View daySpinner = dpDate.findViewById(daySpinnerId);
                    if (daySpinner != null) 
                    {
                        daySpinner.setVisibility(View.GONE);
                    }
                }
            }

            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
            {
                int monthSpinnerId = Resources.getSystem().getIdentifier("month", "id", "android");
                if (monthSpinnerId != 0) 
                {
                    View monthSpinner = dpDate.findViewById(monthSpinnerId);
                    if (monthSpinner != null) 
                    {
                        monthSpinner.setVisibility(View.GONE);
                    }
                }
            }

            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
            {
                int yearSpinnerId = Resources.getSystem().getIdentifier("year", "id", "android");
                if (yearSpinnerId != 0) 
                {
                    View yearSpinner = dpDate.findViewById(yearSpinnerId);
                    if (yearSpinner != null) 
                    {
                        yearSpinner.setVisibility(View.GONE);
                    }
                }
            }

I found the above solution to this problem here: Custom Date Picker Dialog in Android Lollipop

I wanted to make sure that it was easily searchable so others could benefit from this so I created this new post. (The solution took me several hours to locate and understand, so I hope to help someone with this).

I've tested this and it works perfectly. In fact, if you put the solution for the Lollipop first and then under that, in the code, put the solution for Kitkat, then it is compatible for both versions without interference. (Make sure to use try/catch ;)

EDIT 7.22.2015: I thought it was obvious if one was using a DatePicker that it needed to be initialized. I included the code to show that you need to initialize the DatePicker before you run the rest of the code (in both situations) otherwise your Views will throw a NullPointerException. That includes the yearSpinner throwing a null. Also, you should have at least one view for the date, don't hide all 3, i.e., don't hide the day, month, and the year at the same time.

like image 455
Brandon Avatar asked Jun 11 '15 19:06

Brandon


3 Answers

Very simple, but not intuitive.

First change the theme from DialogPicker

new DatePickerDialog(getActivity(),android.R.style.Theme_Holo_Dialog, this, year,month, day);

Now, yes you can hide any spinner.

dialog.getDatePicker().findViewById(getResources().getIdentifier("day","id","android")).setVisibility(View.GONE);

Work fine for me in 5.0.2 API 21

like image 129
Nicolas Scordamaglia Avatar answered Oct 18 '22 14:10

Nicolas Scordamaglia


Just for the lazy bones, this the fully integrated code (any SDK) that is working for me to build a month picker (90% equal to @Brandon suggestion):

public void initMonthPicker(){
    dp_mes = (DatePicker) findViewById(R.id.dp_mes);

    int year    = dp_mes.getYear();
    int month   = dp_mes.getMonth();
    int day     = dp_mes.getDayOfMonth();

    dp_mes.init(year, month, day, new DatePicker.OnDateChangedListener() {
        @Override
        public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            month_i = monthOfYear + 1;
            Log.e("selected month:", Integer.toString(month_i));
         //Add whatever you need to handle Date changes
        }
    });

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        int daySpinnerId = Resources.getSystem().getIdentifier("day", "id", "android");
        if (daySpinnerId != 0)
        {
            View daySpinner = dp_mes.findViewById(daySpinnerId);
            if (daySpinner != null)
            {
                daySpinner.setVisibility(View.GONE);
            }
        }

        int monthSpinnerId = Resources.getSystem().getIdentifier("month", "id", "android");
        if (monthSpinnerId != 0)
        {
            View monthSpinner = dp_mes.findViewById(monthSpinnerId);
            if (monthSpinner != null)
            {
                monthSpinner.setVisibility(View.VISIBLE);
            }
        }

        int yearSpinnerId = Resources.getSystem().getIdentifier("year", "id", "android");
        if (yearSpinnerId != 0)
        {
            View yearSpinner = dp_mes.findViewById(yearSpinnerId);
            if (yearSpinner != null)
            {
                yearSpinner.setVisibility(View.GONE);
            }
        }
    } else { //Older SDK versions
        Field f[] = dp_mes.getClass().getDeclaredFields();
        for (Field field : f)
        {
            if(field.getName().equals("mDayPicker") || field.getName().equals("mDaySpinner"))
            {
                field.setAccessible(true);
                Object dayPicker = null;
                try {
                    dayPicker = field.get(dp_mes);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                ((View) dayPicker).setVisibility(View.GONE);
            }

            if(field.getName().equals("mMonthPicker") || field.getName().equals("mMonthSpinner"))
            {
                field.setAccessible(true);
                Object monthPicker = null;
                try {
                    monthPicker = field.get(dp_mes);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                ((View) monthPicker).setVisibility(View.VISIBLE);
            }

            if(field.getName().equals("mYearPicker") || field.getName().equals("mYearSpinner"))
            {
                field.setAccessible(true);
                Object yearPicker = null;
                try {
                    yearPicker = field.get(dp_mes);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                ((View) yearPicker).setVisibility(View.GONE);
            }
        }
    }
}
like image 35
Carlos Borau Avatar answered Oct 18 '22 12:10

Carlos Borau


It has different id for 5 and 6+. I have handled following code.

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            int yearSpinnerId = Resources.getSystem().getIdentifier("date_picker_year", "id", "android");
            if (yearSpinnerId != 0)
            {
                View yearSpinner = datePicker.findViewById(yearSpinnerId);
                if (yearSpinner != null)
                    yearSpinner.setVisibility(View.GONE);
            }
        }

        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            int yearSpinnerId = Resources.getSystem().getIdentifier("date_picker_header_year", "id", "android");
            if (yearSpinnerId != 0)
            {
                View yearSpinner = datePicker.findViewById(yearSpinnerId);
                if (yearSpinner != null)
                    yearSpinner.setVisibility(View.GONE);
            }
        }
like image 1
abalta Avatar answered Oct 18 '22 12:10

abalta