Как избежать исключения нулевого указателя в двух видах деятельности - PullRequest
2 голосов
/ 27 января 2020

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

Но мое приложение падает, когда я щелкаю элемент.

Я новичок в разработке android, поэтому любая помощь будет весьма признательна.

Диалог настраиваемого оповещения Класс диалогового окна оповещения

public static class ToPrintAccountSearchDialog extends AppCompatDialogFragment
    {
        private AutoCompleteTextView toprint_auto_account_search_dialog;

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

            LayoutInflater layoutInflater = getActivity().getLayoutInflater();
            View view = layoutInflater.inflate(R.layout.for_printing_account_search_dialog_layout, null);
            builder.setView(view);
            builder.setTitle("Search Account");

            List<ForBillPrintConsumerEntities> forBillPrintConsumerEntities = new ArrayList<>();
            toprint_auto_account_search_dialog = view.findViewById(R.id.Alert_Dialog_Account_Auto_Search);
            ForPrintingConsumerAccountSearchAdapter forPrintingConsumerAccountSearchAdapter = new ForPrintingConsumerAccountSearchAdapter(getActivity(), forBillPrintConsumerEntities);
            toprint_auto_account_search_dialog.setThreshold(1);
            toprint_auto_account_search_dialog.setAdapter(forPrintingConsumerAccountSearchAdapter);
                toprint_auto_account_search_dialog.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
                {
                    PrintBill printBill = new PrintBill();
                    printBill.getotherinformationbyaccountforprinting();
                }
            });

            return builder.create();
        }
    }

Это код для отображения AlertDialogInput Основная активность


Account_No = findViewById(R.id.toprint_Account_No_Value);
        Account_No.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                forPrintAccountSearchDialog();
            }
        });

public void forPrintAccountSearchDialog()
    {
        ToPrintAccountSearchDialog toPrintAccountSearchDialog = new ToPrintAccountSearchDialog();
        toPrintAccountSearchDialog.show(getSupportFragmentManager(), "ToPrintAccountSearchDialog");
    }

это метод, который я хочу вызвать, когда щелчок по элементу внутри AlertDialog AutocompleteTextview, который также находится внутри основного действия, чтобы заполнить мое текстовое представление в основной деятельности

public void getotherinformationbyaccountforprinting()
    {
        ConsumerAccountForPrinting = toprint_auto_account_search_dialog.getText().toString();
        db = new DatabaseHelper(getApplicationContext());
        sqLiteDatabase = db.getReadableDatabase();
        Cursor cursor = db.ForPrintingGetOtherInfoByAccount(ConsumerAccountForPrinting, sqLiteDatabase);
        if (cursor.moveToFirst()) {
            do {
                String ACCOUNT_NUMBER = cursor.getString(0);
                String NAME = cursor.getString(1);
                String ADDRESS = cursor.getString(2);
                Account_No.setText(ACCOUNT_NUMBER);
                Name.setText(NAME);
                Address.setText(ADDRESS);
                }
            while (cursor.moveToNext());
        }
    }

Помощник базы данных

public Cursor ForPrintingGetOtherInfoByAccount(String keyword, SQLiteDatabase sqLiteDatabase)
    {
        String [] projections = {ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.ACCOUNT_NO,
                ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.NAME,
                ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.ADDRESS,
                String selection = ConsumerListOtherInfoAdapterByAccount.getOtherInfoForListByAccount.CONSUMER_ACCOUNT_NO+" LIKE ?";
        String [] selection_args = {keyword};
        Cursor cursor = sqLiteDatabase.query(ForPrintingConsumerOtherInfoAdapterByAccount.getOtherInfoForPrintingByAccount.TABLE_NAME,projections,selection,selection_args,null,null,null);
        return cursor;
    }

проекция, которая вызывает внутри базы данных помощник

public class ForPrintingConsumerOtherInfoAdapterByAccount
{
    public static abstract class getOtherInfoForPrintingByAccount
    {
        public static final String TABLE_NAME = "toPrintBill";
        public static final String ACCOUNT_NO = "account_no";
        public static final String NAME = "name";
        public static final String ADDRESS = "address";
    }
}

enter image description here

Когда я нажимаю диалог оповещения о просмотре текста Выскакивает

enter image description here

* 105 1 * Когда я набираю число Autocompletetextview предложит данные, которые имеют то же значение из таблицы базы данных sqlite

enter image description here

Но когда я щелкните элемент, который происходит


java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.AutoCompleteTextView.getText()' on a null object reference
        at com.vicjames.qiimeterreader.PrintBill.getotherinformationbyaccountforprinting(PrintBill.java:224)
        at com.vicjames.qiimeterreader.PrintBill$ToPrintAccountSearchDialog$1.onItemClick(PrintBill.java:189)
        at android.widget.AutoCompleteTextView.performCompletion(AutoCompleteTextView.java:1017)

Как создать связь между классом диалогового окна оповещений и основным действием, чтобы я мог использовать этот метод?

Ответы [ 4 ]

1 голос
/ 28 января 2020

Используйте LocalBroadcastManager. Зарегистрируйте получателя в методе onResume в своей деятельности, указав конкретное действие c, например, "executeMainActivityCode". Для этого вам нужно что-то вроде этого:

onResume:

LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, new IntentFilter("executeMainActivityCode"));

