Variable with Activity and Fragments - android

I have my activity with one boolean variable public.
I set the variable value to true in other class inside MainActivity, but when my application enters the onPause() function, the variable gets the value false, why?
public class MainActivity extends ActionBarActivity {
public boolean detectedState;
public boolean isDetectedState() {
return detectedState;
}
public void setDetectedState(boolean DetectedState) {
this.detectedState = DetectedState;
}
// i have one fragment in MainActivity...
public static class contentFragment extends Fragment{
// Get and set value of Variable
MainActivity activity = new MainActivity();
System.out.println(activity.isDetectedState());
//out is false
activity.setDetectedState(enable);
System.out.println(activity.isDetectedState());
//out is true
// if now i click in home Button for example, the application is with state onPause.. and my out println is false, why?
}
#Override
protected void onPause(){
super.onPause();
System.out.println(isDetectedState());
//here out is false...
}
}

You should understand that the value of detectedState is set to true for the instance of activity instantiated inside the Fragment class. Variable's value doesn't get affected if you change its value inside an inner class.

You should never create Activity like this
MainActivity activity = new MainActivity();
You can use interfaces to pass data between Activity and Fragment.

You can achieve it by making that variable static but it would be better if you store in the application class.check this

Related

How to get fragment tag or ID?

I have 2 fragments which are instantiated from the same class as the layouts are identical like so:
getSupportFragmentManager().beginTransaction().
add(R.id.leftContainer,new LeftFragmentClass(),"leftFrag").commit();
getSupportFragmentManager().beginTransaction().
add(R.id.rightFrag,new LeftFragmentClass(),"rightFrag").commit();
Within LeftFragmentClass there is a callback method which is called when the button within the fragment is pressed. After this some processing is done and data is displayed, however, right now the callback cannot distinguish which button was pressed. Is there a function which can return which fragment button was pressed?
For this type of condition i create a function inside fragment which will return me the instance of fragment and make the fragment constructor private something like:-
public class LeftFragmentClass extends Fragment{
private String fragmentTag = null;
public LeftFragmentClass(){}
public static LeftFragmentClass newInstance(String tag){
LeftFragmentClass mLeftFragmentClass = new LeftFragmentClass();
Bundle bundle = new Bundle();
bundle.putString ("tag",tag);
mLeftFragmentClass.setArgument(bundle);
return mLeftFragmentClass;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
tag = getArguments().getString("tag")
}
}
So i used newInstance function to create instance of LeftFragmentClass and pass the tag to it which i m setting to Fragment argument using bundle and inside onCreate get bundle using getArguments and from it the tag value. Pass this tag value as one of the parameter to your callback method to identify which button was clicked.
So from activity for getting instance of LeftFragmentClass you can write as
LeftFragmentClass mLeftFragmentClassLeft = LeftFragmentClass.newInstance("left")
LeftFragmentClass mLeftFragmentClassRight = LeftFragmentClass.newInstance("Right")
==== Edit ====
keep the fragment class constructors always public don't make it private as i suggested above in my sample code. Making it private will cause application to crash with exception
java.lang.RuntimeException: Unable to start activity
ComponentInfo{MainActivity}:
android.support.v4.app.Fragment$InstantiationException: Unable to
instantiate fragment com.thatswhy.AppAlertDialog: make sure class name
exists, is public, and has an empty constructor that is public
Fragment fragment = getFragmentManager().findFragmentByTag("Tag")
As per provided the info you can do something like this, in your callback method pass the button object and check accordingly,
Some code snippet to explain the same :
Suppose your callback method is onButtonClick() then you can pass button object like :
public void onButtonClick(Button button){
// check here with button id
if(button.getId() == R.id.button1) {
} else if(button.getId() == R.id.button1) {
}
}
Hope this makes things clear..
The cleanest way of doing this I've seen is to create two distinct View.OnClickListener(s) in the Activity.
Have a getter() for each. public View.OnClickListener getLeftButtonPressed(), public View.OnClickListener getRightButtonPressed()
Then when you instantiate your left and right instances of your fragment, just pass in the appropriate 'View.OnClickListener' to the constructor of the Fragment. This not only reduces the code in the Fragment(s), it also centralizes the 'logic' of what to do when buttons are pressed.
public class MyActivity extends Activity {
// create the two listeners
View.OnClickListener leftButtonListener = new View.OnClickListener() {
public void onClick(View v) {
leftButtonClicked(v);
}
});
View.OnClickListener rightButtonListener = new View.OnClickListener() {
public void onClick(View v) {
rightButtonClicked(v);
}
});
// 2 getters
public View.OnClickListener getLeftListener() { return this.leftButtonListener; }
public View.OnClickListener getRightListener() { return this.rightButtonListener; }
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.content_layout_id);
}
// actual logic of what to do when each button is pressed.
private void leftButtonClicked(View v){
// some logic here
}
private void rightButtonClicked(View v){
// some logic here
}
}
This removes you later having to keep track of which button was pressed by making use of strings and if/then/else blocks, etc.
Add a parameter to interface callback function in your fragment;
interface Interfacecallback{
public void callbackfunction(int fragid);
}
Interfacecallback interfacecallback;
//in your button click
//pass 1 for fragment right
//pass 2 for fragment left
interfacecallback.callbackfunction(1);
You can check the fragment tag using this line of code if it exists:-
Fragment mapFragment = getFragmentManager().findFragmentByTag("MapRestaurantFragment");

