0

I have a fragment with an EditText and a Button:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    tools:context=".activity.main" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:id="@+id/etLocation"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/btnSearch"
            android:text="Search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:map="http://schemas.android.com/apk/res-aukto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.app.myapp.activity.main" >
    </FrameLayout>
</LinearLayout>

And from my fragment I am trying to set up an onClickListener for that button so that I can use the text from the etLocation when I click btnSearch:

package com.app.myapp.fragment;

import ...

public class main_fragment extends Fragment implements OnMapReadyCallback, View.OnClickListener{
    GoogleMap googleMap;

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

@Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.fragment_main_fragment, container, false);
    mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    if(mapFragment == null){
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mapFragment = SupportMapFragment.newInstance();
        fragmentTransaction.replace(R.id.map, mapFragment).commit();
    }
    mapFragment.getMapAsync(this);
    Button btnSearch = view.findViewById(R.id.btnSearch);
    btnSearch.setOnClickListener(this);
    return view;
}

@Override public void onMapReady(GoogleMap googleMap){
    this.googleMap = googleMap;
}

@Override public void onClick(View v){
    EditText etLocation = v.findViewById(R.id.etLocation);
    String location = etLocation.getText().toString();
}

My fragment is being displayed within Activity main, and I can see the Button and TextView, but when I click the button my app crashes.

If I comment out the getText() line like this, my app does not crash:

@Override public void onClick(View v){
    EditText etLocation = v.findViewById(R.id.etLocation);
    //String location = etLocation.getText().toString();
}

So I am confident that the getText() is causing the app to crash.

using setText() in this way also causes the app to crash.

Why can't I call getText() (or setText()) in this way?

trinaldi
  • 2,872
  • 2
  • 32
  • 37

1 Answers1

0

Because "v" inside the onClickListener is the clicked View in this case your button.This means you are trying to find a view by id inside the button, which in this case cant happened because a button is not a ViewGroup. You have a couple of ways to do this:

  1. Declare the EditText as a field and find it wherever you find your views
  2. Before you find btnSearch fins the EditeText as a local final variable, set the click listener to the button as an anonymous interface setOnClickListener(new View.OnCl..). Use the EditText variable inside that click listener
  3. Like you are doing it now you can use getView() instead of "v". getView method in a Fragment gives you the Fragment View

As general recommendation in Fragments, Views should be find in the onViewCreated method, you have to override it.

cutiko
  • 9,887
  • 3
  • 45
  • 59
  • Thanks! That worked. I'll come back to upvote after I get enough reputation. –  Mar 17 '18 at 15:00
  • I will recommend to read this about the method differences https://stackoverflow.com/questions/25119090/difference-between-oncreateview-and-onviewcreated-in-fragment – cutiko Mar 17 '18 at 19:01