Персонализиран диалогов прозорец за избор на дата в Android Lollipop

Искам инструмент за избор на дата да показва само месец и година. Персонализирах инструмента за избор на дата, за да го направя, т.е. да премахна полето „ден“ от инструмента за избор, но в Android Lollipop получавам инструмент за избор с ден, месец и година. Следва моята част от кода. Моля, помогнете ми да разбера проблема. Благодаря предварително.

    try {
        Field f[] = mDatePicker.getClass().getDeclaredFields();
        for (Field field : f) {

            if (field.getName().equals("mDaySpinner") || field.getName().equals("mDayPicker")) {
                field.setAccessible(true);
                Object dayPicker = new Object();
                dayPicker = field.get(mDatePicker);
                ((View) dayPicker).setVisibility(View.GONE);
            }

        }
    } catch (SecurityException e) {
    } catch (IllegalArgumentException e) {
    } catch (IllegalAccessException e) {
    }

person sravanalakshmi.sunkara    schedule 20.10.2014    source източник
comment
Какво не работи? Приложението срива ли се? Ако е така, публикувайте проследяването на стека.   -  person Egor Neliuba    schedule 20.10.2014
comment
също показва ден, което не е правилно в моя случай. Трябва да показва само месец и година. Работи правилно до Kitkat.   -  person sravanalakshmi.sunkara    schedule 20.10.2014
comment
IMHO достъпът до вътрешни елементи в класа за избор на дата е лоша практика. Зависите от въпросните полета с определени имена; ако имената се променят... Мисля, че е по-добре да приложите своя собствена персонализирана джаджа с два нормални цифрови въртящи се въртящи се.   -  person Laur Ivan    schedule 21.10.2014
comment
Това ще се повреди при бъдещи актуализации на операционната система. Никога не трябва да използвате отражение за достъп до ресурси на частна рамка в приложение, което планирате да пуснете публично.   -  person alanv    schedule 22.03.2015


Отговори (3)


Използването на отражение за намиране и скриване на елементи от потребителския интерфейс всъщност не е добра практика. Във вашия случай той спря да работи в Lollipop, защото mDaySpinner сега се съдържа във вътрешен частен статичен DatePickerSpinngerDelegate клас в рамките на DatePicker клас.

Бих препоръчал вместо това да преминете през йерархията на изгледа, за да намерите и скриете елемента за въртене на деня. Написах следния код, който работи в lollipop:

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    int daySpinnerId = Resources.getSystem().getIdentifier("day", "id", "android");
    if (daySpinnerId != 0) {
        View daySpinner = datePicker.findViewById(daySpinnerId);
        if (daySpinner != null) {
            daySpinner.setVisibility(View.GONE);
        }
    }
}
person cse    schedule 20.01.2015
comment
@alanv Примерът за код в този отговор не използва отражение. Всъщност този отговор изрично съветва да не използвате размисъл, като казва, че не е страхотна практика. Може би сте предвидили коментара си за примера на кода в оригиналния въпрос, който всъщност използва отражение. - person cse; 22.03.2015
comment
Да, въпреки че този отговор все още се опитва да използва частни ресурси на рамката. Ресурсът за ID на деня не е публичен и следователно не е гарантирано, че съществува. Не е гарантирано, че това решение ще работи в бъдещи версии на операционната система или дори в различни персонализирани от OEM версии на Lollipop. - person alanv; 22.03.2015
comment
@cse,@Sivakumar,@Maulik.J как да използвам този mang с фрагмент от диалоговия прозорец за избор на дата?? - person Reprator; 21.12.2015

Това е основен пример за избор на месец, но може лесно да се адаптира, за да избира също година и/или ден (работи и за по-стари версии на Android):

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

}

person Carlos Borau    schedule 02.10.2015

Продължих да правя модифициран инструмент за избор на дата, наречен Simple Date picker ... използвах кода, подобен на инструмента за избор на дата, само за да покажа месец и година

вижте https://github.com/resengupta/Month-Year-Date-Picker

Класът SimpleDatePickerDialog.java отговаря за показването на инструмента за избор на номера на месеца и годината. SimpleDatePickerDelegate.java работи за прилагане на правила към инструментите за избор на числа. SimpleDatePickerDialogFragment.java е DialogFragment, който обвива диалоговия прозорец за предупреждение.

person ReeSen    schedule 15.10.2015