#android #class #android-widget #singleton #datepicker
#Android #класс #android-виджет #синглтон #средство выбора даты
Вопрос:
Эта мелочь начала меня сильно расстраивать. Я думал, что это что-то простое, но, думаю, я не совсем понял, как работает Android.
В любом случае, проблема в том, что в моем приложении для Android будет несколько кнопок, которые при нажатии открывают диалоговое окно выбора даты или времени. Я знаю, как реализовать их непосредственно в том же классе, что и само основное действие, но я не думаю, что это хорошее решение по причинам обслуживания, а также на тот случай, если я собираюсь когда-нибудь продолжить разработку этого приложения.
Я пытался сделать это несколькими различными способами и каждый раз терпел неудачу, когда пытался это сделать. Это оставило меня довольно невежественным в том, что делать и в чем проблема.
Вот один из способов, которым я пытался это сделать:
основное действие (я упростил его и постарался предоставить только необходимый код, потому что он длинный). Это соответствует шаблону проектирования singleton.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dateButton = (Button) findViewById(R.id.editDateButton);
dateButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if(view.getId() == R.id.editStartDateButton) {
DatePickers.getInstance().setDate(dateButton);
}
}
Класс средств выбора даты (расширяет действие; также упрощен код и удалены все ненужные вещи):
private static DatePickers self = null;
public static DatePickers getInstance() {
if (null == self) {
self = new DatePickers();
}
return self;
}
public void setDate(Button button) {
theButtonUsed = button;
showDialog(DATE_DIALOG_ID);
}
После вызова ShowDialog класс похож на пример Hello-DatePicker на сайте разработчика Android.
Также я попытался сделать это почти так же, как здесь, но с той разницей, что при нажатии кнопки dateButton запускается новое действие, представляющее собой диалоговое окно выбора даты. В этом случае класс DatePicker был таким:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datePicker);
showDialog(DATE_DIALOG_ID);
}
И все остальное, как в примере Hello-DatePicker на сайте разработчиков Android. Оба эти решения приводят к проблеме, из-за которой мое приложение разбилось и было вынуждено завершить работу.
Я надеюсь, вы понимаете, в чем проблема, и что вы могли бы направить меня и показать, что я делаю неправильно. Я постарался сделать это коротким и предоставить только необходимую информацию.
Спасибо -Z
Редактировать:
Как я упоминал в одном из комментариев, реальная проблема заключалась в том, что я просто забыл добавить новое действие в файл манифеста. Возможно, были некоторые другие проблемы, которые были решены с помощью принятого ответа. Я надеюсь, что это все еще полезно для всех, кто сталкивается с подобными проблемами.
Ответ №1:
Я думаю, что могу вам в этом помочь.
Я знаю, что мое решение не будет следовать вашему одноэлементному подходу, но оно определенно отделяет код выбора даты от вызывающего действия или Activities, который, в свою очередь, становится модульным и чистым.
Итак, вот оно: ниже приведен назначенный код выбора даты (я назвал его DateSelector). Вы запускаете этот activityForResult, и он вернет пакет с указанием дня, месяца и года для вызывающего действия.
Я также собираюсь вставить простой макет, который DateSelector использует прямо под ним; это просто прозрачный макет…
package com.cyberfabric.historicise.activities;
import java.util.Calendar;
import com.cyberfabric.historicise.R;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
public class DateSelector extends Activity{
private final static int DIALOG_DATE_PICKER = 0;
private int setYear;
private int setMonth;
private int setDay;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.date_picker);
Calendar today = Calendar.getInstance();
setYear = today.get(Calendar.YEAR);
setMonth = today.get(Calendar.MONDAY);
setDay = today.get(Calendar.DAY_OF_MONTH);
showDialog(DIALOG_DATE_PICKER);
}
@Override
protected Dialog onCreateDialog(int id){
switch(id){
case DIALOG_DATE_PICKER:
return new DatePickerDialog(this, mDateSetListener, setYear, setMonth, setDay);
}
return null;
}
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener(){
@Override
public void onDateSet(android.widget.DatePicker view, int year, int month, int day) {
setYear = year;
setMonth = month;
setDay = day;
returnDate();
}
};
/*
* Package up the data and return it back to the calling intent
*/
private void returnDate(){
Intent intent = getIntent(); // calling/parent intent //
Bundle bundle = new Bundle();
bundle.putInt("year", setYear);
bundle.putInt("month", setMonth);
bundle.putInt("day", setDay);
intent.putExtra("set_date", bundle);
setResult(Activity.RESULT_OK, intent);
finish();
}
}
Вот макет, который использует DateSelector:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/transparent"
/>
Ваше вызывающее действие или Activities должны запускать DateSelector как таковой:
// some global variable declared in order to start activityForResult and to catch
// it back on onActivityResult
private final static int REQUEST_GET_DATE = 3;
Запуск DateSelector из вызывающего действия:
Intent dp = new Intent(EventForm.this, DateSelector.class);
EventForm.this.startActivityForResult(dp, REQUEST_GET_DATE);
И, наконец, в вашей вызывающей активности просто поймайте ее на activityresult:
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case REQUEST_GET_DATE:
if(resultCode == Activity.RESULT_OK){
Bundle setDate = data.getBundleExtra("set_date");
int setDay = setDate.getInt("day");
int setMonth = setDate.getInt("month");
int setYear = setDate.getInt("year");
System.out.println(setDay " " setMonth " " setYear);
}
break;
}
}
Я надеюсь, это поможет, надеюсь, вам понравится,
Лучшие,
-serkan
Комментарии:
1. Спасибо за ваш ответ. Это сработало после некоторой модификации, хотя реальная причина этой проблемы была действительно банальной: я забыл добавить новое действие в файл манифеста: 3
2. какие изменения вы применяете? это не сработало в оригинальной форме? было бы полезно для других, если бы вы прокомментировали или отредактировали оригинальный ответ serkan .. 10q