0

I have an array of objects displayed in a list view inside the MainActivity, and to add a filter to the list I added a floating button in the MainActivity that shows a dialog fragment.

Edit I know it's a NullPointerException error and it's coming from the edittext, I want to know what's wrong with to code that made it so.

The dialog shows 2 edit text fields with default positive and negative button.

I want to call a custom method when the positive button is pressed that retrieve the text entered in the edit text and then filter the list based on that.

the problem is I get

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

The code
MainActivity

public class MainActivity extends AppCompatActivity {

private  ListView listView;
public CustomAdaptar adaptar;

protected static ArrayList<Trip> trips = new ArrayList<>();
protected static ArrayList<Trip> allTrips = new ArrayList<>();

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

    listView = (ListView) findViewById(R.id.listView);
    adaptar = new CustomAdaptar();
// A lot of code for setting the list and other funcutionality

    FloatingActionButton fab_filter = (FloatingActionButton) findViewById(R.id.fab_filter);
    fab_filter.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            DialogFrag filter = new DialogFrag();
            filter.show(getFragmentManager(),"Filter");
        }
} }

DialogFragment Code

public class DialogFrag extends DialogFragment{
LayoutInflater inflater;
EditText min;
EditText max;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    inflater = getActivity().getLayoutInflater();
    builder.setView(inflater.inflate(R.layout.filter_popup, null));

    builder.setMessage("Filter")
            .setPositiveButton("Filter", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    customFilter();
                }
            })
            .setNegativeButton("Back", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {

                }
            });

    min = (EditText) getView().findViewById(R.id.et_filterMinPrice);
    max = (EditText) getView().findViewById(R.id.et_filterMaxPrice);
    return builder.create();
}

public void customFilter() {
    MainActivity.trips.clear();

    String et_minPrice = min.getText().toString();
    String et_maxPrice = max.getText().toString();

    int minPrice = Integer.parseInt(et_minPrice);
    int maxPrice = Integer.parseInt(et_maxPrice);

    if ( et_minPrice.length()>0 && et_maxPrice.length()==0) {
        //Do the filtering
        }

edit stacktrace

FATAL EXCEPTION: main
                                                                                 Process: com.transcendedapps.customlistandjson, PID: 1071
                                                                                 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
                                                                                     at com.transcendedapps.customlistandjson.DialogFrag.customFilter(DialogFrag.java:49)
                                                                                     at com.transcendedapps.customlistandjson.DialogFrag$2.onClick(DialogFrag.java:29)
                                                                                     at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                     at android.os.Looper.loop(Looper.java:158)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:7229)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Amr Yasser
  • 17
  • 10

1 Answers1

0

To inflate views inside DialogFragment you should use onViewCreated(View view, @Nullable Bundle savedInstanceState) because in onCreate(@Nullable Bundle savedInstanceState) you do not have the inflated view yet. You can do something like this:

First add a button to your filter_popup layout. Then:

public static DialogFrag newInstance(FragCallback callback) {
    Bundle bundle = new Bundle();
    bundle.putSerializable("FragCallback", callback);
    DialogFrag dialog = new DialogFrag();
    dialog.setArguments(bundle);
    return dialog;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.filter_popup, container, false);
}
...
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    this.callback = (FragCallback) getArguments().getSerializable("FragCallback");
    min = (EditText) view.findViewById(R.id.et_filterMinPrice);
    max = (EditText) view.findViewById(R.id.et_filterMaxPrice);
    customButton = (Button) view.findViewById(R.id.custom_button); // the button in your layout
    customButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            callback.filter(min.getText().toString(),min.getText().toString());
        }
    });
}

The callback interface:

public interface FragCallback extends Serializable {

    void filter(String min, String max);
}

On your activity:

public class MainActivity extends AppCompatActivity implements FragCallback{
...
 FloatingActionButton fab_filter = (FloatingActionButton) findViewById(R.id.fab_filter);
fab_filter.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      DialogFrag.newInstance(this).show(getFragmentManager(),FragDialog.class.getSimpleName());
    }
}
....
@Override
public void filter(String max, String min){
    //do the filtering
}

With this solution there is no need to call onCreateDialog(Bundle savedInstanceState).

Jonathan Aste
  • 1,764
  • 1
  • 13
  • 20
  • The code I used is almost copy paste from google Dialog reference https://developer.android.com/guide/topics/ui/dialogs.html#DialogFragment – Amr Yasser Mar 22 '17 at 21:06
  • Refer to the new documentation here: https://developer.android.com/reference/android/app/DialogFragment.html – Jonathan Aste Mar 23 '17 at 15:01
  • let me know if its useful for you – Jonathan Aste Mar 23 '17 at 15:01
  • I'll try your code out, but for now I solved the the issue by switching getView with getDialog... min = (EditText) getView().findViewById(R.id.et_filterMinPrice); to min = (EditText) getDialog().findViewById(R.id.et_filterMinPrice); – Amr Yasser Mar 26 '17 at 00:26
  • tried this today and it worked fine, but u can't set positive and negative buttons using this method – Amr Yasser Apr 21 '17 at 23:01
  • you can create your own positive and negative buttons, within your custom layout – Jonathan Aste Apr 22 '17 at 23:44