How to call Fragment method from parent activity/Fragment2? [closed] - android

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I simply want to call a method declared in fragment through parent activity and it gives me the error " Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference"` Please suggest something.
Fragment Method:
public void loadSpinnerData() {
Toast.makeText(mActivity, "HELLO", Toast.LENGTH_SHORT).show();
}
Calling method from parent actvity:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new NoticeBoard();
break;
case 1:
fragment = new Quotes();
if (fragment instanceof Quotes)
((Quotes) fragment).loadSpinnerData();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
my logcat is as follows
Logcat error : java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference 05-25 08:46:59.740: E/AndroidRuntime(6152): at app.redalkemi.edublaze.Quotes.loadSpinnerData(Quotes.java:210)

try changing your code a little bit
public void loadSpinnerData(Context contxt) {
Toast.makeText(contxt, "HELLO", Toast.LENGTH_SHORT).show();
}
in parent activity
if (fragment instanceof Quotes)
((Quotes) fragment).loadSpinnerData(youractivityname.this);

Related

Unable to get Fragment Manager from RecyclerView.Adapter

I'm attempting to transit out of a recycler view into a target fragment, but it seems like I can't get the fragment manager to do so. When I try to build, I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentManager android.support.v7.app.AppCompatActivity.getSupportFragmentManager()' on a null object reference
The code below is what's causing the error, specifically the line with getSupportManager().
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
final Course course = courses.get(i);
if (course != null)
{
viewHolder.course = course;
viewHolder.tvLine1.setText(course.getName());
viewHolder.tvLine2.setText(course.getCourse_code());
viewHolder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();
CourseViewFragment viewFragment = new CourseViewFragment();
Bundle args = new Bundle();
args.putString("CourseID", course.getId());
args.putString("CourseName", course.getName());
args.putString("CourseCode", course.getCourse_code());
args.putString("StartAt", course.getStart_at());
args.putString("EndAt", course.getEnd_at());
viewFragment.setArguments(args);
fm.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.add(android.R.id.content, viewFragment)
.addToBackStack(null)
.commit();
}
});
}
}
The problem is not in your adapter. It seems that the context is null when you click the item.
Normally it is caused by destroyed Activities. Here's one scenario:
The adapter receive the context via constructor or setter, and keep the reference to the activity.
The Activity is destroyed for some reason (user action, low memory, etc.)
The context that the adapter has becomes null
You get NPE.
So please check where you call adapter. Maybe the answer is in there.

Android - Fragment Transition issue

I currently am working on a newsfeed module where i have this issue of fragment transition.
Transition Example :
Newsfeed >a> Profile >b> Detail >c> Profile.
Newsfeed >a> Detail >b> Profile >c> Detail.
Every time i visit a page twice and tries to back again at "a". My app crashed giving nullpointerexception on
getActivity().onBackPressed();
in fragment. Each stack is poped in MainActivity in override onBackPressed. All flows are fine when there are no 2 of the same fragment transition in the backstack.
PopBackStack Example :
getSupportFragmentManager().popBackStack("profile", FragmentManager.POP_BACK_STACK_INCLUSIVE);
Let me know if you need more codes to help.
Any help would be appreciated.
Thank you!
Edit:
Logcat Error :
09-19 02:15:02.399 29778-29778/com.dbs.alive E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dbs.alive, PID: 29778
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference
at com.dbs.alive.ProfileFragment$1.onClick(ProfileFragment.java:171)
at android.view.View.performClick(View.java:5210)
at android.view.View$PerformClick.run(View.java:21328)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5551)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Main Activity (onBackPressed)
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
//this.finish();
super.onBackPressed();
} else {
for (int i = getSupportFragmentManager().getBackStackEntryCount(); i > 0; i--) {
String ide = getSupportFragmentManager().getBackStackEntryAt(i - 1).getName();
if (ide != null) {
//1. FROM NEWSFEED
if (ide.equals("newsfeed")) {
getSupportFragmentManager().popBackStack("newsfeed", FragmentManager.POP_BACK_STACK_INCLUSIVE);
break;
} else if (ide.equals("profile")) {
getSupportFragmentManager().popBackStack("profile", FragmentManager.POP_BACK_STACK_INCLUSIVE);
break;
}
Fragment AddBackStack
Fragment fragment = ProfileFragment.newInstance("", "");
Bundle mBundle = new Bundle();
mBundle.putString("profileid", postOwnerId);
mBundle.putString("profilename", postOwnerName);
mBundle.putString("profileicon", RealmHelper.getUserProfileUrl(postOwnerId));
fragment.setArguments(mBundle);
FragmentTransaction transaction = ((AppCompatActivity) activity).getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.newsfeed_layout, fragment);
transaction.addToBackStack("profile");
transaction.commit();

After specific method other methods won't work

I've been working on an app that displays articles and shows the article's title on the toolbar and if I set the article text and toolbar text by calling the method from the article fragment on the main activity in the fragment's onResume method then it works fine, however as soon as I try doing it after calling a specific method within the fragment it just doesnt work giving me java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
I have tried changing everything and making the refreshDisplay method get called at different times and renaming and changing and completely removing the method input from newClassArticle and no matter what - no matter if I just use static strings, no matter if I don't even change the strings - after newClassArticle is called on the fragment, it will no longer execute the actions within refreshDisplay and will give the above error.
This is the newArticle method in the main activity:
public void newArticle() {
frag_article newArticle = new frag_article();
newArticle.setArguments(getIntent().getExtras());
FragmentManager fragManager = getFragmentManager();
FragmentTransaction transaction = fragManager.beginTransaction();
transaction.replace(R.id.activeFrag, newArticle);
transaction.commit();
newArticle.newArticleClass(articles.get(0));
}
This is the setActionBarTitle method in the main activity:
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
This is the newClassArticle method in the fragment:
public void newClassArticle(class_article newArticleClass){
articleTitle = newArticleClass.title;
articleBody = newArticleClass.body;
refreshDisplay();
}
and this is the refreshDisplay method in the fragment:
public void refreshDisplay(){
activity.setActionBarTitle(articleTitle);
txtBody.setText(articleBody);
}
Any help on this infuriating issue would be welcome

Null pointer exception when calling fragment method

I have been stuck on this for awhile, I am loading a fragment from within an activity (replacing another). It loads fine and I can see it and return to the previous fragment, but when I call a method to load data into it I get a null pointer exception. My first code was this...
public class MainActivity extends Activity implements MainListFragment.MainListListener, StoryFragment.StoryListener {
MainListFragment mainListFragment;
StoryFragment storyFragment;
.
.
.
public void onMainListClick(DBRecordType recordType, int recordID){
switch(recordType){
case story:{
DBHandler dbHandler = new DBHandler(this, null, null, 1);
Story story = dbHandler.getStory(recordID);
Toast.makeText(getApplicationContext(), story.toString(), Toast.LENGTH_SHORT ).show();
storyFragment = new StoryFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, storyFragment);
transaction.addToBackStack(null);
transaction.commit();
storyFragment.loadStory(story);
break;
}
I am getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
at com.maniblett.listtest.StoryFragment.loadStory(StoryFragment.java:60)
at com.maniblett.listtest.MainActivity.onMainListClick(MainActivity.java:104)
The method in the fragment is setting text in an edittext, here's the fragment method I am calling mName and mSummary are references to edit text widgets :
public void loadStory(Story story){
mName.setText(story.get_name());
mSummary.setText(story.get_summary());
}
Is it legal to refer to a fragment like this (calling a method on the same reference I used to add the fragment via the fragment manager)? It seems like I already have a reference to the fragment, so using find fragment by ID would be redundant but when I double checked everything I read seemed to indicate I needed to find the fragment using findFragmentByID or Tag first so changed my code to this...
storyFragment = new StoryFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, storyFragment, "loadedFragment");
transaction.addToBackStack(null);
transaction.commit();
StoryFragment loadedFragment = (StoryFragment)getFragmentManager().findFragmentByTag("loadedFragment");
loadedFragment.loadStory(story);
break;
But I get a similar error, which is:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.maniblett.listtest.StoryFragment.loadStory(com.maniblett.listtest.datamodel.Story)' on a null object reference
at com.maniblett.listtest.MainActivity.onMainListClick(MainActivity.java:107)
at com.maniblett.listtest.MainListFragment.onListItemClick(MainListFragment.java:156)
at android.app.ListFragment$2.onItemClick(ListFragment.java:160)
at android.widget.AdapterView.performItemClick(AdapterView.java:300)
I have verified the object I am sending is not null after creating it (the 'story' in the case statement is an enum). Again, the frgament loads and runs fine if I comment out the method call, it is just when I call the emthod on it it fails. so, I guess I don't have the actual fragment that is loaded? Can someone tell me what I'm doing wrong? (I did search many other similar topics but couldn't find anything which helped, I'm pretty new to android). Thanks to any who take the time to help!
StoryFragment class:
public class StoryFragment extends Fragment
{
StoryListener activityCallback;
private EditText mName;
private EditText mSummary;
public interface StoryListener {
public void onAddButtonClick(String text);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_story, container, false);
Button button = (Button)rootView.findViewById(R.id.button);
mName = (EditText)rootView.findViewById(R.id.name);
mSummary = (EditText)rootView.findViewById(R.id.summary);
button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
DBHandler dbHandler = new DBHandler(getActivity().getBaseContext(), null, null, 1);
Story story = new Story(mName.getText().toString(),mSummary.getText().toString());
dbHandler.addStory(story);
activityCallback.onAddButtonClick("Story"); //use same callback for all record types passing back record type created?
}
} );
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try { activityCallback = (StoryListener) activity;
}
catch (ClassCastException e) {
throw new ClassCastException(activity.toString()+ " must implement StoryListener");
}
}
public void loadStory(Story story){
mName.setText(story.get_name());
mSummary.setText(story.get_summary());
}
}
Well, you should understand how android works in the first place. The onCreateView method gets called only when the fragment is going to come visible. So when you call loadstory immediately after the FragmentTransaction method its obvious you'll get an NullPointer Exception
My solution:
Declare two variables in the StoryFragment as name and summary
Change the loadStory method is like this
public void loadStory(Story story){
this.name = story.get_name();
this.summary = story.get_summary();
}
Finally in the OnCreateView method of StoryFragment after change here appropriately
mName = (EditText)rootView.findViewById(R.id.name);
mSummary = (EditText)rootView.findViewById(R.id.summary);
//if your fragment is also gonna be called by some other manner you should check for null in this.name and this.summary before setting it to the `TextView`
mName.setText(this.name);
mSummary.setText(this.summary);
Thank you. That worked perfectly. Actually, what I did was create a private Story type and then in StoryFragment.loadStory I assigned it.
public void loadStory(Story story){
mStory = story;
}
I also was able to then see that it works fine to not have to search for the fragment using findFragmentByID, this part worked:
storyFragment = new StoryFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, storyFragment);
transaction.addToBackStack(null);
transaction.commit();
storyFragment.loadStory(story);
Thanks very much for pointing me in the right direction here

Transferring data from 1 fragment to another fragment

Currently trying to use a bundle to transfer information from both my IncomeFragment and ExpenseFragment to HomeFragment but I'm unsure as to how to do it. I've tried implementing doubleA's code which he provided.
This is my onAcceptClicked method from my MainActivity which takes the value of the total income/expense from the relevant fragment and transfers it to the HomeFragment:
public void onAcceptClicked(String fragment, String total) {
final FragmentManager fm = getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
if (fragment == "income") {
HomeFragment homeFrag = new HomeFragment();
Bundle incomeBundle = new Bundle();
incomeBundle.putString(IncomeFragment.TAG, total);
//homeFrag.newInstance(total);
ft.replace(R.id.content_layout, homeFrag, HomeFragment.TAG);
ft.commit();
}
else if (fragment == "expense"){
HomeFragment homeFragment = new HomeFragment();
Bundle expenseBundle = new Bundle();
expenseBundle.putString("bundleIncome", total);
homeFragment.setArguments(expenseBundle);
ft.replace(R.id.content_layout, homeFragment, HomeFragment.TAG);
ft.commit();
}
}
I have an interface in my IncomeFragment which I use to communicate with my MainActivity so I can use the onAcceptClicked method to transfer my totals over. I plan on basically doing the same thing with my ExpenseFragment. The code below is a snippet from my IncomeFragment:
public interface SendIncomeData {
public void onAcceptClicked(String fragment, String total);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_accept:
//Toast.makeText(getActivity(), stringIncomeTotal, Toast.LENGTH_LONG).show();
sendIncomeData.onAcceptClicked("income", stringIncomeTotal);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Unfortunately I'm getting an error with this line of code
sendIncomeData.onAcceptClicked("income", stringIncomeTotal);
This is the error
java.lang.NullPointerException: Attempt to invoke interface method 'void mos.myapplication.IncomeFragment$SendIncomeData.onAcceptClicked(java.lang.String, java.lang.String)' on a null object reference
I don't know why it's saying there's a null object reference and/or how I could fix this error.
I'm guessing there's probably going to be an error displaying my totals in my HomeFragment because I haven't called the method below anywhere within my code in my MainActivity or my IncomeFragment / ExpenseFragment. The reason I haven't used it is because I wasn't sure how to get it so that the HomeFragment opens first when the application is launched.
static HomeFragment newInstance(String total)
{
HomeFragment frag = new HomeFragment();
Bundle args = new Bundle();
args.putString(TAG, total);
frag.setArguments(args);
return frag;
}
I don't even mind starting from scratch, as long as I can transfer totals and display them from IncomeFragment > HomeFragment and also ExpenseFragment > HomeFragment
You need to check if bundle is null in the first place:
bundle = this.getArguments();
if (bundle != null)
{
// continue with your logic
}
Also, all Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly. See below links for more info:
http://developer.android.com/training/basics/fragments/communicating.html
http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
A lot of people will argue that using interfaces is the best way to do that, which isn't really wrong but there are much simpler ways. Edit: not necessarily simpler
-One way is to get a reference to the activity within the fragment by calling
this.getActivity();
then in your activity class you can have a method that passes the data to the other fragment since it has a reference to both fragments.
-Then there's an even better way to do it actually (though that first part is probably helpful too):
In the fragment that has the data that needs to be moved, you can get a reference to the other fragment from the FragmentManager. This assumes that you created that fragment with a string ID like so:
Fragment otherFragment;
getSupportFragmentManager().beginTransaction().add(otherFragment, "otherFrag").commit();
Then in the fragment with the data, you'll do:
FragmentActivity fragmentActivity = (FragmentActivity)getActivity();
OtherFragment otherFragment = (OtherFragment)fragmentActivity.getSupportFragmentManager().findFragmentByTag("otherFrag");
Then with a reference to OtherFragment (in this case), you can do something like:
otherFragment.dataString = "myData";
But you'll probably want to have a test to make sure the other fragment doesn't come back null, and if it is null you might just want to create it then and there since you already have a reference to the FragmentManager.
Edit: I'm just going to say that I like this method more, subjectively.

Categories

Resources