MyTetra Share
Делитесь знаниями!
DatePickerFragment.java
21.04.2017
18:46
Раздел: Android - books - AndroidProgramming2e - 12 Диалоговые окна
DatePickerFragment.java

DatePickerFragment.java

package com.bignerdranch.android.criminalintent; 
 
import android.app.Activity; 
import android.app.Dialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.os.Bundle; 
import android.support.v4.app.DialogFragment; 
import android.support.v7.app.AlertDialog; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.widget.DatePicker; 
 
import java.util.Calendar; 
import java.util.Date; 
import java.util.GregorianCalendar; 
 
//В коде DatePickerFragment создается и настраивается экземпляр AlertDialog, отображающий виджет DatePicker. В качестве хоста DatePickerFragment используется экземпляр CrimePagerActivity. 
 
public class DatePickerFragment extends DialogFragment { 
 
    public static final String EXTRA_DATE = 
            "com.bignerdranch.android.criminalintent.date"; 
 
    private static final String ARG_DATE = "date"; 
 
    private DatePicker mDatePicker; 
//    Чтобы передать дату преступления DatePickerFragment, мы напишем метод 
//    newInstance(Date) и сделаем объект Date аргументом фрагмента. 
    public static DatePickerFragment newInstance(Date date) { 
        Bundle args = new Bundle(); 
        args.putSerializable(ARG_DATE, date); 
 
        DatePickerFragment fragment = new DatePickerFragment(); 
        fragment.setArguments(args); 
        return fragment; 
    } 
 
    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
        Date date = (Date) getArguments().getSerializable(ARG_DATE); 
 
//        Чтобы получить нужные значения, следует создать объект Calendar и использовать Date для определения его конфигурации. После этого вы сможете получить нужную информацию из Calendar. В методе onCreateDialog(…) получите объект Date из аргументов и используйте его с Calendar для инициализации DatePicker. 
        Calendar calendar = Calendar.getInstance(); 
        calendar.setTime(date); 
        int year = calendar.get(Calendar.YEAR); 
        int month = calendar.get(Calendar.MONTH); 
        int day = calendar.get(Calendar.DAY_OF_MONTH); 
//        В методе DatePickerFragment.onCreateDialog(…) заполните представление и назначьте его диалоговому окну 
//        Почему мы возимся с определением и заполнением макета, когда объект DatePicker можно было бы создать в коде так, как показано ниже? 
//        @Override 
//        public Dialog onCreateDialog(Bundle savedInstanceState) { 
//            DatePicker dp = new DatePicker(getActivity()); 
//            return new AlertDialog.Builder(getActivity()) 
//                    .setView(dp) 
//... 
//.create(); 
//        } 
//        Использование макета упрощает изменения в случае изменения его содержимого. Предположим, вы захотели, чтобы рядом с DatePicker в диалоговом окне отображался виджет TimePicker. При использовании заполнения можно просто обновить файл макета, и новое представление появится на экране. Также обратите внимание на то, что дата, выбранная в DatePicker, автоматически сохраняется при поворотах. 
//                Вспомните, что представления могут сохранять состояние между изменениями конфигурации, но только в том случае, если у них есть атрибут id. При создании DatePicker в dialog_date.xml вы также приказали инструментарию построения программы сгенерировать уникальный идентификатор для этого виджета DatePicker. Если DatePicker создается в коде, то для сохранения состояния вам придется назначить идентификатор DatePicker на программном уровне. 
 
        View v = LayoutInflater.from(getActivity()) 
                .inflate(R.layout.dialog_date, null); 
 
