-2

I'm pretty new at Android, so I've already seen similar questions like mine, but I still can't send a Text to another fragment. I get this following error:

java.lang.NullPointerException: Attempt to invoke virtual method '

Here's the code, for better understanding...

FragOne

public class FragOne extends Fragment {

SendDados enviar;
String NumPessoas;

public interface SendDados{
    void setdados(String numPessoas);
}

@Override
public void onAttach(Activity activity){
    super.onAttach(activity);
    try{ enviar=(SendDados)activity;
    }catch (ClassCastException e){
      throw new ClassCastException("erro");
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.reserva_layout, container, false);


final TextView numero=(TextView)rootView.findViewById(R.id.qtdPessoas);

reservar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
NumPessoas= numero.getText().toString();
enviar.setdados("1");
}
});

FragTwo

 public class FragTwo extends Fragment {

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.confirm_reserva_layout, container, false);

    numeroPessoas=(TextView)rootView.findViewById(R.id.numPessoas);
return rootView;

}

public void UpdateDados(String numPessoas)

{
   numeroPessoas.setText(numPessoas);
}

Activity

  public class MenuActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener,ReservaFragment.SendDados {

  @Override
public void setdados(String numPessoas) {
 ConfirmaReservaFragment cf=      (ConfirmaReservaFragment)getSupportFragmentManager().findFragmentById(R.id.confirmaReserva);
    cf.UpdateDados(numPessoas);
}

What I need to do is this, when I click the button, the textView from FragOne, must be copied to FragTwo, what am I doing wrong here? I always get this error: java.lang.NullPointerException: Attempt to invoke virtual method '

I appreciate any help.

Amit Upadhyay
  • 7,179
  • 4
  • 43
  • 57

4 Answers4

1

Since we are talking about simple TextViews, copying the whole TextView to send it to another fragment seems too complicated for a simple job. Just send a String and display the text inside a new TextView inside FragTwo.

I recommend reading this link for passing parameters to fragments before their construction.

If you insist on passing TextViews as parameters to fragments then you are going to have to find a way to serialize TextViews (I don't think they implement Parcelable) and that won't be a simple job.

Regarding your code:

  • Names of objects start with small caps (first snippet).
  • Names of methods start with small caps (last snippet).
  • Use instanceof in onAttach (first snippet).
  • I don't see what ConfirmaReservaFragment is?

Also I really really recommend you type your code in English.

Community
  • 1
  • 1
Spidey
  • 894
  • 1
  • 13
  • 29
  • Totally agree your lack of standars is disturbing hahaha read this http://www.cs.dartmouth.edu/~campbell/cs65/guide.pdf – Juan Hurtado Aug 16 '16 at 00:52
  • Thank you guys I'm new at this, and I really need to improve my code. I'll keep in mind that! Do i have to specify the activity on the OnAttach method? like if (context instanceof ReservActivity) { enviar= (SendDados) context;}} –  Aug 16 '16 at 22:02
  • By the way the idea is not to copy the whole TextView, is just simply send a String and display the text inside the TextView, seems to be easy, but I think there's something missing, and I don't know why I keep getting the same error: java.lang.NullPointe‌​rException: Attempt to invoke interface method ' 'void com.example.rhuan.pr‌​ojetomanagetime.fragm‌​ents.ReservaFragment$‌​SendDados.setdados(ja‌​va.lang.String)' on a null object reference... –  Aug 16 '16 at 22:08
1

Fragments should comunicate through an activity so i will post you a short example of how to correctly send data from one fragment to another using a host activity:

First we will use this layout named host activity layout with a framelayout as a parent called host_fragment_container :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/host_fragment_container"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>

now we are going to load our host activity and set this layout as a content view and create a basic method to change fragments on this frame layout :

public class HostActivity extends AppCompatActivity
        implements TextViewContainerFragment.textViewClickListener{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.host_activity_layout);
    }

    private void switchFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.host_fragment_container, fragment)
                .commit();
    }

}

Now lets create our first fragment (the one who will send the text) :

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:id="@+id/text_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>

we will use this same xml file for both sender and receiver fragments

public class TextViewContainerFragment extends Fragment {

    public interface textViewClickListener {
        void onTextViewClicked(String value);
    }

    private textViewClickListener mActivityCallback;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.text_view_container_fragment, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        final TextView textView = (TextView) view.findViewById(R.id.text_view);
        //search the view by id and cast it into a text view the set it on click lsitener
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // now if the cast was successful the activity callback will be valid and ready to use
                // but we are going to check if its valid anyways
                if (mActivityCallback != null) {
                    mActivityCallback.onTextViewClicked(textView.getText().toString());
                }
            }
        });
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // if context is extracted from an activity
        // that means its safe to cast
        if (context instanceof Activity) {
            mActivityCallback =
                    (textViewClickListener) context;
        }
    }

    // factory method
    public static TextViewContainerFragment newInstance() {
        return new TextViewContainerFragment();
    }
}

