i'm trying to send data from activity to fragment
here is the activity code :
Bundle args=new Bundle();
args.putString("username", username);
ViewEmpAttend fragobj=new ViewEmpAttend();
fragobj.setArguments(args);
here is the fragment code :
username=this.getArguments().getString("username");
but this code gives me an error said "null object reference" in the onCreateView method in (Fragment Class) .
please help :)
Try to retrieve arguments from onCreate of Fragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String username = this.getArguments().getString("username");
}
In activity define one method.
public class MainActivity extends AppCompatActivity {
String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//your code
}
//define this method
public String getName(){
this.name = username;
}}
In fragment use following code.
String userName = ((activityName) getActivity()).getName();//you will get name here.
For something simple like that, i will just create a constructor method in the fragment to pass in a string.
for example
public class MyFragment extends Fragment{
private String myString;
public MyFragment (){
// Recommended Empty Constructor
}
public MyFragment (String yourString){
this.myString = yourString;
}
}
On your Activity class you can pass in the string direct to your fragment constructor
public MyClass extends Activity{
#override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
openFragment();
}
public void openFragment(){
MyFragment fragment = new Fragment("yourString");
// Here begin the fragment transaction
}
}
Related
I have an app which has one MainActivity and two Fragments. These fragments send argument to MainActivity this way:
Bundle args = new Bundle();
args.putLong("id",id);
sf.setArguments(args);
And then MainActivity takes argument in onCreate() method
protected void onCreate(Bundle savedInstanceState) {
private long wayId = getArguments().getLong("id");
}
How can I determine which fragment sent this argument to MainActivity ?
You can add another argument into the bundle like the tag of the fragment.
Bundle args = new Bundle();
args.putLong("id",id);
args.putString("fragmentTag", fragmentTag);
sf.setArguments(args);
and retrive the tag in your onCreate()
You can define a separate inrterface for every fragment
public class FragmentA extends Fragment {
public static interface FragmentAInterface {
void doSomething(String data);
}
}
public class FragmentB extends Fragment {
public static interface FragmentBInterface {
void doSomething(String data);
}
}
And then in your activity:
public class MyActivity extends AppCompatActivity implements FragmentA.FragmentAInterface, FragmentB.FragmentBInterface{
#Override
public void doSomething(String data) {
//Guaranteed to come from Fragment A
}
#Override
public void doOtherThing(String data) {
//Guaranteed to come from Fragment B
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to pass data from an activity to a fragment, using an interface.
Please have a look at the code snippets below:
Interface:
public interface FragmentCommunicator {
public void passData(String name);
}
MainActivity:
public class MainActivity extends AppCompatActivity{
FragmentCommunicator fragmentCommunicator;
private Fragment fragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fragment= new Fragment();
fragmentCommunicator = (FragmentCommunicator) getApplication();
fragmentCommunicator.passData("hello");
getSupportFragmentManager().beginTransaction().replace(R.id.container ,fragment).commit();
}
});
}
}
Fragment:
public class Fragment extends android.support.v4.app.Fragment implements FragmentCommunicator {
FragmentCommunicator communicator;
Context c;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, null);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.c = context;
}
#Override
public void passData(String name) {
Toast.makeText(c, name, Toast.LENGTH_SHORT).show();
}
}
I just want to pass some string when I click on button, (or some other event) to launch a fragment, and when the fragment is launched, it should show a toast containing that string...
Please help
any help would be appreciated.
Write this line of code after onCreate method.
public void passVal(FragmentCommunicator fragmentCommunicator) {
this.fragmentCommunicator = fragmentCommunicator;
}
Something like this
public class MainActivity extends AppCompatActivity{
FragmentCommunicator fragmentCommunicator;
private Fragment fragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button);
fragment= new Fragment();
//App is crasing for this line. Working fine by removing it
//fragmentCommunicator = (FragmentCommunicator) getApplication();
//fragmentCommunicator.passData("hello");
getSupportFragmentManager().beginTransaction().replace(R.id.container ,fragment).commit();
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fragmentCommunicator.passData("Hello");
}
});
}
//Here is new method
public void passVal(FragmentCommunicator fragmentCommunicator) {
this.fragmentCommunicator = fragmentCommunicator;
}
}
Then write this line of code into onCreateView() of your fragment. Something like this
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, null);
((MainActivity) getActivity()).passVal(new FragmentCommunicator() {
#Override
public void passData(String name) {
Toast.makeText(c, name, Toast.LENGTH_SHORT).show();
}
});
return view;
}
Note: no need to implement FragmentCommunicator interface in your fragment. Hope it works. It works for me. I have tested
Activities contain fragments, you shouldn't need to pass anything. One technique would be to store your data in the activity scope and get a reference to it with getActivity().
Best practice to reference the parent activity of a fragment?
As far as the code you posted, I don't see where you call your pass data method within the fragment. I would suggest calling it in onviewcreated().
I will attempt to provide some sample code later as doing this on my mobile device is proving difficult.
Try passdata (getActivity ().someStringVariable);
In your Fragment class, have a TAG field. Naming a fragment Fragment can be a bit confusing as it is the same name as an Android Fragment, so I will use ExampleFragment:
public class ExampleFragment extends android.support.v4.app.Fragment implements FragmentCommunicator {
public static final String TAG = "ExampleFragment";
// ...
}
Now, when you replace the fragment in the activity, make sure to pass the TAG:
getSupportFragmentManager().beginTransaction().replace(R.id.container ,fragment, ExampleFragment.TAG).commit();
Note that in your case it would be Fragment.TAG, but I used ExampleFragment to clarify that Fragment.TAG is not part of the Android SDK.
To get a reference of your fragment in your activity, use the FragmentManager to find your fragment:
Fragment myFragment = getSupportFragmentManager().findFragmentByTag(ExampleFragment.TAG);
You can then make sure that myFragment is not null and cast it to FragmentCommunicator:
if (myFragment != null) {
fragmentCommunicator = (FragmentCommunicator) myFragment;
}
Note that in your example fragmentCommunicator = (FragmentCommunicator) getApplication(); is invalid because it is your fragment that is implementing the interface, not your application.
I have a fragment hosted by a ViewPager
public class FragmentOne extends Fragment {
DatabaseHelper db;
String TAG = "FragmentOne";
DisplayActivity displayActivity;
....
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
displayActivity = new DisplayActivity();
initView();
}
Button delete = (Button) getActivity().findViewById(R.id.dont);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
displayActivity.removeCurrentFragment(count-1);
}
});
My goal is to remove this current fragment from the ViewPager. However, through the debugger I found that displayActivity is null.
How do I get a reference of displayActivity?
public class DisplayActivity extends FragmentActivity {
ViewPager viewPager;
PagerAdapter pagerAdapter;
String TAG = "DisplayActivity";
public void removeCurrentFragment(int position){
pagerAdapter.fragmentArrayList.remove(position);
pagerAdapter.notifyChangeInPosition(1);
pagerAdapter.notifyDataSetChanged();
Log.e(TAG, "in removeCurrentFragment");
}
I tried using displayActivity = new DisplayActivity();
But doesn't seem to work.
This is the error
NullPointerException: Attempt to invoke virtual method 'void .DisplayActivity.removeCurrentFragment(int)' on a null object reference
Use getActivity() with a cast to DisplayActivity.
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
displayActivity = (DisplayActivity) getActivity();
initView();
}
I have an Activity that starts a Fragment. Inside that fragment i have an EditText. And when i get the text that the user types there, i want to get that from my Activity with the help of an interface. I'm using this guide
On my MainActivity i'm implementing the commentListener interface and i've managed to get the result inside the onCommentEntered method. But on doneListener, which is triggered when the user presses a button finishing the activity, i'm getting null.
Obviously onCommentEntered runs after doneListener.
Any suggestions on how to get the result on doneListener?
class MainActivity implements fragment.commentListener{
static String comment;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addtransaction);
done=(TextView)findViewById(R.id.done_button);
}
// called when user presses a button and MainActivity finishes.
public void doneListener(View v){
// Here i get NULL
System.out.println(comment);
finish();
}
#Override
public void onCommentEntered(String data) {
comment=data;
// Here i get what the user typed
System.out.println(comment);
}
}
My fragment
public class thefragment extends Fragment {
commentListener cListener;
static TextView note;
EditText comment;
public interface commentListener{
void onCommentEntered(String data);
}
public static thefragment newInstance(){
return new thefragment ();
}
public thefragment (){
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
cListener=(commentListener) context;
}
#Override
public void onDetach() {
super.onDetach();
cListener=null;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v;
v=inflater.inflate(R.layout.fragment, container, false);
comment=(EditText)v.findViewById(R.id.comment_picker);
comment.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
cListener.onCommentEntered(comment.getText().toString());
}
}
});
return v;
}
}
Create a new Interface, as well as implement the same in Fragment. create a method in the interface and override the same in Fragments. While calling the fragment from Activity create an Interface type fragment and call the interface method.
eg:
public class thefragment extends Fragment implement fragmentNofyInterface {
...
#Override
protected void notify(String txt){
mTvTxt.setText(txt);
}
.....
}
Interface Format
public interface fragmentNofyInterface {
protected void notify(String txt);
}
Activity format
class MainActivity implements fragment.commentListener{
.....
private fragmentNofyInterface mFragmentNotifier;
.........
thefragment mFragment = new thefragment();
mFragmentNotifier = (fragmentNofyInterface ) mFragment;
FragmentTransaction transaction = mFragmentMngr.beginTransaction().
add(R.id.rl_fragment_navigation_container,
mFragment);
transaction .commit();
......
//Notify the fragment when you required
mFragmentNotifier.notify("hello world");
}
Switching to addTextChangedListener and TextWatcher for my EditText, like this here,
seems to fix my problem.Now onCommentEntered method is called before doneListener and thus String commentgets whatever was typed in the EditText.Thanks everyone for helping.
I have a main activity class, and a private inner class within the main activity. The private inner class has methods that when called will display fragments. This inner class implements an interface defined in the Fragment's class, to be used as a sort of callback. It is probably easiest to show through code.
public class MainActivity extends FragmentActivity {
//on a button clicked
EditItemManger em = new EditItemManager();
em.begin();
private class EditItemManager implements on EditItemFragment.EditedItemClickedListener{
//consructor, other stuff. no onCreate method because this inner class does not (explicity??) extend activty
public void begin(){
EditItemFragment editItemFrag = new EditItemFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(editItemFrag, EDIT_FRAG_TAG)
fragmentTransaction.commit();
}
#Override
public void onEditItemClicked() {
editFinish();
}
public void editFinish()
{
// other stuff
}
}
}
My EditItemFragment class, where the onAttach method always has a null activity parameter
public class EditItemFragment extends DialogFragment {
protected EditedItemClickedListener editedItemClickedListener;
protected ImageButton button;
public EditItemFragment(){}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_name_fragment, container, false);
button = (ImageButton) view.findViewById(R.id.submit_new_item_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
editedItemClickedListener.onEditedItemButtonClicked();
}
});
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
editedItemClickedListener= (EditedItemClickedListener) activity;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
public interface OnEditNameButtonClickedListener {
public void onEditNameButtonClicked();
}
So because the parameter in onAttach() in my Fragment class is always null, it eventually causes a null pointer exception. I am wondering if it is because the fragment is called from a class that is not extending activity. The problem is that if this class extends activity, there will be an issue with trying to commit the Fragment Transaction
I guest your onAttach returns nullpointer exception. Its because your parent Activity the main activity doesnt implement your custom interface so it return null. See the code below let me know if it help you:
public class MainActivity extends FragmentActivity implements EditItemFragment.EditedItemClickedListener{
private DialogFragment editItemDialog;
//Do your code here
#Override
public void onEditItemClicked() {
editFinish();
}
public void showDialog(){
//this is for showing your custom dialog fragment
editItemDialog = EditItemFragment.newInstance();
editItemDialog.show(getSupportFragmentManager(),"editItemDialog");
}
}
this is for your EditItemFragment:
public class EditItemFragment extends DialogFragment{
//Do your code here
public static EditItemFragment newInstance(){
EditItemFragment editItemDialog = new EditItemFragment();
return editItemDialog;
}
}