        mDatePicker = (DatePicker) v.findViewById(R.id.dialog_date_date_picker); 
        mDatePicker.init(year, month, day, null); 
//        В этой реализации используется класс AlertDialog.Builder, предоставляющий 
//        динамичный интерфейс для конструирования экземпляров AlertDialog. 
        return new AlertDialog.Builder(getActivity()) 
//        Метод настраивает диалоговое окно для отображения переданного объекта View 
//        между заголовком и кнопкой(-ами). 
                .setView(v) 
//        Затем вызываются два метода AlertDialog.Builder для настройки диалогового 
//        окна: 
//        public AlertDialog.Builder setTitle(int titleId) 
//        public AlertDialog.Builder setPositiveButton(int textId, DialogInterface.OnClickListener listener) 
                .setTitle(R.string.date_picker_title) 
//        Метод setPositiveButton(…) получает строковый ресурс и объект, реализующий DialogInterface.OnClickListener. Когда пользователь нажимает кнопку положительного ответа в диалоговом окне, приложение должно получить дату из DatePicker и отправить результат CrimeFragment. В коде onCreateDialog(…) замените параметр null вызова setPositiveButton(…) реализацией DialogInterface.OnClickListener, которая возвращает выбранную дату и вызывает sendResult. 
                .setPositiveButton(android.R.string.ok, 
                        new DialogInterface.OnClickListener() { 
                            @Override 
                            public void onClick(DialogInterface dialog, int which) { 
                                int year = mDatePicker.getYear(); 
                                int month = mDatePicker.getMonth(); 
                                int day = mDatePicker.getDayOfMonth(); 
                                Date date = new GregorianCalendar(year, month, day).getTime(); 
                                sendResult(Activity.RESULT_OK, date); 
                            } 
                }) 
//        Построение диалогового окна завершается вызовом AlertDialog.Builder.create(), который возвращает настроенный экземпляр AlertDialog. 
                .create(); 
    } 
//      Чтобы вернуть новую дату фрагменту CrimeFragment для обновления уровня модели и его собственного представления, мы упакуем ее как дополнение объекта Intent и передадим этот объект Intent в вызове CrimeFragment. onActivityResult(…) 
//      Вызов Fragment.onActivityResult(…) может показаться странным — с учетом того, что активность-хост не получает вызова Activity.onActivityResult(…) в этом  взаимодействии. Но как будет показано позднее в этой главе, использование  onActivityResult(…) для передачи данных от одного фрагмента к другому не только работает, но и улучшает гибкость отображения фрагмента диалогового окна. 
    private void sendResult(int resultCode, Date date) { 
        //    Какой метод будет использоваться для передачи интента целевому фрагменту? 
//    Как ни странно, DatePickerFragment передаст его при вызове CrimeFragment.onActivityResult(int, int, Intent). 
//    Метод Activity.onActivityResult(…) вызывается ActivityManager для родительской активности при уничтожении дочерней активности. При работе с активностями вы не вызываете Activity.onActivityResult(…) самостоятельно; это делает ActivityManager. После того как активность получит вызов, экземпляр FragmentManager активности вызывает Fragment.onActivityResult(…) для соответствующего фрагмента. 
//    Если хостом двух фрагментов является одна активность, то для возвращения данных можно воспользоваться методом Fragment.onActivityResult(…) и вызывать его непосредственно для целевого фрагмента. Он содержит все необходимое: 
//  код запроса, соответствующий коду, переданному setTargetFragment(…), по которому целевой фрагмент узнает, кто возвращает результат; 
//  код результата для определения выполняемого действия; 
//  экземпляр Intent, который может содержать дополнительные данные. 
//        Чтобы получить их, вызовите getTargetFragment() и getTargetRequestCode() для фрагмента, назначившего целевой фрагмент. В файле CrimeFragment.java создайте константу для кода запроса, а затем назначьте CrimeFragment целевым фрагментом экземпляра DatePickerFragment. 
        if (getTargetFragment() == null) { 
            return; 
        } 
//        Чтобы получить данные в DatePickerFragment, мы сохраним дату в пакете аргументов DatePickerFragment, где DatePickerFragment сможет обратиться к ней. 
        Intent intent = new Intent(); 
        intent.putExtra(EXTRA_DATE, date); 
 
        getTargetFragment() 
                .onActivityResult(getTargetRequestCode(), resultCode, intent); 
    } 
} 

 
MyTetra Share v.0.52
Яндекс индекс цитирования