2

I'm trying to call a method that is inside another class that will populate TextViews when an item is clicked inside AutoCompleteTextView that is also inside an AlertDialogInput.

But my app crashes when I click an Item.

I'm new in android development so any help would be pretty much appreciated.

Custom Alert Dialog Alert Dialog Class

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

This is the code to show AlertDialogInput Main Activity


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

this is the method that I want to call when an Item is clicked inside AlertDialog AutocompleteTextview that is also inside Main Activity to populate my textview insid main activity

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

Data Base Helper

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

projection that calls inside database helper

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

When I Click The Text View Alert Dialog Pops Up

enter image description here

When I Type number The autocompletetextview will suggest data that has the same value from sqlite database table

enter image description here

But when I click an Item this Happens


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)

How can I create communication between my alert dialog class and main activity so i can use that method?

  • Please have a look at [this answer](https://stackoverflow.com/a/37122385/7948109). In this answer they have used Fragment. you can Implement similar implication using `interface` in `Dialogs` – Rahul Gaur Jan 27 '20 at 04:04

4 Answers4

1

Use LocalBroadcastManager. Register a receiver in onResume method in your activity, with a specific action, for example "executeMainActivityCode" can be it. For that, you need something like this:

onResume:

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

onPause (don't forget about this):

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

From your dialog, call this code:

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

Inside the receiver, call your method in onReceive and you're good to go.

Furkan Yurdakul
  • 2,801
  • 1
  • 15
  • 37
  • One more problem sir, ```ConsumerAccountForPrinting = toprint_auto_account_search_dialog.getText().toString();``` Since toprint_auto_account_search_dialog AutoCompleteTextview is inside Alert Dialog and Not in MainActivity I'm getting a null pointer exception. How can I solve this –  Jan 30 '20 at 00:13
0

You're calling findViewById too early:

Account_No = findViewById(R.id.toprint_Account_No_Value);

This calls it when the Activity is being constructed. Try replacing Account_No in getotherinformationbyaccountforprinting with findViewById(R.id.toprint_Account_No_Value), or setting up Account_No in onCreate after calling setContentView.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • That is not the problem, the problem is when I try to execute ```getotherinformationbyaccountforprinting()``` I get a null object exception –  Jan 28 '20 at 05:27
  • Right, I got that part - did you try my suggestion? You're calling `findViewById` too early, it sets `Account_No` to `null`, so it's `null` when you access `Account_No` in `getotherinformationbyaccountforprinting`. If you call it in `getotherinformationbyaccountforprinting` like I suggested, it shouldn't be `null` at that point. – Ryan M Jan 28 '20 at 20:24
0

As I suggested in the comment you can use interface to communicate between Activities/Fragments/Adapters/etc`.

1. create an Interface

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

2. implement the interface in your activity

3. pass interface in alertDialog

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

4. in your dialog receive the interface using constructor


private DataTransfer dataTransfer;

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

5. User this dataTransfer to pass data to activity

dataTransfer.sendData("Some important data");

6. In your activity there will be an @Override method void sendData(String data);

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

Edit 1: explanation

There is 1 Activity A and 1 DialogFragment B

B wants to send data to A

A gives B an interface so when B calls dataTransfer.sendData("Hello");

A will also call it's own overridden sendData(String data);

Now if you print this

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

This will print

Hello

You can call any other method from sendData

Hope this will help!

Please ask if you need more help

Community
  • 1
  • 1
Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
  • How is this going to execute the method ```getotherinformationbyaccountforprinting()``` ? that will populate textviews inside the main activity –  Jan 28 '20 at 00:43
  • add this method inside `sendData` and pass the data as parameters – Rahul Gaur Jan 28 '20 at 03:43
  • Can u please elaborate your answer more? Sorry I'm new to this:( –  Jan 28 '20 at 05:28
  • Please check my updated answer, please ask if you need explanation related to anything else – Rahul Gaur Jan 28 '20 at 08:58
0

Found an answer on how to get the text from AutoCompletetextview from another class or a fragment

Inside Main Activity on Create Add fragment support

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

Then Inside your fragment onCreate Add the following codes

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

Then Inside Main Activity Create a variable and put the value of autocompletetextview like this

    public void account_no_to_print(String account_no)
    {
        this.ConsumerAccountForPrinting = account_no;
    }