Получение данных в AlertDialog, избегая «Попытка вызвать виртуальный метод по нулевой ссылке на объект» - PullRequest
0 голосов
/ 29 января 2019

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

package com.profiapp.profi;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

public class DataListFragment extends Fragment {

    private RecyclerView contactList;
    private ContactListAdapter adapter;
    private LinearLayoutManager layoutManager;
    private SQLiteDatabase mDatabase;
    private static DataListFragment instance;
    private AlertDialog optionDialog;


    public DataListFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        contactList = (RecyclerView) inflater.inflate(R.layout.fragment_data_list,
                container, false);

        layoutManager = new LinearLayoutManager(getActivity());
        contactList.setLayoutManager(layoutManager);

        ProfiDatabase profi = new ProfiDatabase(getContext());
        mDatabase = profi.getWritableDatabase();


        adapter = new ContactListAdapter(getContext(), getAllItems());
        contactList.setAdapter(adapter);
        adapter.setListener(new ContactListAdapter.Listener() {
            @Override
            public void onLongClick(long id, String nr, String ad, String dat) {
                openOptionDialog(id, nr, ad, dat);
            }
        });

        instance = this;

        return contactList;
    }
    public void onStart(){
        super.onStart();
    }



    public Cursor getAllItems() {
        return mDatabase.query(
                ContactContract.ContactEntry.TABLE_NAME,
                null,
                null,
                null,
                null,
                null,
                "_id DESC"
        );
    }

    public static DataListFragment getInstance(){
        return instance;
    }

    public void updateCursor(){
        adapter.swapCursor(getAllItems());
    }

    public void openOptionDialog(final long entryId, final String nr, final String ad, final String dat){

        AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if(position == 0){
                    NewContactDialogFragment fragment = new NewContactDialogFragment();
                    fragment.show(getActivity().getSupportFragmentManager(), "contact");
                    fragment.onEditContact(nr, ad, dat);


                }else if(position == 1){
                    deleteEntry(entryId);
                    optionDialog.dismiss();
                }
            }
        } ;

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getLayoutInflater();
        View optionMenu = inflater.inflate(R.layout.fragment_option_alert_dialog, null);
        builder.setView(optionMenu);
        builder.setTitle("Nustatymai");
        ListView optionsList = optionMenu.findViewById(R.id.option_list);
        optionsList.setOnItemClickListener(itemClickListener);
        builder.setNeutralButton(R.string.atsaukti, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.setCancelable(true);
        optionDialog = builder.create();
        optionDialog.show();

    }

    public void deleteEntry(long id){
        mDatabase.delete(ContactContract.ContactEntry.TABLE_NAME,
                "_id = ?",
                new String[]{Long.toString(id)});
        updateCursor();
    }
}

package com.profiapp.profi;


import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import static com.profiapp.profi.ProfiDatabase.insertContact;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;



public class NewContactDialogFragment extends DialogFragment {
    private AlertDialog contact;
    private static View dialogView2;
    private View dialogView;
    private EditText numerisMade;
    private EditText addressMade;
    private TextView dateMade;



    public NewContactDialogFragment() {
        // Required empty public constructor
    }

    public class onClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.input_date:
                    new DataPickerFragment().show(getActivity().getSupportFragmentManager(),
                            "datapicker");
            }
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        dialogView = inflater.inflate(R.layout.fragment_new_contact_dialog, null);
        dialogView2 = dialogView;
        TextView date = dialogView.findViewById(R.id.input_date);
        Date currentDate = Calendar.getInstance().getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String currentDateTimeString = format.format(currentDate);
        date.setText(currentDateTimeString);
        date.setOnClickListener(new onClick());
        final EditText numeris = dialogView.findViewById(R.id.input_number);
        final EditText address = dialogView.findViewById(R.id.input_address);

         TextWatcher textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if(!numeris.getText().toString().isEmpty() && !address.getText().toString().isEmpty()
                && numeris.getText().toString().trim().length() == 11 || numeris.getText().toString().trim().length() == 9) {
                    contact.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
                }else{
                    contact.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
                }
            }
        };

         numeris.addTextChangedListener(textWatcher);
         address.addTextChangedListener(textWatcher);


        builder.setView(dialogView)
                .setTitle("Prideti nauja adresata")
                .setPositiveButton(R.string.prideti, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    TextView date = dialogView.findViewById(R.id.input_date);

                        long nr = Long.parseLong(numeris.getText().toString());
                        String adresas = address.getText().toString();
                        String data = date.getText().toString();
                        onPrideti(nr, adresas, data);
                }
            })
                .setNegativeButton(R.string.atsaukti, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dismiss();
                    }
                });

        contact = builder.create();
        contact.setCancelable(true);
        return contact;


    }

    public void onStart(){
        super.onStart();
        contact.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    }



    public void onPrideti(long nr, String adresas, String data){
        SQLiteOpenHelper profi = new ProfiDatabase(getContext());
        SQLiteDatabase db = profi.getWritableDatabase();
        insertContact(db, adresas, nr, data);
        db.close();
        DataListFragment.getInstance().updateCursor();
    }


    public static void setNewDate(String date){
        TextView dateInput = dialogView2.findViewById(R.id.input_date);
        dateInput.setText(date);
    }

    public void onEditContact(String nr, String adresas, String data){
        numerisMade = dialogView.findViewById(R.id.input_number);
        addressMade = dialogView.findViewById(R.id.input_address);
        dateMade = dialogView.findViewById(R.id.input_date);

        numerisMade.setText(nr);
        addressMade.setText(adresas);
        dateMade.setText(data);
    }
}

Теперь я хочу использовать тот же AlertDialog, который я использую, чтобы добавить новый контакт для редактирования сведений о контактах.До сих пор мне удавалось получить необходимые данные из моей базы данных, однако каждый раз, когда я пытаюсь добавить текст в AlertDialog, я получаю это исключение «Попытка вызвать виртуальный метод для ссылки на нулевой объект».Я вроде получаю, что когда я вызываю метод set (onEditContact ()) для установки значений для моего AlertDialog, представления еще не инициализированы, и поэтому исключение, но я хотел бы знать, есть ли способ обойти это и заполнитьпредставления после того, как они были созданы вместе с AlertDialog?

1 Ответ

0 голосов
/ 30 января 2019

Я решил проблему, создав идентичный фрагмент AlerDialog и передав мои значения его методу onCreate, а не пытаясь передать данные после того, как они были созданы.Не знаю, если это правильный способ сделать это, но это сработало как шарм

...