Starting a new Activity causes the app to restart - java

I've created a button which will open a new activity, but when I start the app and click on the button, the application just immediately restarts without any logcat errors. Here is my code:
public class amumu extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.amumu, container, false);
}
public void OnClickAmumuRunes(View view){
Intent GoToRunes = new Intent(view.getContext(), amumurunes.class);
startActivity(GoToRunes);
}
public void OnClickAmumuBuild(View view){
Intent GoToRunes = new Intent(view.getContext(), amumubuild.class);
startActivity(GoToRunes);
}
This is the code which I want to open, but I can't:
public class amumubuild extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.amumubuild, container, false);
}
}
and this is a fragmentclass where is tablayout in which first class is
public class FragmentClass extends AppCompatActivity {
private ViewPager viewPager;
private TabLayout tabLayout;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragments);
initViews();
setuppager();
}
private void initViews(){
viewPager = findViewById(R.id.ViewPager);
tabLayout = findViewById(R.id.tab);
}
private void setuppager(){
PagerAdapter pagerAdapter = new SlideAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
public void OnClickDisplayToastAmumu(View view) {
Toast.makeText(this,"Amumu",Toast.LENGTH_SHORT).show();
}
public void OnClickDisplayToastLee(View view) {
Toast.makeText(this,"Lee Sin",Toast.LENGTH_SHORT).show();
}
public void OnClickDisplayToastPantheon(View view) {
Toast.makeText(this,"Pantheon",Toast.LENGTH_SHORT).show();
}
public void OnClickDisplayToastNami(View view) {
Toast.makeText(this,"Nami",Toast.LENGTH_SHORT).show();
}

You are using startActivity() to navigate to a Fragment. This doesn't work. You can only specify Activity classes in an Intent.
Additionally, make sure that you register each Activity in the AndroidManifext.xml file like this:
<application>
...
<activity android:name="com.example.SecondActivity">
</application>
Check out this post to see how to navigate between multiple Fragments in one Activity: How to start Fragment from an Activity

You can not start fragment by startActivity function so you need this:
private void loadFragment(final Fragment fragment) {
// load fragment
try {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.commit();
currentFragment = fragment;
} catch (Exception e) {
Log.d("mal", e.toString());
}
}

Related

Saving State In Fragment With ViewPager Android Studio

Need a little help on how to approach saving state in my single activity application. I looked at a few resources but couldn't quite find one that fits the build. Essentially I have single activity with a Fragment container view that I'm using to swap out fragments as needed. My issue is that as my activity is destroyed when a lifecycle event occurs, the fragment with my view pager is restored but the individual fragments on the tabs are not loaded. I cannot figure out how to save the state properly. Below is my code:
Activity:
public class StartActivity extends AppCompatActivity {
FirebaseAuth mAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
mAuth = FirebaseAuth.getInstance();
if (savedInstanceState == null) {
LoginFragment fragment = new LoginFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.frameLayout, fragment)
.commit();
}
}
#Override
public void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
if(currentUser != null){
MainActivity mainActivityFrag = new MainActivity();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.frameLayout, mainActivityFrag)
.commit();
}
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState, #NonNull PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
#Override
protected void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
}
Fragment With View Pager:
public class MainActivity extends Fragment {
private FirebaseAuth mAuth;
private SectionsPagerAdapter sectionsPagerAdapter;
private ViewPager viewPager;
private TabLayout tabs;
private Toolbar toolbar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAuth = mAuth = FirebaseAuth.getInstance();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
sectionsPagerAdapter = new SectionsPagerAdapter(getContext(),((AppCompatActivity)getActivity()).getSupportFragmentManager());
viewPager = view.findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
tabs = view.findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
tabs.showContextMenu();
toolbar = view.findViewById(R.id.topAppBar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
setHasOptionsMenu(true);
tabs.getTabAt(0).setIcon(R.drawable.home_selector);
tabs.getTabAt(1).setIcon(R.drawable.destination);
tabs.getTabAt(2).setIcon(R.drawable.mail_outline_blk);
tabs.getTabAt(3).setIcon(R.drawable.notification_bell);
return view;
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.main_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.logout:
mAuth.signOut();
//navigate to home fragment
LoginFragment fragment = new LoginFragment();
((AppCompatActivity)getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frameLayout, fragment)
.commit();
return true;
default:
return false;
}
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
}
}
Adapter Code:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3, R.string.tab_text_4};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
mContext = context;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position){
case 0:
PostFragment postFragment = new PostFragment();
return postFragment;
case 1:
TestFragment userFeedFragmentt = new TestFragment();
return userFeedFragmentt;
default:
TestFragment userFeedFragmenttt = new TestFragment();
return userFeedFragmenttt;
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 2 total pages.
return 4;
}
}

