I have a problem that I don't know how to solve. How do you hide a toolbar in a specific fragment, I have already been searching around on the internet and what I found was communicating activity and fragment would solve it. But it doesn't work for me at all, here is my code:
main_activity:
public class MainActivity extends ActionBarActivity implements like_frag.OnHideToolbar{
....
public void onHidingToolbar(int position){
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
if(toolbar == null){
getSupportActionBar().hide();
}else{
getSupportActionBar().hide();
}
}
like_frag.java
public class like_frag extends Fragment {
OnHideToolbar mCallback;
Toolbar toolbar;
public interface OnHideToolbar {
public void onHidingToolbar(int position);
}
public void onAttach(Activity activity){
try{
mCallback = (OnHideToolbar) activity;
}catch(ClassCastException e){
throw new ClassCastException(activity.toString() + "error implementing");
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.swipefrag, container, false);
toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
}
thanks in advance.
I have a drawer inside the toolbar.
Put this code in fragment in which you want to hide toolbar...
#Override
public void onResume() {
super.onResume();
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
}
#Override
public void onStop() {
super.onStop();
((AppCompatActivity)getActivity()).getSupportActionBar().show();
}
In the fragment's onCreate method call:
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
Replace AppCompateActivity with the activity class you used.
Edited:
You could simply use the onResume method to call hide() and the onStop method to call show() as suggested in some of the comments.
#Override
public void onResume() {
super.onResume();
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
}
#Override
public void onStop() {
super.onStop();
((AppCompatActivity)getActivity()).getSupportActionBar().show();
}
If you are using the new Navigation Component, add this while setting up the toolbar
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
#Override
public void onDestinationChanged(#NonNull NavController controller,
#NonNull NavDestination destination, #Nullable Bundle arguments) {
if(destination.getId() == R.id.full_screen_destination) {
toolbar.setVisibility(View.GONE);
bottomNavigationView.setVisibility(View.GONE);
} else {
toolbar.setVisibility(View.VISIBLE);
bottomNavigationView.setVisibility(View.VISIBLE);
}
}
});
And for Kotlin, you can do the following:
navController.addOnDestinationChangedListener { _, destination, _ ->
if(destination.getId() == R.id.full_screen_destination) {
toolbar.setVisibility(View.GONE)
bottomNavigationView.setVisibility(View.GONE);
} else {
toolbar.setVisibility(View.VISIBLE)
bottomNavigationView.setVisibility(View.VISIBLE);
}
}
Create an interface in the fragment and use it to tell the parent activity to hide the toolbar.
Add these lines to your fragment:
private OnEventListener listener;
public interface OnEventListener {
void hideToolbar() ;
}
public void setOnEventListener(OnEventListener listener) {
this.listener = listener;
}
After creating your fragment in the main activity add:
myFragment.setOnEventListener(new MyFragment.OnEventListener() {
#Override
public void hideToolbar() {
getSupportActionBar().hide();
}
});
Whenever you need to hide the toolbar execute:
listener.hideToolbar();
from inside your fragment.
Just add these methods to the fragment where you want to diable the toolbar ,and also in the fragment's onStop() make it visible again.
#Override
public void onResume() {
super.onResume();
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
}
#Override
public void onStop() {
super.onStop();
((AppCompatActivity)getActivity()).getSupportActionBar().show();
}
in kotlin hide and show supportActionBar as follows:
override fun onResume() {
super.onResume()
(activity as AppCompatActivity).supportActionBar?.hide()
}
override fun onStop() {
super.onStop()
(activity as AppCompatActivity).supportActionBar?.show()
}
and if you want to have your own custom toolbar, in OncreateView set:
//your Custom toolbar in xml
val toolbar = binding.toolbar
(activity as AppCompatActivity).setSupportActionBar(toolbar)
Simply use supportActionBar?.hide() or supportActionBar?.show().
If you are using NavigationController:
navController.addOnDestinationChangedListener { controller, destination, arguments ->
if (destination.id == R.id.loginSuccessFragment) {
supportActionBar?.hide()
} else {
supportActionBar?.show()
}
}
Put this code in fragment in which you want to hide toolbar...
Add this( ((AppCompatActivity)getActivity()).getSupportActionBar().hide();) in onCreateView or in onResume.
and do this in onDestroy()
#Override
public void onDestroy() {
super.onDestroy();
((AppCompatActivity)getActivity()).getSupportActionBar().show();}
use getSupportActionBar().hide(); and getSupportActionBar().show(); in lifeCycle methods
You can try it.
#Override
public void onDestinationChanged(#NonNull NavController controller, #NonNull NavDestination destination, #Nullable Bundle arguments) {
if (destination.getId() == R.id.nav_dashboard){
if (toolbar !=null){
toolbar.setVisibility(View.GONE);
}
}else {
toolbar.setVisibility(View.VISIBLE);
}
}
Related
I have an app consisting of (among other things) one Activity and one Fragment. In the Activity som data is displayed using TextViews, and in the Fragment the user can input some data using EditText-views. I have a method which takes data from both the Activity and Fragment, performs some calculations and finally displays a result in both the Fragment and the Activity. This method currently works when I call if after editing the text in any of the EditText-views in the Fragment. However, I also want to call it each time I update the data in the Activity but when I attempt this, I can not fetch the EditText data because they return null.
So my question is: what is good practice, or the ”right way” to do when dealing with methods that are supposed to be reached from both an Activity and a Fragment? I would greatly appreciate if someone could lead me onto the right track.
I have read the official documentation on Fragments and there ViewModel was mentioned. But this doesn’t seem suitable in for my application since I want the Activity to be involved. Do I need to use this or can I go through my main Activity? I’ve also read about Interfaces, but I’m not sure which one would suit my project best. I’m currently using Interfaces, but I’m not sure if I’m doing it correctly.
I’ve also watched this video and read these following questions:
Shared ViewModel to help communication between fragments and parent activity
Call a fragmentMethod from another fragment, but can't refer to them in parentFragmentActivity's View pager
how to manage the fragments in android correctly?
"My God"’s reply to this question was helpful but I’m still not sure what is the best thing to do in my case, as I have a Fragment where user can input data, and the same fragment should also view data as a result of that input. (Maybe my first mistake is building the app like this?)
I provide some code in case it is helpful.
public class AccuracyFragment extends Fragment {
EditText editTextLevel, editTextAccuracy;
private OnFragmentInteractionListener mListener;
public AccuracyFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_accuracy, container, false);
editTextAccuracy = view.findViewById(R.id.text_accuracy_character);
editTextLevel = view.findViewById(R.id.text_level_character);
TextWatcher watcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//Doing nothing
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//Doing nothing
}
#Override
public void afterTextChanged(Editable editable) {
updateFragment(Float.valueOf(editTextLevel.getText().toString()), Float.valueOf(editTextAccuracy.getText().toString()));
}
};
editTextLevel.addTextChangedListener(watcher);
editTextAccuracy.addTextChangedListener(watcher);
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null; //I don’t know what this does
}
#Override
public void onResume() {
super.onResume();
// updateFragment(); //Should I have this?
}
public interface OnFragmentInteractionListener {
String[] onAccuracyFragmentInputChanged(float levelFromFragment, float accuracyFromFragment); }
public void updateFragment(float level, float accuracy) {
//Complicated method doing things with editTextLevel and editTextAccuracy. However, it doesn’t work when this method is called from outside AccuracyFragment – EditTexts are null
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
#Override
public void onStop() {
super.onStop();
}
}
public class MainActivity extends AppCompatActivity implements AccuracyFragment.OnFragmentInteractionListener, AdapterView.OnItemSelectedListener {
AccuracyFragment accuracyFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_new);
selectedID = null;
textView1 = (TextView) findViewById(R.id.text_1);
textView2 = (TextView) findViewById(R.id.text_2);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state, then we don't need to do anything and should return or else we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
accuracyFragment = new AccuracyFragment();
}
}
//This is the core method which takes the value from two EditTexts in the Fragment, and two TextViews in the MainActivity
private String[] getRequiredAccuracy(float firstValueFromActivity, float secondValueFromActivity, float firstValueFromFragment, float secondValueFromFragment) {
//This methods uses parameters from the Activity, and two from the Fragment, and is intended to be called from both the Activity and from the Fragment itself
String returnValues[] = {s, q, r, c}; //This method is too complex to show, but it will end up outputting some values
return returnValues;
}
public void methodCalledUponClick(View view) {
//After showing a Dialog with some choices, I intend to call the method from fragment:
accuracyFragment.updateFragment();
}
#Override
public String[] onAccuracyFragmentInputChanged(float levelFromFragment, float accuracyFromFragment) {
String returnValues[] = {"0", "0", "0"};
if (selectedID != null) {
if (textView1.length() == 0 || textView2.length() == 0) {
//Do nothing if any of these are empty
} else {
returnValues = getRequiredAccuracy(Float.valueOf(textView1.getText().toString()), Float.valueOf(textView2.getText().toString()), levelFromFragment, accuracyFromFragment);
}
}
return returnValues;
}
}
}
You can go ahead with callback/Interface to communicate with fragment and activity simultaneously.
For Creating callback/Interface:
public interface CallBackListener {
void onCallBack(String value);// pass any parameter in your onCallBack which you want to return
}
In Fragment Class:
public class AccuracyFragment extends Fragment {
private CallBackListener callBackListener;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//getActivity() is fully created in onActivityCreated and instanceOf differentiate it between different Activities
if (getActivity() instanceof CallBackListener)
callBackListener = (CallBackListener) getActivity();
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
EditText editText = (EditText) view.findViewById(R.id.edittext);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(callBackListener != null)
callBackListener.onCallBack(s.toString());
}
});
}
}
In your Activity:
public class MainActivity extends AppCompatActivity implements CallBackListener
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onCallBack(String value) {
Toast.makeText(mContext,"onCallback Called",Toast.LENGTH_LONG).show();
}
}
I'm new to android and I'm trying to get a hang of creating and using Fragments.
I have a fragment that shows a simple list of multiple dates to choose from and implements an onClickListener. The idea is once a user chooses a date, the fragments sends the date back to the MainActivity which then runs a query in database and sends the database response to another fragment.
I'm stuck on the point of sending the date back to MainActivity, elegantly. I can't find much info. I found this:
Activity activity = getActivity();
if(activity instanceof MyActivity){
MyActivity myactivity = (MyActivity) activity;
myactivity.myMethod();
}
I'm very new to this but this seems hacky to me. Is this the right way or is there another way?
Any input is appreciated
I prefer the interface based approach because is very clean. You can declare a nested interface in your Fragment or an external one:
interface OnMyStuffListener {
void myMethod();
}
Make the Activity to implement that interface:
public class MainActivity extends Activity implements OnMyStuffListener {
#Override
public void myMethod() {
// Do whatever you want.
}
}
The Fragment will be attached to the Activity so you can check the instance of the Context and cast it to the Activity:
public class MyFragment extends Fragment implements View.OnClickListener {
private OnMyStuffListener mListener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnMyStuffListener) {
mListener = (OnMyStuffListener) context;
} else {
throw new IllegalArgumentException("The context " + context.getClass().getName() +
"must implement " + OnMyStuffListener.class.getName());
}
}
#Override
public void onDetach() {
super.onDetach();
// Release it avoiding memory leak.
mListener = null;
}
#Override
public void onClick(View v) {
mListener.myMethod();
}
}
YES this is absolutely right. You can use this, if you are not sure that your Fragment is attached to Activity
You can also achieve this by using Interface, using an EventBus like LocalBroadcastManager, or starting a new Activity with an Intent and some form of flag passed into its extras Bundle or something else.
Here is an example about using Interface:
1. Add function sendDataToActivity() into the interface (EventListener).
//EventListener.java
public interface EventListener {
public void sendDataToActivity(String data);
}
2. Implement this functions in your MainActivity.
// MainActivity.java
public class MainActivity extends AppCompatActivity implements EventListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void sendDataToActivity(String data) {
Log.i("MainActivity", "sendDataToActivity: " + data);
}
}
3. Create the listener in MyFragment and attach it to the Activity.
4. Finally, call function using listener.sendDataToActivity("Hello World!").
// MyFragment.java
public class MyFragment extends Fragment {
private EventListener listener;
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
if(activity instanceof EventListener) {
listener = (EventListener)activity;
} else {
// Throw an error!
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
// Send data
listener.sendDataToActivity("Hello World!");
return view;
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
Hope this will help~
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.
I know I came a bit too late to the party and over the past 3 years (or maybe longer) there've been thousands and thousands of discussion like this one (unfortunately most of them involving activities and not fragments), but I'm curious about one thing.
Having the following piece of code, can mFragment be null when the AsyncTask's callback onError() or onSuccess() gets called after the screen orientation changes? So the AsyncTask starts, I rotate the screen of the device and at some point the AsyncTask will return an error or a success. When this happens, can the mFragment be null?
I already know that this cannot happen when dealing with Activities because basically no messages will be processed between a call to onRetainNonConfigurationInstance() of the previous instance and onCreate() of the new instance of the activity.
Unfortunately I couldn't find anything about this rule when it comes to fragments.
Do you guys know anything about this?
Thank you for your answers!
public class Fragment extends Fragment {
private WorkerFragment mWorkerFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWorkerFragment =(WorkerFragment)getFragmentManager().findFragmentByTag("worker_fragment");
if (mWorkerFragment == null) {
mWorkerFragment = new WorkerFragment();
getFragmentManager().beginTransaction().add(mWorkerFragment, "worker_fragment").commit();
}
if (savedInstanceState == null) {
mWorkerFragment.performAsyncTask();
}
private static class WorkerFragment extends Fragment {
private TypeOfAsyncTask mAsyncTask;
private Fragment mFragment;
private Callback mCallback = new Callback() {
#Override
public void onError(Error error) {
// Can mFragment be null here?
mFragment.onSendRequestError(error);
}
#Override
public void onSuccess(Result result) {
// Can mFragment be null here?
mFragment.onSendRequestSuccess(result);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mFragment = (Fragment) getTargetFragment();
}
#Override
public void onDetach() {
super.onDetach();
mFragment = null;
}
private void performAsyncTask() {
mAsyncTask = new TypeOfAsyncTask(mCallback);
mAsyncTask.execute();
}
}
}
I'm developing an Android app and am to the point where I would like to integrate Facebook login onto the main page. I am following these directions for the same:
https://developers.facebook.com/docs/android/login-with-facebook/#step1
Part of the walkthrough lists changing the MainActivity class to extend FragmentActivity. My MainActivity class, however, already extended it because of a content slider I implemented on the main view. The original onCreate code of MainActivity was:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
invalidateOptionsMenu();
}
});
}
And this was working great. Following the Facebook login walkthrough, I added a new 'MainFragment' class following the directions as literally as possible:
public class MainFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, container, false);
return view;
}
}
, also added a com.facebook.widget.LoginButton to my MainActivity layout (this seems to display fine), and tried to tie it all together by adding the following to the OnCreate section of the MainActivity class (displayed above, but not repeating it all here again for brevity):
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new MainFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mainFragment)
.commit();
} else {
// Or set the fragment from restored state info
mainFragment = (MainFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
The question I fundamentally have is how to make both my existing slider and Facebook login play together nicely? If I add the Facebook code needed to OnCreate of MainActivity, then my slider goes away. If I don't add the code, then Facebook login obviously doesn't work. I've read as much as possible on Fragments thinking I might be doing something wrong there, but haven't had much luck...
Thanks in advance for any help you can provide!
Here is my solution, you make your MainActivity as the first level, in this level your Android app will check whether the user is logged or not, based on this, go to the second level, which is either a Facebook login page or the content slider. For implementation, it would be like this:
This is the MainActivity:
public class MainActivity extends FragmentActivity{
private LoginFragment loginFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
loginFragment = new LoginFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, loginFragment)
.commit();
} else {
// Or set the fragment from restored state info
loginFragment = (LoginFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
}
}
This is the LoginFragment:
public class LoginFragment extends Fragment {
private LoginButton authButton;
private static final String TAG = "MainFragment";
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.login_fragment,
container, false);
authButton=(LoginButton)view.findViewById(R.id.login_button);
authButton.setFragment(this);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
Session session = Session.getActiveSession();
if (session != null &&
(session.isOpened() || session.isClosed()) ) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
startActivity(new Intent(getActivity(), ContentSliderActivity.class));
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
}
And here is the activity which you suppose to have a content slider, this will be displayed after the user has successfully logged in, here I call it ContentSliderActivity:
public class ContentSliderActivity extends FragmentActivity{
.....................
}
I was able to discern the problem was in the MainFragment on CreateView method. For some reason, if I removed this override, I didn't have a problem where my content sliderr gets removed. No idea why, but instead of adding the following lines: LoginButton authButton = (LoginButton) findViewById(R.id.authButton); authButton.setFragment(this); in the onViewCreate method of MainFragment, I simply moved them to the onCreate method in MainActivity. Seems to have worked for me, although not entirely sure what the original problem was honestly.