Java Android ListActivity - 在对话框回调循环后添加行

Java Android ListActivity - row adding after dialog callBack loop

所以我正在做一个项目,制作一个闹钟应用程序。 它仍然是一个工作进展,我只是 android 开发的初学者(我现在正在课程中),所以如果代码看起来效率低下,请原谅我。作为一名蓬勃发展的开发人员,我将不胜感激任何建议。

言归正传。我的问题是,当我添加闹钟时,在设置时间并按下 "Change Alarm Time" 按钮后,添加了 2 行。 调试器显示 "finalizeAlarm" 被调用了两次,我不知道为什么。

主要活动:

package com.nickholden.lazyalarm;

import android.app.FragmentManager;
import android.app.ListActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends ListActivity implements DialogCallBack{

    static final int TIME_DIALOG_ID = 1337;
    ArrayList<Alarm> alarmList = new ArrayList<Alarm>();
    int pos;
    Button btnAlarmSet;
    TextView txtAlarmTime;
    TimePicker timePicker;
    int hour;
    int minutes;
    Button btnChangeTime;
    MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = (ListView) findViewById(android.R.id.list);
        listView.setBackgroundColor(Color.GREEN);
        adapter = new MyAdapter(this, R.layout.activity_alarm,
                android.R.id.text1, alarmList);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(listener);
    }

    private OnItemClickListener listener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            pos = position;
        }
    };
// Add a new alarm
    public void btnAddNewAlarm(View view) {
        FragmentManager fragmentManager = getFragmentManager();
        AlarmDialogFragment alarmDialogFragment = new AlarmDialogFragment(this, new Intent());
        alarmDialogFragment.setCancelable(false);
        alarmDialogFragment.show(fragmentManager, "set_alarm_time");
    }

    public static String pad(int time) {
        if (time >= 10)
            return String.valueOf(time);
        else
            return "0" + String.valueOf(time);
    }

    // Delete the entire row
    public void btnDelete(final View view) {
        // Create delete confirmation dialog here
        alarmList.remove(pos);
        adapter.notifyDataSetChanged();
        Toast.makeText(this, "Alarm Removed", Toast.LENGTH_SHORT).show();
    }

    public void btnClearAll(View view) {
        // Create delete confirmation dialog here
        alarmList.removeAll(alarmList);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void finalizeAlarm(Intent intent) {
       Alarm alarm = (Alarm) intent.getSerializableExtra("alarm");

       adapter.add(alarm);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

interface DialogCallBack{
    public void finalizeAlarm(Intent intent);
} 

我的适配器:

package com.nickholden.lazyalarm;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;

public class MyAdapter extends ArrayAdapter {

    Alarm[] objects;
    Context context;
    int textViewResource;
    int resource;
    View view;

    public MyAdapter(Context context, int resource, int textViewResourceId,
            ArrayList<Alarm> alarmList) {
        super(context, resource, textViewResourceId, alarmList);
        this.context = context;
        this.resource = resource;
        this.textViewResource = textViewResourceId;
        this.objects = alarmList.toArray(new Alarm[alarmList.size()]);
    }

    static class ViewContainer {
        // public ImageView imageView;
        public TextView time;
        public TextView date;
        public Button button;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewContainer viewContainer;
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            rowView = inflater.inflate(resource, null);
            viewContainer = new ViewContainer();
            rowView.setBackgroundColor(Color.MAGENTA);
            viewContainer.time = (TextView) rowView
                    .findViewById(R.id.alarm_time);
            //Code to get time input by user

            viewContainer.date = (TextView) rowView
                    .findViewById(R.id.alarm_date);
            //Code to get date input by user

            viewContainer.button = (Button) rowView.findViewById(R.id.delete);
            rowView.setTag(viewContainer);
        } else {
            viewContainer = (ViewContainer) rowView.getTag();
        }
        return rowView;
    }
}

AlarmDialogFragment:

package com.nickholden.lazyalarm;


import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.Calendar;


/**
 * Created by Nick on 1/12/15.
 */
public  class AlarmDialogFragment extends DialogFragment {
    private TextView textView;
    private TimePicker timePicker;
    private Calendar c;
    int hour;
    int minutes;
    private DialogCallBack callBack;
    private Intent intent;
public AlarmDialogFragment(DialogCallBack callBack, Intent intent) {
    this.callBack = callBack;
    this.intent = intent;
}


@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
    View viewInflater = inflater.inflate(R.layout.activity_alarm_set, container);
    textView = (TextView)viewInflater.findViewById(R.id.current_alarm_time);
    getDialog().setTitle("Set Time Of Alarm");

    Button btnDiss = (Button) viewInflater.findViewById(R.id.done);
    btnDiss.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            getDialog().dismiss();
        }
    });



    Button btnChangeTime = (Button)viewInflater.findViewById(R.id.change_time);
    btnChangeTime.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            changeTime();
        }
    });
    return viewInflater;


}

public void changeTime(){
    FragmentManager fragmentManager = getFragmentManager();
    c = Calendar.getInstance();
    hour = c.get(Calendar.HOUR_OF_DAY);
    minutes = c.get(Calendar.MINUTE);
    TimePickerDialog timePickerDialog;
    timePickerDialog = new TimePickerDialog(getActivity(), listenerSetter(), hour, minutes, true);
    timePickerDialog.show();
}

public TimePickerDialog.OnTimeSetListener listenerSetter() {
    TimePickerDialog.OnTimeSetListener timePickerListener = new TimePickerDialog.OnTimeSetListener() {

        @Override
        public void onTimeSet (TimePicker view, int selectedHour,
                              int selectedMinute) {
            hour = selectedHour;
            minutes = selectedMinute;
            textView.setText(MainActivity.pad(selectedHour) + " : " + MainActivity.pad(minutes));
            Toast.makeText(getActivity().getBaseContext(),
                    "Alarm Set:\n" +  MainActivity.pad(hour) + " : " + MainActivity.pad(minutes),
                    Toast.LENGTH_SHORT).show();
            intent.putExtra("time", MainActivity.pad(selectedHour)+ " : " +MainActivity.pad(minutes));
            Alarm alarm = new Alarm();
            intent.putExtra("alarm", alarm);
            callBack.finalizeAlarm(intent);
        }
    };
    return timePickerListener;

    }

}

报警:

package com.nickholden.lazyalarm;

import java.io.Serializable;
import java.sql.Date;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

public class Alarm implements Serializable {
    public static final long serialVersionUID = 12345L;
    public static int lastIndex = 0;

}

似乎是一个错误。看到这个 Jelly Bean DatePickerDialog --- is there a way to cancel?

添加

if (view.isshown())

之前

callBack.finalizeAlarm(intent);