This question already has answers here:
How to pass values between Fragments
(18 answers)
Closed 6 years ago.
I have Two Dynamic Fragments associated with one activity, I am trying to pass one Text from First Fragment to Second Fragment using Bundle, but I am getting Null Pointer Exception. Is it the right way to pass String between two fragments? Below is my code :
First Fragment
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_main, container, false);
String text = "GetThisStringInSecondFragment";
TextView txtView = null;
txtView = (TextView) view.findViewById(R.id.firstfragmenttext);
txtView.setText(text);
Bundle bundle = new Bundle();
bundle.putString("HI", text);
return view;
}
}
Second Fragment
public class SecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_secondmain,
container, false);
TextView txtView = null;
txtView = (TextView) view.findViewById(R.id.secondfragmenttext);
Bundle bundle = this.getArguments();
String myInt = bundle.getString("HI");
txtView.setText(myInt);
return view;
}
}
Activity
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnLoad = (Button) findViewById(R.id.btn_load);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FirstFragment hello = new FirstFragment();
fragmentTransaction.add(R.id.fragment_container, hello, "HELLO");
fragmentTransaction.commit();
FragmentManager fragmentManager2 = getFragmentManager();
FragmentTransaction fragmentTransaction2 = fragmentManager2.beginTransaction();
SecondFragment hello2 = new SecondFragment();
fragmentTransaction2.add(R.id.fragment_container, hello2, "HELLO");
fragmentTransaction2.commit();
}
};
btnLoad.setOnClickListener(listener);
}
}
You are doing getArguments in second fragment but where are you sending those arguments from first fragment. You can use Interface here and define it in activity. From activity, you can use setArgument() method for second fragment.
check the following link for more detailed information and steps to do that.
https://developer.android.com/training/basics/fragments/communicating.html
Related
UPDATE: This is my current code, however it breaks after I re-click the same button....
Cause: java.lang.IllegalStateException: Fragment already active
I have a main_activity.xml split into Frame layouts.
The upper frame layout contains an edit text and 3 buttons (small, medium, large).
The lower frame layout contains a text view to populate the text of the edit text in either small, medium or large font.
I put the text into a bundle and am attempting to reopen that bundle in the corresponding fragment once the button is clicked.... however, the bundle does not contain any text information from the text according to my debugger.
Here is my code with the medium, large buttons removed
Any help, please?
MainActivity:
public class MainActivity extends AppCompatActivity {
TextView textView;
Button bSmall;
Small fSmall = new Small();
Bundle bundle = new Bundle();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(findViewById(R.id.fragment)!=null){
if(savedInstanceState!=null){
return;
}
}
final EditText editText = (EditText) findViewById(R.id.type_here);
final Button bSmall = (Button)findViewById(R.id.small);
Button bMedium = (Button)findViewById(R.id.medium);
bSmall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message_small = editText.getText().toString();
small = message_small;
bundle.putString("message_small", message_small);
fSmall.setArguments(bundle);
FragmentManager fm =getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment, fSmall).commit();
}
});
bMedium.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message_medium = editText.getText().toString();
bundle.putString("message_medium", message_medium);
fMedium.setArguments(bundle);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment, fMedium).commit();
}
});
}
public String getMyData(){
return small;
}
}
Small:
public class Small extends Fragment {
EditText editText;
View myView;
public Small() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.fragment_small, container, false);
Bundle bundle = new Bundle();
bundle = getArguments();
MainActivity activity = (MainActivity)getActivity();
//String dataFromMainActivity = activity.getMyData();
String myString = bundle.getString("message_small");
TextView set = myView.findViewById(R.id.small_text);
set.setText(myString);
// Inflate the layout for this fragment
return myView;
}
}
You forgot to add the bundle to the fragment.
You need to do something like this:
Small fSmall = new Small();
...
bundle.putString("message_small", message_small);
fSmall.setArguments(bundle);
FragmentManager fm =getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment, fSmall);
I think you forgot to add your bundle to your Fragment before calling the fragment manager.
You should try something like this:
Small fSmall = new Small();
Bundle bundle = new Bundle();
bundle.putString("message_small", message_small); //parameters are (key, value).
fSmall.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, fSmall).commit();
In your second fragment, you should check if myString is not null or empty.
String myString = getArguments().getString("message_small");
if (myString == null) {
Log.e("TAG", "Error: null argument");
}
EDIT I see another problem here. You are accessing varaibles that have not been instatiated. You should inflate your layout before calling findViewById() or it will return a NullPointerException.
Update your Small class like this :
public class Small extends Fragment {
private EditText editText;
View myView;
public Small() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
myView = inflater.inflate(R.layout.fragment_small, container, false);
String myString = getArguments().getString("message_small");
// Here, myView is != null
TextView editText = myView.findViewById(R.id.small_text);
// Here, editText is != null
editText.setText(myString);
return myView;
}
}
Best
This is my view holder class inside adapter class which is a separate class file. The recycler view is shown in a fragment and on click of the recycler view item I need to go to a new fragment activity and get the texts that was shown in the clicked item
public class BookViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public final BookRecyclerAdapter mAdapter;
private TextView titleTextView, authorTextView;
public BookViewHolder(View itemView, BookRecyclerAdapter adapter) {
super(itemView);
titleTextView = (TextView) itemView.findViewById(R.id.listItem_title_tView);
authorTextView = (TextView) itemView.findViewById(R.id.listItem_author_tView);
this.mAdapter = adapter;
itemView.setOnClickListener(this);
}
private void setBookCardView(String tText, String aText){
titleTextView.setText(tText);
authorTextView.setText(aText);
}
#Override
public void onClick(View v) {
String title = titleTextView.getText().toString();
String author = authorTextView.getText().toString();
//I NEED TO PASS THIS STRINGS TO NEW FRAGMENT
}
}
How can a start a new fragment activity which can access these two strings - title and author
In the onClick method of the view holder class
Bundle bundle = new Bundle();
bundle.putString("key", "value");
bundle.putString("key", "value");
SecondFragment secondFragment = new SecondFragment();
secondFragment.setArguments(bundle);
AppCompatActivity activity = (AppCompatActivity) v.getContext();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, secondFragment).addToBackStack(null).commit();
After this you can start to retrieve the data in the fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment, container, false);
String strtext=getArguments().getString("string1"); //fetching value by key
String strtext1=getArguments().getString("string2");
}
Use Bundle to pass data adapter to fragment in your click Listener
Fragment fragment = new FragmentName();
FragmentManager fragmentManager = context.getSupportFragmentManager(); // this is basically context of the class
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Bundle bundle=new Bundle();
bundle.putString("string1", "your string");
bundle.putString("string2", "your string"); //key and value
//set Fragmentclass Arguments
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
and retrieve data in fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment, container, false);
String strtext=getArguments().getString("string1"); //fetching value by key
String strtext1=getArguments().getString("string2");
}
In the view holder class onClick:
Bundle bundle = new Bundle();
bundle.putString("key", "value");
bundle.putString("key", "value");
SecondFragment secondFragment = new SecondFragment();
secondFragment.setArguments(bundle);
AppCompatActivity activity = (AppCompatActivity) v.getContext();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, secondFragment).addToBackStack(null).commit();
In the recieving fragment
View view = inflater.inflate(R.layout.fragment_book, container, false);
Bundle bundle = this.getArguments();
if(bundle != null){
Snackbar.make(view, bundle.get("key").toString(), Snackbar.LENGTH_LONG).show();
}
So what i want to do is that from first.java Fragment pass the EditText data and ImageView to two.java. I manage to replace first.java with two.java when i click the button (transaction.replace(R.id.top,Two);). I am familiar with Intent but i am not sure how to pass EditText and Imageview in Fragments. Please refer to the screenshot.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager manager=getSupportFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
first first=new first();
transaction.add(R.id.top,first);
transaction.commit();
}
}
first.java
public class first extends Fragment implements View.OnClickListener{
Button get_button;
EditText get_input_name;
ImageView get_image;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first,container,false);
get_input_name=(EditText)rootView.findViewById(R.id.input_name);
get_button=(Button)rootView.findViewById(R.id.submit);
get_image=(ImageView)rootView.findViewById(R.id.img1);
get_button.setOnClickListener(this);
return rootView;
}
public void onClick(View v){
FragmentManager manager=getFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
two Two=new two();
transaction.replace(R.id.top,Two);
transaction.commit();
}
}
two.java
public class two extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_two, container, false);
}
}
Anyone can help? thx
Put both values in Bundle.
Bundle bundle = new Bundle();
bundle.putString("edtValue", <EditText value>);
bundle.putString("image", <Image path/url>);
Pass Bundle in Fragment
Two.setArguments(bundle);
Fetch these value in second fragment
Bundle bundle = getArguments();
String edtValue = bundle.getString("edtValue");
Tip : You should use camel case while declaring class name, check Java Coding Style Guidelines or Google Java Style Guide
You cannot share data between two fragments if they are on different activities but you can declare a variable in activity and get the result in any of the two fragments.
If both fragment are on same activity you can use Bundle , putExtra method for sharing data.
Further read Link
RRR answer is right.
You can do this by using constructor too.
in second activity make on constructor with values you want to get.
String text;
String imagepath;
// or int imageid;
public Two(String text, String imagepath /* or int imageid*/) {
super();
this.text = text;
this.imagepath = imagepath;
//or
this.imageid = imageid;
}
and from first fragment do like this.
FragmentManager manager=getFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
two Two=new two(get_input_name.getText().toString.Trim(),imagepath /*or R.drawable.Imageid*/);
transaction.replace(R.id.top,Two);
transaction.commit();
FragmentManager manager=getFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
Bundle args = new Bundle();
args.putInt("your_data",value);
two Two=new two();
two.setArguments(args);
transaction.replace(R.id.top,Two);
transaction.commit();
in two.java
Get these value and set in fragment
public class two extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Bundle b = getArguments();
String s = b.getInt("your_data");
// Do Whatever you want
return inflater.inflate(R.layout.fragment_two, container, false);
}
}
This question already has answers here:
Passing data from one fragment to another
(4 answers)
Closed 6 years ago.
Hello i am working with fragment to pass data from one fragment to another with My Model object like Student with (id,name),but i cant able to pass and view data in second fragment from pass first fragment.
use static variable
if you use view pager then update fragment when a fragment is change
In Fragment transaction send data in constructor when when a fragment is replace
You can pass data from one fragment to other using constructor or using setArgument
Using Constructor
ModelStudent student = new ModelStudent(1, "ABCD");
FragmentTwo fragmentTwo = new FragmentTwo(student);
Using setArgument
FragmentTwo fragmentTwo = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putSerializable("STUDENT", student);
fragmentTwo.setArguments(bundle);
Fragment 1
public class FragmentOne extends Fragment {
private View rootView;
private Button btnPassData;
public FragmentOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.frgament_one, container, false);
btnPassData = (Button) rootView.findViewById(R.id.btnPassData);
btnPassData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ModelStudent student = new ModelStudent(1, "ABCD");
// first way
//FragmentTwo fragmentTwo = new FragmentTwo(student);
// or second way
FragmentTwo fragmentTwo = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putSerializable("STUDENT", student);
fragmentTwo.setArguments(bundle);
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content, fragmentTwo).commit();
}
});
return rootView;
}
}
Fragment 2
public class FragmentTwo extends Fragment {
private View rootView;
private ModelStudent modelStudent;
private TextView txtStudent;
public FragmentTwo() {
}
public FragmentTwo(ModelStudent modelStudent) {
this.modelStudent = modelStudent;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.frgament_two, container, false);
txtStudent = (TextView) rootView.findViewById(R.id.txtStudent);
Bundle bundle = getArguments();
ModelStudent student = (ModelStudent) bundle.getSerializable("STUDENT");
txtStudent.setText("RollNo: " + student.getRollNo() + " Name: " + student.getName());
return rootView;
}
My Fragment
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
return view;
}
public void sendItem(String item) {
btn.setText(item);
}
}
And in my activity
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
// Load fragment with data
CustomFrag frag = (CustomFrag) getSupportFragmentManager().findFragmentByTag("custFrag");
frag.sendItem(data);
}
I'm getting a nullpointer exception any time I attempt to use the views of my fragment. If I try to load the view inside the method as well, it will not work
i.e. inside sendItem()
btn = (Button)getView().findViewById(R.id.button1);
My layout (button_fragment) contains the button:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Because you have executed the transaction does not mean that the fragment has actually created its view. Which is why btn is still null.
To pass data from the activity to the fragment, use the argument bundle:
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
Then, in onCreateView:
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments().getString("item"));
See this Best practice for instantiating a new Android Fragment question and the first answer.
The problem here is that the fragment's layout is not drawn yet when sendItem(...) is called. Which means btn is null at that point. Instead, this is how you're supposed to do it (see http://developer.android.com/guide/components/fragments.html):
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments.getString("item"));
return view;
}
}
And
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
}
Edit:
njzk2 was faster, but I hope the details I gave will help you further. In any case, the link he gave explains nicely why you should do it like that.