Get state of activity (paused / resumed)

I am using a LoaderManager to get some data and when it finishes a child fragment should be shown. In some cases this happens when the activity is already in paused state and can not perform the fragment transaction.
Is there a way to get the current state of the activity (seems to have a mResume flag)? Or do I have to maintain my own boolean?
The new Architecture Components allow you to do it with:
this.getLifecycle().getCurrentState()
A quick look in the Activity source code indicates that the Activity class does keep track on the resume state with the member mResumed. But since mResume is not public and isResumed() is hidden, we can't use them.
You can have a simple solution to provide you with that information for all your classes. Simply create a base Activity class that store the state. For example:
public class ActivityBase extends Activity {
private boolean mIsResumed = false;
#Override
public void onResume() {
super.onResume()
mIsResumed = true;
}
#Override
public void onPaused() {
super.onPaused()
mIsResumed = false;
}
public boolean isResumed() {
return mIsResumed
}
}
Simply extend this class with your class:
public class MyActivity extends ActivityBase {
private void onLoadDone() {
if (isResumed()) {
// Show the fragment
}
}
}
One way it could be achieved is by using breakpoints on your Activity (for instance, putting a breakpoint in your onResume method), and using the Evaluate Expression window that you can open by clicking a right click on your Debug menu window, and selecting it from there (OR SHIFT + F8) for mac. Once opened, you can intercept the current state (depending where your breakpoint is) using this line in your Evaluate Expression Window:
getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
If it returns true, that means your Activity is currently in the resume state.
If false, it's in another state.
They have plenty of other states you can play with, just check here

Get & Set Value of my Activity from a fragment - Android

I would like know how can I get and set a value of my activity from my fragment?? is that possible?
below is my activity and the attribute 'myStation' is the value I want get and set from my fragment.
public class MyActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
public static Station myStation;
In my fragment I can execute 'getActivity()' but I really don't know if I can do that. if I'm wrong, what is the correct process?¿
Thanks.
If the fragment is only used in that activity, then you can simply cast the activity. Otherwise you'll have to verify that it is the correct activity perhaps using instance of.
Let's look at the simpler case:
public class MyActivity extends Activity {
private boolean myFlag;
public boolean getMyFlag() {
return myFlag;
}
public void setMyFlag(boolean myFlag) {
this.myFlag = myFlag;
}
And here would be the fragment to adjust the flag.
public class MyUniqueFragment extends Fragment {
public void updateActivityFlag(boolean myFlag) {
MyActivity myActivity = (MyActivity) getActivity();
myActivity.setMyFlag(myFlag);
}
}

Calling one function on another activity

I have created a function
public void setTabHome(int index) { }
on main.java page. This function is to set the page by index.
By default, index is 0. I want to call main.java page from main1.java with the parameter index set to 1.
You can set the method to static and then call it again.
I would just insert that method again in main1.java though ¯_(ツ)_/¯
or even better access main1.java through an Intent.
public static void setTabHome(int index) { }
main.setTabHome(indexnumber)
Make an instance of your main.java class in main1.java class. Using this instance, you can call the function in main.java. Like this
Main main = new Main();
main.yourfunctionName();
But better you make another function in main1.java and use this function. Beacuse the parameters you used in one activity may cannot be used in another activity.
main.java define a public static instance in the class
public class Menu extends Activity{
public static Menu instance = null;
#Override
public void onCreate(Bundle savedInstanceState) {
instance = this;
}
public void setTabHome(int index) { }
}
main1.java call like this:
Menu.instance.setTabHome(number);

Android: how do I call findPreference() from my main activity?

I'm handling the preferences screen for my Android app. I want to disable (grey it out) an item if the preceding one has a specific value.
I have implemented two classes: MainActivity and PreferencesActivity.
In MainActivity I do:
public class MainActivity extends Activity implements OnSharedPreferenceChangeListener {
...
public void onCreate (Bundle savedInstanceState) {
...
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
sharedPrefs.registerOnSharedPreferenceChangeListener(this);
...
}
Then, when my preferences are requested by the user:
startActivity(new Intent(this, PreferencesActivity.class));
Then, to handle preferences in MainActivity, I do:
#Override
public void onSharedPreferenceChanged (SharedPreferences prefs, String key) {
if ("sport".equals(key)) {
sport = prefs.getString("sport", "");
ListPreference lp = findPreference("match_duration");
if (sport.equals(getString(R.string."sport_soccer"))) {
lp.setEnabled(false);
}
}
...
}
The problem is I can't call findPreference in MainActivity ("The method findPreference(String) is undefined for the type MainActivity"...).
Is my approach wrong? Shoud I implement onSharedPreferenceChanged() method in PreferencesActivity? If so, how do I use MainActivity properties in PreferencesActivity?
findPreference() should be called from a class implementing PreferenceActivity interface (PreferencesActivity in my context). MainActivity properties can be accessed via SharedPreferences class.

Categories

Resources