Null object reference when passing variable from activity to fragment

I am getting a null object reference when passing a variable from an activity to a fragment and I can't find out what the problem is. The variable I am trying to pass is currentPollName. Any help would be appreciated.
Here is the GroupActivity:
public class GroupActivity extends AppCompatActivity {
private ViewPager myViewPager;
private TabLayout myTabLayout;
private GroupTabsAccessorAdapter myTabsAccessorAdapter;
private String currentPollName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group);
currentPollName = getIntent().getExtras().get("pollName").toString();
Toast.makeText(GroupActivity.this, currentPollName, Toast.LENGTH_SHORT).show();
Bundle bundle = new Bundle();
bundle.putString("pollName", currentPollName);
PollFragment fragInfo = new PollFragment();
fragInfo.setArguments(bundle);
Toolbar toolbar = (Toolbar) findViewById(R.id.group_page_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(currentPollName);
myViewPager = (ViewPager) findViewById(R.id.group_tabs_pager);
myTabsAccessorAdapter = new GroupTabsAccessorAdapter(getSupportFragmentManager());
myViewPager.setAdapter(myTabsAccessorAdapter);
myTabLayout = (TabLayout) findViewById(R.id.group_tabs);
myTabLayout.setupWithViewPager(myViewPager);
}
public String getGroupName() {
return currentPollName;
}
}
Here is the PollFragment OnCreateView
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
pollView = inflater.inflate(R.layout.fragment_poll, container, false);
currentPollName = getArguments().getString("pollName");
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
UsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
GroupNameRef = FirebaseDatabase.getInstance().getReference().child("Groups").child(currentPollName);
InitializeFields();
RetrieveDisplayPollOptions();
newOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RequestNewPollOption();
}
});
submitOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SavePollOption();
}
});
return pollView;
}
Here is the Itent that starts the GroupActivity
list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String currentPollName = list_view.getItemAtPosition(position).toString();
Intent pollIntent = new Intent(getContext(), GroupActivity.class);
pollIntent.putExtra("pollName", currentPollName);
startActivity(pollIntent);
}
});
I found the following things in the code
fragInfo Fragment is not passed to GroupTabsAccessorAdapter. So
add the fragment to the adapter and then write
myViewPager.setAdapter(myTabsAccessorAdapter);
In PollFragment move currentPollName =
getArguments().getString("pollName"); in onViewCreated as below.
public void onViewCreated(View view, #Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
currentPollName = getArguments().getString("pollName");
}`

How to Access Activity(except mainactivity) from Fragment?

I created my test project where i code to communicate between two fragments but actully I want to access activity from fragment.
Here is code to connect fragment to fragment, its working absolutely right without any error but now i want to change this code to connect activity from fragment instead of fragment to fragment communication.
So Please change this code to access activities from fragment. I stuck on this issue for than a week.So Guys please resolve this.
here is my mainaactivity:
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener {
private FragmentA fragmentA;
private FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
fragmentB = new FragmentB();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container_a, fragmentA)
.replace(R.id.container_b, fragmentB)
.commit();
}
#Override
public void onInputASent(CharSequence input) {
fragmentB.updateEditText(input);
}
#Override
public void onInputBSent(CharSequence input) {
fragmentA.updateEditText(input);
}
Here is my FragmentA.java:
public class FragmentA extends Fragment {
private FragmentAListener listener;
private EditText editText;
private Button buttonOk;
public interface FragmentAListener {
void onInputASent(CharSequence input);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
editText = v.findViewById(R.id.edit_text);
buttonOk = v.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence input = editText.getText();
listener.onInputASent(input);
}
});
return v;
}
public void updateEditText(CharSequence newText) {
editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentAListener) {
listener = (FragmentAListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentAListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Here is my FragmentB.java:
public class FragmentB extends Fragment {
private FragmentBListener listener;
private EditText editText;
private Button buttonOk;
public interface FragmentBListener {
void onInputBSent(CharSequence input);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b, container, false);
editText = v.findViewById(R.id.edit_text);
buttonOk = v.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence input = editText.getText();
listener.onInputBSent(input);
}
});
return v;
}
public void updateEditText(CharSequence newText) {
editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentBListener) {
listener = (FragmentBListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentBListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Here is my Fertilizers.java file which i want to access from FragmentA.:
public class Fertilizers extends AppCompatActivity {
RecyclerView mRecyclerView;
List<FertilizerData> myFertilizersList;
FertilizerData mFertilizersData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fertilizers);
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
GridLayoutManager gridLayoutManager;
gridLayoutManager = new GridLayoutManager(Fertilizers.this, 1);
mRecyclerView.setLayoutManager(gridLayoutManager);
myFertilizersList = new ArrayList<>();
mFertilizersData = new FertilizerData("Urea Fertilizer","Urea is a concent","Rs.1900",R.drawable.urea);
myFertilizersList.add(mFertilizersData);
myFertilizersList.add(mFertilizersData); }
}
please write here a block of code to call Fertilzers Activity from FragmentA, I,ll be very thankful to you.
Calling getActivity() in your fragment gives you the calling activity so if MainActivity started your fragment then you would do
(MainActivity(getActivity())).something_from_your_main_activity
Solution found by itself regarding this issue.
FragmentHome.java class should look like this:
public class FragmentHome extends Fragment {
private Button button;
public FragmentHome(){
}
public interface OnMessageReadListener
{
public void onMessageRead(String message);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
button = (Button)v.findViewById(R.id.bn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), Fertilizers.class);
intent.putExtra("some"," some data");
startActivity(intent);
}
});
return v;
}
}
FertilizersActivity.java should look like this:
public class Fertilizers extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fertilizers);
Bundle bundle = getIntent().getExtras();
if (bundle != null){
if(bundle.getStringArrayList("some") !=null){
Toast.makeText(getApplicationContext(),"data:" + bundle.getStringArrayList("some"),Toast.LENGTH_LONG).show();
}
}
}
}

How to fix : error: not an enclosing class: Context

I have the error noted in the title: error: not an enclosing class: Context
I already tried in some other forums to solve this problem but they couldn't help, I checked youtube and other questions on stackoverflow but couldn't find an answer to this problem.
My code looks like this:
public class TermineFragment extends Fragment {
private Button button;
Context c;
#Override
public void onAttach(Context c) {
super.onAttach(c);
Context context = c;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull final LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_3, container, false);
button = view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(Context.this, AnmeldungButton.class));
startActivity(intent);
}
});
return view;
}
}
This produces the error:
error: not an enclosing class: Context
Which comes from the line:
Intent intent = new Intent(getActivity(Context.this,AnmeldungButton.class));
I want that my button in the Fragment AnmeldungButton.java is I mean in the Activity but I hope you understand me ...
You can use getContext() for start activity in fragment
Intent intent = new Intent(getContext(), AnmeldungButton.class);
startActivity(intent);
Use this code
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(),AnmeldungButton.class);
startActivity(intent);
}you a
});
Here is the problem you are using are passing parameter in the wrong way.
Intent(Context packageContext, Class<?> cls)
public class TermineFragment extends Fragment {
Context c;
#Override
public void onAttach(Context c) {
super.onAttach(c);
this.c = c; //this is one of the best way to get context of the activity to which the particular activity is associated with
}
#Nullable
#Override
public View onCreateView(#NonNull final LayoutInflater inflater, #Nullable
ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_3, container, false);
button = view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(c,AnmeldungButton.class);//Pass the context like this.
startActivity(intent);
});
return view;
}
}

Handling Multiple Fragments when orientation changes

I have a MainActivity, and I want to attach a fragment with 3 buttons in it to that activity. On clicking button 1 it should replace this fragment with another fragment. But when I change orientation the current fragment and the old fragment are both getting attached. Can someone help me solve this ?
Following is my MainActivity.java:
public class MainActivity extends AppCompatActivity implements OnButtonsClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.mainactivity, new FragmentHomepage(), "aboutMe")
.commit();
}
#Override
public void button1Action() {
FragmentAboutMe fragmentAboutMe=new FragmentAboutMe();
getSupportFragmentManager().beginTransaction()
.add(R.id.mainactivity,fragmentAboutMe)
.commit();
}
#Override
public void button2Action() {
Intent intent =new Intent(this,ActivityMasterDetail.class);
startActivity(intent);
}
#Override
public void button3Action() {
Intent intent =new Intent(this,ActivityViewPager.class);
startActivity(intent);
}
}
This is my FragmentHomepage.java:
public class FragmentHomepage extends Fragment {
private static final String ARG_SECTION_NUMBER ="section number";
OnButtonsClickListener onButtonsClickListener;
public static FragmentHomepage newInstance(int sectionNumber){
FragmentHomepage fragmentHomepage=new FragmentHomepage();
Bundle args=new Bundle();
args.putInt(ARG_SECTION_NUMBER,sectionNumber);
fragmentHomepage.setArguments(args);
return fragmentHomepage;
}
public FragmentHomepage(){}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
onButtonsClickListener= (OnButtonsClickListener) context;
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Button button1= (Button) getActivity().findViewById(R.id.aboutMe);
final Button button2= (Button) getActivity().findViewById(R.id.task2);
final Button button3= (Button) getActivity().findViewById(R.id.task3);
button1.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
onButtonsClickListener.button1Action();
}
});
button2.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
onButtonsClickListener.button2Action();
}
});
button3.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
onButtonsClickListener.button3Action();
}
});
}
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView=null;
rootView =inflater.inflate(R.layout.fragment_homepage,container,false);
return rootView;
}
}
and my second activity is as follows
(in FragmentAboutMe.java):
public class FragmentAboutMe extends Fragment {
int counters=0;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null)counters=0;
else counters=savedInstanceState.getInt("count");
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("count",13);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_aboutme,container,false);
}
}
In your onCreate() method put a check whether the fragment is already present. Android automatically restores the fragment manager state upon orientation change and hence upon orientation change, the fragment which you added on button click would automatically be added. Thus if you will add new fragment in onCreate() without check, this would result in adding the 2 fragments. This is causing the issue.
FragmentManager fm = getSupportFragmentManager();
if (fm.findfragmentById(R.id.mainactivity) == null) {
FragmentHomepage fragment = new FragmentHomepage ();
fm.beginTransaction().add (R.id.mainactivity, fragment).commit();
}
You would want to save the state. You would need to extend Fragment to store the objects that need saving.
Override the onConfigurationChanged(..) and it should work out.
When I had to handle screen orientation changes, I recall having used this reference [link].
There are two ways.
Either you need to save the state in the bundle in onSaveInstanceState() method. Also save the states of fragment.
When activity recreate itself then check the value of bundle inside onCreate() or onRestoreInstanceState() method. Now initialize all the objects as before.
Else
set the value of activity inside manifest file as
android:configChanges="layoutDirection|orientation|screenLayout|screenSize"
and override the method.
#Override
public void onConfigurationChanged(Configuration newConfig) {
}
Second technique will not allow the activity to restart on orientation change.

Categories