Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

DatePicker

Элемент DatePicker позволяет пользователю выбрать дату (число, месяц, год). Данный виджет используют как правило на отдельном экране. Также существует похожее по функционалу диалоговое окно DatePickerDialog.

DatePicker находился в разделе Date & Time в Android Studio 3.01. Сейчас на панели инструментов данного компонента нет, поэтому придётся добавлять вручную.

Нужно помнить, что внутренняя нумерация месяцев в Android начинается с 0, поэтому январь = 0, февраль = 1 и т.д. Поэтому как правило, в коде следует прибавлять единицу к значению месяца при работе с датой или наоборот - отнимать единицу, если данные поступают снаружи (например, из текстового поля).

Добавим на экран текстовую метку, кнопку и виджет даты:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="47dp"
        android:text="New Button"/>

    <DatePicker
        android:id="@+id/datePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"/>
</RelativeLayout>

Пользователь может выбрать любую дату на виджете, а обычный щелчок на кнопке позволит отобразить выбранную дату в текстовой метке. Длительное нажатие на кнопку устанавливает текущую дату на виджете и в текстовой метке.

Настройка даты на самом виджете происходит через метод init(). Изменение даты можно прослушивать через OnDateChangedListener():


package ru.alexanderklimov.datepicker;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Calendar;

public class MainActivity extends AppCompatActivity {

    private DatePicker mDatePicker;
    private TextView mInfoTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mInfoTextView = (TextView) findViewById(R.id.textView);
        mDatePicker = (DatePicker) findViewById(R.id.datePicker);

        Calendar today = Calendar.getInstance();

        mDatePicker.init(today.get(Calendar.YEAR), today.get(Calendar.MONTH),
                today.get(Calendar.DAY_OF_MONTH), new DatePicker.OnDateChangedListener() {

                    @Override
                    public void onDateChanged(DatePicker view, int year,
                                              int monthOfYear, int dayOfMonth) {
                        Toast.makeText(getApplicationContext(),
                                "onDateChanged", Toast.LENGTH_SHORT).show();

                        mInfoTextView.setText("Год: " + year + "\n" + "Месяц: "
                                + (monthOfYear + 1) + "\n" + "День: " + dayOfMonth);
                    }
                });

        Button changingDateButton = (Button) findViewById(R.id.button);
        changingDateButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                mInfoTextView.setText(new StringBuilder()
                        // Месяц отсчитывается с 0, поэтому добавляем 1
                        .append(mDatePicker.getDayOfMonth()).append(".")
                        .append(mDatePicker.getMonth() + 1).append(".")
                        .append(mDatePicker.getYear()));
            }
        });

        changingDateButton.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                setCurrentDateOnView();

                return true;
            }
        });
    }

    // устанавливаем текущую дату
    public void setCurrentDateOnView() {
        final Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        // set current date into textview
        mInfoTextView.setText(new StringBuilder()
                // Месяц отсчитывается с 0, поэтому добавляем 1
                .append(day).append(".").append(month + 1).append(".")
                .append(year));

        // Устанавливаем текущую дату для DatePicker
        mDatePicker.init(year, month, day, null);
    }
}

DatePicker

Настройка компонента

По умолчанию DatePicker состоит из двух элементов - Spinner и CalendarView. Вы можете настроить внешний вид компонента, если укажете через XML-атрибуты android:calendarViewShown и android:spinnersShown, какой элемент не нужно выводить. Также можно это сделать программно через методы setCalendarViewShown() и setSpinnersShown() (API level 11).

Напишем пример программного управления внешним видом DatePicker:


<?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="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:paddingBottom="@dimen/activity_vertical_margin"
              android:paddingLeft="@dimen/activity_horizontal_margin"
              android:paddingRight="@dimen/activity_horizontal_margin"
              android:paddingTop="@dimen/activity_vertical_margin">

    <RadioGroup
        android:id="@+id/optGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RadioButton
            android:id="@+id/optCalendar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="CalendarView"/>

        <RadioButton
            android:id="@+id/optSpinners"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Spinners"/>

        <RadioButton
            android:id="@+id/optBoth"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Both"/>
    </RadioGroup>

    <DatePicker
        android:id="@+id/datePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="true"
        android:spinnersShown="false"/>

</LinearLayout>

Код для активности:


package ru.alexanderklimov.datepicker;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.DatePicker;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class MainActivity extends AppCompatActivity {

    private DatePicker mDatePicker;
    private RadioButton mCalendarRadionButton;
    private RadioButton mSpinnerRadioButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mDatePicker = (DatePicker) findViewById(R.id.datePicker);

        RadioGroup radioGroup = (RadioGroup) findViewById(R.id.optGroup);
        mCalendarRadionButton = (RadioButton) findViewById(R.id.optCalendar);
        mSpinnerRadioButton = (RadioButton) findViewById(R.id.optSpinners);
        mDatePicker = (DatePicker) findViewById(R.id.datePicker);

        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (mCalendarRadionButton.isChecked()) {
                    mDatePicker.setCalendarViewShown(true);
                    mDatePicker.setSpinnersShown(false);
                } else if (mSpinnerRadioButton.isChecked()) {
                    mDatePicker.setCalendarViewShown(false);
                    mDatePicker.setSpinnersShown(true);
                } else {
                    mDatePicker.setCalendarViewShown(true);
                    mDatePicker.setSpinnersShown(true);
                }
            }
        });
    }
}

DatePicker

Новый внешний вид в Android 5.0 (API 21) Lollipop

В Android 5.0 (API 21) внешний вид компонента изменился. Поэтому неплохо бы проверить, всё ли работает в старом коде.

TimePicker

Скриншот взят из статьи Криминальное чтиво.

Реклама