Как разделить основной вид деятельности и указатель даты на собственные классы - PullRequest
4 голосов
/ 14 ноября 2011

Эта маленькая штука начала меня сильно расстраивать.Я думал, что это было что-то простое, но я не совсем ясно понял, как работает Android.

В любом случае, проблема в том, что в моем приложении для Android есть несколько кнопок, которые открывают диалог выбора даты или времени.коробка при нажатии.Я знаю, как реализовать их непосредственно в том же классе, что и основной вид деятельности, но я не думаю, что это хорошее решение по причинам обслуживания, а также, если я собираюсь разрабатывать это приложение в будущем.

Я пытался сделать это несколькими различными способами и терпел неудачу каждый раз, когда пытался это сделать.Это оставило меня в неведении о том, что делать и в чем проблема.

Вот один из способов, которым я пытался это сделать:

основное действие (я упростил его и попытался предоставить только необходимый кодпотому что это долго).Это следующий шаблон проектирования синглтона.

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

Класс средств выбора даты (расширяет Activity; также упрощенный код и все ненужные вещи удалены):

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 Ответ

1 голос
/ 15 ноября 2011

Я думаю, что могу вам помочь.

Я знаю, что мое решение не будет следовать вашему одноэлементному подходу, но оно определенно отделяет код DatePicker от вызывающего Activity или Activity - который в свою очередь становится модульным иclean.

Итак, вот и все: ниже указан код DatePicker (я назвал его 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"
    />

Ваша вызывающая активность или действия должны запустить 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 из вызывающего Activity:

Intent dp = new Intent(EventForm.this, DateSelector.class);
EventForm.this.startActivityForResult(dp, REQUEST_GET_DATE);

И, наконец, в вызывающем Activity просто поймайте его на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;
    }
}

Надеюсь, это поможет, надеюсь, вам понравится,

Best,

-serkan

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