onPause (не забудьте об этом):

LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver));

В диалоговом окне вызовите этот код:

LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent("executeMainActivityCode"));

Внутри приемника вызовите свой метод в onReceive, и вы готовы к go .

0 голосов
/ 03 февраля 2020

Найден ответ о том, как получить текст из AutoCompletetextview из другого класса или фрагмента

Внутри основного действия при создании Добавить поддержку фрагментов

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        ToPrintAccountSearchDialog toPrintAccountSearchDialog = new 
        ToPrintAccountSearchDialog();
        ToPrintNameSearchDialog toPrintNameSearchDialog = new ToPrintNameSearchDialog();
        fragmentTransaction.add(R.id.activity_print_bill,toPrintAccountSearchDialog);
        fragmentTransaction.commit();

Затем внутри вашего фрагмента onCreate Добавьте следующие коды

            toprint_auto_account_search_dialog = 
            view.findViewById(R.id.Alert_Dialog_Account_Auto_Search);
            toprint_auto_account_search_dialog.setOnItemClickListener(new 
            AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
            {
                String account_no_to_print = 
                toprint_auto_account_search_dialog.getText().toString();
                PrintBill printBill = (PrintBill) getActivity();
                printBill.account_no_to_print(account_no_to_print);
                dismiss();
            }

Затем внутри основного действия Создайте переменную и поместите значение autocompletetextview следующим образом

    public void account_no_to_print(String account_no)
    {
        this.ConsumerAccountForPrinting = account_no;
    }
0 голосов
/ 27 января 2020

Как я предлагал в комментарии, вы можете использовать interface для связи между операциями / фрагментами / адаптерами / и т. Д.

1. создать интерфейс

public interface DataTransfer{
    void sendData(String data); //change parameter to whatever you want
}

2. реализовать интерфейс в своей деятельности

3. передать интерфейс в alertDialog

ToPrintAccountSearchDialog toPrintAccountSearchDialog = 
    new ToPrintAccountSearchDialog(this);  
    // here this will pass the implemented interface

4. в вашем диалоге получите интерфейс используя конструктор


private DataTransfer dataTransfer;

public ToPrintAccountSearchDialog(DataTransfer dataTransfer){
    this.dataTransfer = dataTransfer;
}

5. Пользователь использует эти данные для передачи данных в действие

dataTransfer.sendData("Some important data");

6. В вашей деятельности будет @Override метод void sendData(String data);

@Override
public void sendData(String data) {
    Log.e("TAG", "sendData: this data is from Dialog " + data);
}

Редактировать 1: объяснение

Есть 1 действие A и 1 DialogFragment B

B хочет отправить данные на A

A дает B interface, поэтому, когда B звонит dataTransfer.sendData("Hello");

A, также будет Назовите его overridden sendData(String data);

Теперь, если вы напечатаете это

@Override
public void sendData(String data) {
    Log.e("TAG", "sendData: " + data);
}

Это напечатает

Hello

Вы можете позвонить любому другому method из sendData

Надеюсь, это поможет!

Пожалуйста, спросите, нужна ли вам дополнительная помощь

0 голосов
/ 27 января 2020

Вы звоните findViewById слишком рано:

Account_No = findViewById(R.id.toprint_Account_No_Value);

Это вызывает его, когда строится действие. Попробуйте заменить Account_No в getotherinformationbyaccountforprinting на findViewById(R.id.toprint_Account_No_Value) или настроить Account_No в onCreate после вызова setContentView.

...