now that we have our interface on the fragment we will implement it on the host activity to listen for callbacks & its going to call a sencond fragment ot display the sent text :

public class HostActivity extends AppCompatActivity
        implements TextViewContainerFragment.textViewClickListener{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.host_activity_layout);

        if (savedInstanceState == null) {
            switchFragment(TextViewContainerFragment.newInstance());
        }
    }

    private void switchFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.host_fragment_container, fragment)
                .commit();
    }

    @Override
    public void onTextViewClicked(String value) {
        switchFragment(TextReceiverFragment.newInstance(value));
    }
}

Here is the code for the receiver fragment (older fragment will be replaced for this one) :

public class TextReceiverFragment extends Fragment {

    public static final String ARG_TEXT_RECEIVED_FROM_ANOTHER_FRAGMENT = "text";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.text_view_container_fragment, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ((TextView) view.findViewById(R.id.text_view)).setText(getArguments() != null ?
                getArguments().getString(ARG_TEXT_RECEIVED_FROM_ANOTHER_FRAGMENT)
                : "No text was sent from another fragment");
    }

    public static TextReceiverFragment newInstance(String text) {
        TextReceiverFragment fragment = new TextReceiverFragment();
        Bundle argument = new Bundle();
        argument.putString(ARG_TEXT_RECEIVED_FROM_ANOTHER_FRAGMENT,
                text);
        fragment.setArguments(argument);

        return  fragment;
    }
}
Juan Hurtado
  • 358
  • 1
  • 7
  • That's awesome! I've made some changes in my code following yours and I got in the same error. My interface method is giving me NULL! I realized that because at first when I clicked the button nothing happened. So without the if condition, when I click the button it gives me the ERROR: java.lang.NullPointerException: Attempt to invoke interface method ' 'void com.example.rhuan.projetomanagetime.fragments.ReservaFragment$SendDados.setdados(java.lang.String)' on a null object reference... I created an another activity to host the fragments but still getting the error. Thanks anyway! –  Aug 16 '16 at 22:00
  • Make sure you are pointing to the right xml, maybe thats it. When i was learning android some times i spent a lot of time trying to figure out a bug and ended up being something silly. It just happens haha – Juan Hurtado Aug 16 '16 at 22:15
  • You were right the problem was pointing to the correct XML... thank you! –  Sep 27 '16 at 20:02
0

If you really want to copy the textview from Fragment 1 to Fragment 2. I suggested you to send the config data (e.g. the text, clicked, color) of the textview instead of the whole object. As the response from Spidey ,sending the widget to other fragment will be a trouble.

To facilitate your work, A textview config model should be used to send the config data of the textview.

public class TextViewConfig implements Parcelable {
private String text;
private boolean selected;
@Override
public int describeContents() {
    return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.text);
    dest.writeByte(this.selected ? (byte) 1 : (byte) 0);
}
public TextViewConfig() {
}
protected TextViewConfig(Parcel in) {
    this.text = in.readString();
    this.selected = in.readByte() != 0;
}
public static final Parcelable.Creator<TextViewConfig> CREATOR = new Parcelable.Creator<TextViewConfig>() {
    @Override
    public TextViewConfig createFromParcel(Parcel source) {
        return new TextViewConfig(source);
    }
    @Override
    public TextViewConfig[] newArray(int size) {
        return new TextViewConfig[size];
    }
};
public String getText() {
    return text;
}
public void setText(String pText) {
    text = pText;
}
public boolean isSelected() {
    return selected;
}
public void setSelected(boolean pSelected) {
    selected = pSelected;
}
}

Since the model class can be implemented as Parcelable easily, you can use it to send the data of the textview. And then you can use the answer from Juan Hurtado to practice the communication between the fragments by sending the config data.

Long Ranger
  • 5,888
  • 8
  • 43
  • 72
0

let's supose u wants to got to the fragment two from fragment one with text "hello" by a click event on fragment one, your code look like this,

class FragOne extends Fragment{
    onCreateView(){
        .
        .
        <your view>.setOnClickListener(new OnClickListener(){
            @cverride
            onClick(){
               Bundle bundle=new Bundle();
               bundle.putString("msg","<ur text will gose here which u wants to send to fragment two>");
               .
               .
               .
              //now move to the fragment two here
              FragTwo fragTwo=new FragTwo();
              fragTwo.setArgument(bundle);
              FragmentManager fragmentManager=getSupportFragmentManager();
              fragmentManager.beginTransaction().add(<ur root layout is>,fragmentTwo).commit();

            }
        });
    }
}

Now in ur Fragmnet Two,

class FragTwo extends Fragment{
        onCreateView(){
            .
            .
            //get text which is send by fragment one
            Bundle bundle=new Bundle();
            String text=bundle.getString("msg");//this is ur text which is send by fragment one
        }
    }

Hope this will help u,