Hi guys,
I just want to know if there is some code to get the current number of fragments displayed on the screen.
Reason for this is, I can tell if two different of them overlaps, but I can't tell if they're equal.
I tried getSupportFragmentManager().getFragments().size() but it doesn't work as it seems as getSupportFragmentManager().getFragments() returns null...
domenicop said:
Hi guys,
I just wanting to know if there is some code to get the current number of fragments displayed on the screen.
Reason for this is, I can tell if two different of them overlaps, but I can't tell if they're equal.
I tried getSuppoertFragmentManager().getFragments().size() but it doesn't work as it seems, getSuppoertFragmentManager().getFragments() returns null...
Click to expand...
Click to collapse
No one can do that? It would be such a helpful little snippet of code....
Maybe you called the method before the Fragments were created? Or you're using a ViewPager. Code...
nikwen said:
Maybe you called the method before the Fragments were created? Or you're using a ViewPager. Code...
Click to expand...
Click to collapse
I am not asking in regard to a particular snippet of code, the problem is generic. I want to be able to count the fragments that are currently on the screen.
Maybe I understood your answer. You're saying that
Code:
getSupportFragmentManager().getFragments().size()
is the right way to check and so want to see code to check his strange behavior? BTW, I'm using a ViewPager (it is one of the fragments in my activity)
domenicop said:
I am not asking in regard to a particular snippet of code, the problem is generic. I want to be able to count the fragments that are currently on the screen.
Maybe I understood your answer. You're saying that
Code:
getSupportFragmentManager().getFragments().size()
is the right way to check and so want to see code to check his strange behavior? BTW, I'm using a ViewPager (it is one of the fragments in my activity)
Click to expand...
Click to collapse
Do you mean Fragments that are actually visible to the user or just those that have been created?
Yeah, that should be the right code... However, it doesn't include the Fragments which were added to the ViewPager as they haven't been added to the Activity/FragmentManager.
nikwen said:
Do you mean Fragments that are actually visible to the user or just those that have been created?
Yeah, that should be the right code... However, it doesn't include the Fragments which were added to the ViewPager as they haven't been added to the Activity/FragmentManager.
Click to expand...
Click to collapse
This is the main activity (it's the same one as the other post)
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentById(R.id.portraitFragmentContainer);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.replace(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentById(R.id.landscapeFragmentContainer);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentById(R.id.contactsPagerFragmentContainer);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.replace(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.replace(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
Log.d(TAG, "# of Fragments on the screen" + getSupportFragmentManager().getFragments().size());
}
Penultimate line is the one that throws a NullPointerException.
Working fine for me here:
Code:
# of Fragments on the screen1
nikwen said:
Working fine for me here:
Code:
# of Fragments on the screen1
Click to expand...
Click to collapse
Maybe it's something with the fragments initialization. How did you run your code?
domenicop said:
Penultimate line is the one that throws a NullPointerException.
Click to expand...
Click to collapse
Did you import the right Fragment from the v4 compatibility lib? Otherwise, you'd have to use getFragmentManager() instead!
Edit: I see, you're using it above as well so it shouldn't be the case, could you try to call fm.getFragments() and see what it returns, where fm is the FragmentManager you already created?
@SimplicityApks It was so before, it still crashes if I use the fm fragment manager.
I add the logcat output for what it's worth:
Code:
11-04 23:20:48.640: ERROR/AndroidRuntime(10131): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.domenicop.census/com.domenicop.census.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
at android.app.ActivityThread.access$600(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5289)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.domenicop.census.MainActivity.onCreate(MainActivity.java:104)
at android.app.Activity.performCreate(Activity.java:5133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)
... 12 more
11-04 23:20:48.650: WARN/ActivityManager(2322): Force finishing activity com.domenicop.census/.MainActivity
11-04 23:20:49.185: WARN/ActivityManager(2322): Activity pause timeout for ActivityRecord{42ad16f0 u0 com.domenicop.census/.MainActivity}
MainActivity.java:104 is the penultimate line of the class. The incriminated one.
domenicop said:
MainActivity.java:104 is the penultimate line of the class. The incriminated one.
Click to expand...
Click to collapse
What's null, fm or mContactsPagerFragment ?
fm.getFragments() does return null... How could that possibly be? I just instantiated them. Maybe I have to wait till they construct heir views?
I jus checked in the Android Developer API and I couldn't find any mention about this method. Eclipse was suggesting it.
I guess it's been deprecated, but even if that is true, why would it completely disappear?
Please someone that doublecheck on this. (I found getFragment (Bundle bundle, String key), no trace of getFragment...)
fm.getFragments() does return null... How could that possibly be? I just instantiated the fragments. Maybe I have to wait till they construct heir views?
EDIT
I just checked in the Android Developer API and I couldn't find any mention about this method. Eclipse is suggesting it.
I guess it's been deprecated, but even if that is true, why would it completely disappear?
Please someone that double-check on this. (I found getFragment (Bundle bundle, String key), no trace of getFragment...)
Also, thank you for talking to me, on other forums I feel like an alien when opening a 3d about android developer questions
domenicop said:
fm.getFragments() does return null... How could that possibly be? I just instantiated the fragments. Maybe I have to wait till they construct heir views?
EDIT
I just checked in the Android Developer API and I couldn't find any mention about this method. Eclipse is suggesting it.
I guess it's been deprecated, but even if that is true, why would it completely disappear?
Please someone that double-check on this. (I found getFragment (Bundle bundle, String key), no trace of getFragment...)
Also, thank you for talking to me, on other forums I feel like an alien when opening a 3d about android developer questions
Click to expand...
Click to collapse
Have you tested whether getFragments() returns null even if you call that method later (for example when a button is pressed)?
nikwen said:
Have you tested whether getFragments() returns null even if you call that method later (for example when a button is pressed)?
Click to expand...
Click to collapse
I just checked and it works if I don't call it from the MainActivity, anyway I've to say the results are not that comfortable. In some cases I've seen some output as scary as # of fragments on the screen is 45
It would be nice to know how this method works though. Without documentation, I can't really make any conclusion here.
Thank you for your help, and please report in this thread if you can find any explanation about the behavior of this method.
Bye.
domenicop said:
Hi guys,
I just want to know if there is some code to get the current number of fragments displayed on the screen.
Reason for this is, I can tell if two different of them overlaps, but I can't tell if they're equal.
I tried getSupportFragmentManager().getFragments().size() but it doesn't work as it seems as getSupportFragmentManager().getFragments() returns null...
Click to expand...
Click to collapse
if u implementing viewpager then u can simply use getCount() method to count the no. of pages.
Related
Hello!
First at all, I'm a beginner in android coding, I'm more a graphist with Photoshop as main tool.
A friend has made an app for my themes and is in holidays until september.
Beeing logical and understanding fast, with my friend Google we found the functions/codes I needed. Except one:
I have a horizontal scroll layout showing the apps needed to install the theme. Each app is showed in a linearlayout.
What I would like is make each linearlayout of apps clickable and make them show the app on the playstore when you click on it.
Thanks for reading
I assume you're using Textviews to add line by line the dependencies.. There is a property called autolink or very much like it that makes a link whenever it finds a url in the text...
But instead of Textviews in a linearlayout, why not use ListView? Then you can handle the click in the item to create an intent to open the browser with the url needed... it's a bit of more work but has a better esthetic than a bunch of TextViews... For instance, it makes it easier to use when in a ldpi device...
Sent from my LG-P350 using xda app-developers app
Sorry for the late.
I'm beginner in java coding so I don't undersand well what you mean dude.
In fact, what I have now is:
In res\layout\main.xml:
Code:
<HorizontalScrollView
android:id="@+id/layout5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout3"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
>
<LinearLayout
android:id="@+id/layout4"
android:background="#00000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
In MainActivity.java:
Code:
boolean apexInstalled = appInstalledOrNot("com.anddoes.launcher");
RelativeLayout apexApp = (RelativeLayout) getLayoutInflater().inflate(R.layout.item, null);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) (125 * scale + 0.5f),(int) (150 * scale + 0.5f));
ImageView apexI = (ImageView) apexApp.findViewById(R.id.appIcon);
apexI.setBackgroundResource(R.drawable.apexicon);
TextView apexT = (TextView) apexApp.findViewById(R.id.appText);
if(apexInstalled){
apexT.setText(R.string.installe);
apexT.setTextColor(Color.parseColor("#5a925d"));
}
else{
apexT.setText(R.string.nninstalle);
apexT.setTextColor(Color.parseColor("#de3747"));
}
apexT.setTypeface(font);
TextView apexTitle = (TextView) apexApp.findViewById(R.id.appTitle);
apexTitle.setText("Apex Launcher"); // \n == retour a la ligne
apexTitle.setTypeface(font);
apexApp.setBackgroundColor(Color.argb(190, 0, 0, 0));
listApp.addView(apexApp, params);
And I have many blocks like this one but with other apps, and I would like them to point on the playstore, what do I have to add?
Use a ListView with a custom Adapter: http://www.vogella.com/articles/AndroidListView/
Then add an OnItemClickedListener to the ListView.
In its onItemClick method you can use an Intent like this one:
Code:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + pkg); //Your package name here
if (getActivity().getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
startActivity(intent);
} else {
Toast.makeText(getActivity(), "Google Play is not installed on the device.", Toast.LENGTH_LONG).show();
}
Thanks trying to help me, but I understand aproximatively the intent, but the listview etc, no..
I'm just trying to modify a bit an app somebody made for me using my logic to understand what I have to do. The problem is that I don't understand how to apply what you tell me :/
Lyechee said:
Thanks trying to help me, but I understand aproximatively the intent, but the listview etc, no..
I'm just trying to modify a bit an app somebody made for me using my logic to understand what I have to do. The problem is that I don't understand how to apply what you tell me :/
Click to expand...
Click to collapse
OK, then let's forget about the ListView if you just want to modify your existing app with as little effort as possible.
Try that in your Java code:
Code:
LinearLayout layout = findViewById(R.id.layout4);
layout.setClickable(true);
layout.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + pkg); //Your package name here
if (getActivity().getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
startActivity(intent);
} else {
Toast.makeText(getActivity(), "Google Play is not installed on the device.", Toast.LENGTH_LONG).show();
}
}
});
(The word Override has to be written with a capital letter at the beginning. XDA does not allow that.)
But if I understand well that code, it will make a "link case" in the whole scroll layout no?
Or a link for each app?
If it's not possible to cut the horizontal scroll in little squares (links), is that possible to put a hyperlink on each imageview? So that click on the icon shows the store.
Lyechee said:
But if I understand well that code, it will make a "link case" in the whole scroll layout no?
Or a link for each app?
If it's not possible to cut the horizontal scroll in little squares (links), is that possible to put a hyperlink on each imageview? So that click on the icon shows the store.
Click to expand...
Click to collapse
Yes, it does. I thought that the Linear layout was loaded as the layout for each app.
Ok. I think that the RelativeLayout in the MainActivity.java is your row, right?
If it is, that should work:
Code:
apexApp.setClickable(true);
apexApp.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + pkg); //Your package name here
if (getActivity().getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
startActivity(intent);
} else {
Toast.makeText(getActivity(), "Google Play is not installed on the device.", Toast.LENGTH_LONG).show();
}
}
});
Yeah, each RelativeLayout is an app square. I'm not at home so I can't test it now, will later in the evening, thanks for your help!
Lyechee said:
Yeah, each RelativeLayout is an app square. I'm not at home so I can't test it now, will later in the evening, thanks for your help!
Click to expand...
Click to collapse
Welcome.
Hello! I'm in front of a problem.
I wanted to face it alone, but I don't manage it..
I have had a problem with "uri", and after googleing, I've found that I had to import it.
But my problem is that I get that error:
Code:
The method getActivity() is undefined for the type new View.OnClickListener(){}
Any idea?
Lyechee said:
Hello! I'm in front of a problem.
I wanted to face it alone, but I don't manage it..
I have had a problem with "uri", and after googleing, I've found that I had to import it.
But my problem is that I get that error:
Code:
The method getActivity() is undefined for the type new View.OnClickListener(){}
Any idea?
Click to expand...
Click to collapse
Ah, you're right. I'm sorry.
I copied the code from one of my fragments. Just delete the getActivity().
So it is:
Code:
apexApp.setClickable(true);
apexApp.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + pkg); //Your package name here
if (getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
startActivity(intent);
} else {
Toast.makeText(MainActivtiy.this, "Google Play is not installed on the device.", Toast.LENGTH_LONG).show(); //replace the MainActivity by your Activity
}
}
});
Works like a charm, thank you a lot Exactly what I wanted
If you need a graphist, I'm your man
PS: Is there a tool in Eclipse to make blocks of code lines? I mean, put them in blocs and then hide what you don't need.
Lyechee said:
Works like a charm, thank you a lot Exactly what I wanted
If you need a graphist, I'm your man
PS: Is there a tool in Eclipse to make blocks of code lines? I mean, put them in blocs and then hide what you don't need.
Click to expand...
Click to collapse
Yeah, there should be a minus on the left side next to each method. Click on it to hide the method.
Want to be added? [INDEX] List of themers and designers
I can link to System settings>Location access with Settings.ACTION_LOCATION_SOURCE_SETTINGS
Fine...but I want to link to System settings>Accounts(Google)>Location settings (this screen is called Google apps location settings)
Does someone know how to do this? Or at least how to get close to there?
Another issue I'm struggling with is how to link to PlayStore>Settings>Ads screen. Has someone an idea?
In the App Ops screen on Android 4.3, find the activity in the settings that you like to open, and launch it the usual way via intent. If you don't have 4.3 yet, you'd have to look at the Android source code and find it there
SimplicityApks said:
In the App Ops screen on Android 4.3, find the activity in the settings that you like to open, and launch it the usual way via intent. If you don't have 4.3 yet, you'd have to look at the Android source code and find it there
Click to expand...
Click to collapse
Thank you for your reply. I can try 4.3 soon. I planned to be compatible with 4.1+. If it is only possible to support 4.3+, that is at least something. Can you tell me how I can code it under 4.3+?`
I would list all activities on my device using the solution provided here.
Then choose the right one from the settings app.
alterechtschreibung said:
Thank you for your reply. I can try 4.3 soon. I planned to be compatible with 4.1+. If it is only possible to support 4.3+, that is at least something. Can you tell me how I can code it under 4.3+?`
Click to expand...
Click to collapse
OK sry, my fault. You don't need 4.3, just create a shortcut in Nova Launcher with activities - >settings and search the right activity. Why I thought 4.3 was needed is only because that was where I created a shortcut on the Homescreen to an activity the last time...
The code itself is clear:
Code:
Intent I = new Intent( "com.google.android.location.settings.GoogleLocationSettingsActivity" );
startActivity(i);
Edit got it!
You probably mean this screen:
"com.google.android.location.settings.GoogleLocationSettingsActivity"
SimplicityApks said:
OK sry, my fault. You don't need 4.3, just create a shortcut in Nova Launcher with activities - >settings and search the right activity. Why I thought 4.3 was needed is only because that was where I created a shortcut on the Homescreen to an activity the last time...
The code itself is clear:
Code:
Intent I = new Intent( "com.google.android.location.settings.GoogleLocationSettingsActivity" );
startActivity(i);
Edit got it!
You probably mean this screen:
"com.google.android.location.settings.GoogleLocationSettingsActivity"
Click to expand...
Click to collapse
Thank you. Unfortunately app crashes when calling it:
I/ActivityManager( 1473): START {act=com.google.android.location.settings.GoogleLocationSettingsActivity u=0} from pid 3501
D/AndroidRuntime( 3501): Shutting down VM
W/dalvikvm( 3501): threadid=1: thread exiting with uncaught exception (group=0x40a9f300)
E/AndroidRuntime( 3501): FATAL EXCEPTION: main
E/AndroidRuntime( 3501): java.lang.IllegalStateException: Could not execute method of the activity
alterechtschreibung said:
Thank you. Unfortunately app crashes when calling it:
I/ActivityManager( 1473): START {act=com.google.android.location.settings.GoogleLocationSettingsActivity u=0} from pid 3501
D/AndroidRuntime( 3501): Shutting down VM
W/dalvikvm( 3501): threadid=1: thread exiting with uncaught exception (group=0x40a9f300)
E/AndroidRuntime( 3501): FATAL EXCEPTION: main
E/AndroidRuntime( 3501): java.lang.IllegalStateException: Could not execute method of the activity
Click to expand...
Click to collapse
I also modified the code with no luck:
public void showClick_google_apps_location_settings(View view) {
Intent intent = showGoogleAppsLocationSettings();
startActivity(intent);
}
public static Intent showGoogleAppsLocationSettings() {
Intent intent = new Intent("com.google.android.location.settings.GoogleLocationSettingsActivity");
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
return intent;
}
Strange... Normally this should work... Maybe try to set the method not static but that shouldn't do anything actually.
SimplicityApks said:
Strange... Normally this should work... Maybe try to set the method not static but that shouldn't do anything actually.
Click to expand...
Click to collapse
Do I need certain permissions for com.google.android.location.settings.GoogleLocationSettingsActivity?
Usually not... You're testing on a real device, not an emulator aren't you?
SimplicityApks said:
Usually not... You're testing on a real device, not an emulator aren't you?
Click to expand...
Click to collapse
I'm on a real device with Android 4.1.x
I tried Nova Launcher. There is this entry:
settings.GoogleLocationSettings$Activity
Google apps location settings
This shortcut in Nova works. In my app it causes the crash.
If there is further code required, just tell me.
I hope probably not.That's it....
Sent from my Xperia U using xda app-developers app
Karchikumar said:
I hope probably not.That's it....
Sent from my Xperia U using xda app-developers app
Click to expand...
Click to collapse
What's wrong with testing on a real device? Finally the app must run on real devices and not in an emulator.
alterechtschreibung said:
What's wrong with testing on a real device? Finally the app must run on real devices and not in an emulator.
Click to expand...
Click to collapse
Nothing, testing on the emulator could crash since the Goggle settings may not be installed.
Really interesting and strange that it crashes, the only thing you can do now is to try other shortcuts and see if they work and it is just the Google location setting.
SimplicityApks said:
Nothing, testing on the emulator could crash since the Goggle settings may not be installed.
Really interesting and strange that it crashes, the only thing you can do now is to try other shortcuts and see if they work and it is just the Google location setting.
Click to expand...
Click to collapse
That works:
public void showClick_backup_restore_settings(View view) {
Intent intent = showBackupRestoreSettings();
startActivity(intent);
}
public static Intent showBackupRestoreSettings() {
Intent intent = new Intent(Settings.ACTION_PRIVACY_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
return intent;
}
and that works too:
public void showClick_google_apps_location_settings(View view) {
PackageManager packageManager = getPackageManager();
String packageName = ("com.dozingcatsoftware.asciicam");
try {
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if(null != intent) {
startActivity(intent);
}
}
catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
-----
while this doesn't work:
public void showClick_google_apps_location_settings(View view) {
PackageManager packageManager = getPackageManager();
String packageName = ("com.google.android.location.settings.GoogleLocationSettingsActivity");
try {
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if(null != intent) {
startActivity(intent);
}
}
catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
and this doesn't work either:
public void showClick_google_apps_location_settings(View view) {
Intent intent = showGoogleAppsLocationSettings();
startActivity(intent);
}
public static Intent showGoogleAppsLocationSettings() {
Intent intent = new Intent("com.google.android.location.settings.GoogleLocationSettingsActivity");
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
return intent;
}
Hi,
Normally sending data via Intent extras is easy. That's because it's between two activities. I'm trying to send data from my SherlockFragment to an Activity and it keeps returning null.
Does anyone know the correct way to send data? I'm trying to send a simple string. This is the way I'm trying:
Code:
Intent one = new Intent(mContext, Test.class);
one.putExtra("databaseUrl", "hello");
startActivity(one);
In my activity I am collecting it like this:
Code:
Intent in = new Intent();
dburl = in.getStringExtra("databaseUrl");
I ran a Log.i on dburl after it collected the data and it returned null so obviously it's not being transferred over.
Any help is appreciated. Thanks.
RED_ said:
Hi,
Normally sending data via Intent extras is easy. That's because it's between two activities. I'm trying to send data from my SherlockFragment to an Activity and it keeps returning null.
Does anyone know the correct way to send data? I'm trying to send a simple string. This is the way I'm trying:
Code:
Intent one = new Intent(mContext, Test.class);
one.putExtra("databaseUrl", "hello");
startActivity(one);
In my activity I am collecting it like this:
Code:
Intent in = new Intent();
dburl = in.getStringExtra("databaseUrl");
I ran a Log.i on dburl after it collected the data and it returned null so obviously it's not being transferred over.
Any help is appreciated. Thanks.
Click to expand...
Click to collapse
// This line creates a new, empty intent
Intent in = new Intent();
// I wouldn't expect it to have any extras here..
in.getStringExtra("databaseUrl");
Have a look at the docs
http://developer.android.com/reference/android/app/Activity.html#getIntent()
PicomatStudios said:
// This line creates a new, empty intent
Intent in = new Intent();
// I wouldn't expect it to have any extras here..
in.getStringExtra("databaseUrl");
Have a look at the docs
http://developer.android.com/reference/android/app/Activity.html#getIntent()
Click to expand...
Click to collapse
Hmmm, problem is when I was doing this in another app; communicating between two activities it was working fine, with the same exact code. I'm not near my code at the moment, I'll see what I can do with getIntent() in the morning. Thanks.
RED_ said:
Hmmm, problem is when I was doing this in another app; communicating between two activities it was working fine, with the same exact code. I'm not near my code at the moment, I'll see what I can do with getIntent() in the morning. Thanks.
Click to expand...
Click to collapse
Let's have another look to make sure...
line 1: Intent in = new Intent();
line 2: dburl = in.getStringExtra("databaseUrl");
.. have you missed anything out in your post by any chance ???
Replace this
Code:
Intent in = new Intent();
by this:
Code:
Intent in = getActivity().getIntent();
nikwen said:
Replace this
Code:
Intent in = new Intent();
by this:
Code:
Intent in = getActivity().getIntent();
Click to expand...
Click to collapse
It won't let me do that.
"The method getActivity() is undefined for the type Test"
Test.class is the activity.
I got it working after removing getActivity() and just using Intent in = getIntent().
Thanks for the help!
I got it working after removing getActivity() and just using Intent in = getIntent().
Thanks for the help!
RED_ said:
I got it working after removing getActivity() and just using Intent in = getIntent().
Thanks for the help!
Click to expand...
Click to collapse
Sounds good. Can you see why the original version doesn't work ?
Incidentally if you were doing this the other way around (if you were in a Fragment and wanted the intent that started its Activity), then you could use getActivity().getIntent().
You didn't mention where in the Activity code you're calling getIntent(), so there is one more step you should take, which is to research the circumstances under which onNewIntent() might be called.
I used this way, and it works.
Code:
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString("POPUP_TYPE");
}
Sending message from fragment to activity.
The best way of communication between Fragment and Activity is through an Interface.
interface StartCommunication
{
public void setComm(String msg);
}
then define the method in Activty and then use this method to send message.
worked for me
You can also follow this.
If it is shared data between and needs to be set once at activity level, you can use private variable in activity with get and set methods.
I just discovered how to use the action bar to have a OptionsMenu. I just solved a problem with it and I wanted to know if I did it the right way.
What I did
So, I added the menu to a fragment started by an activity, adding to it the setHasOptionsMenu(true) in the onCreate method and setting up the two convenience methods public void onCreateOptionsMenu() and public boolean onOptionsItemSelected() of course setting up the xml first.
The problem
Now, if I rotate my device in landscape mode the button in the action bar duplicates. If I put it in portrait mode again, the number of items stays the same (I'm sure it doesn't actually increase, checked the size in different ways) though.
What I thought and how I solved it
So, I was thinking about some fragment overlaps, but if they actually overlap then I shouldn't notice anything, right?
Is the menu being recreated, while not destroyed when the fragment is destroyed?
I solved the problem removing the item in the menu, in the Fragment.onDestroy() method manually.
Is the menu supposed to be cleared manually, or there is something wrong with my code (eg. fragments overlapping, etc..) ?
domenicop said:
Is the menu supposed to be cleared manually, or there is something wrong with my code (eg. fragments overlapping, etc..) ?
Click to expand...
Click to collapse
Could you please post your code? That would make helping much easier.
nikwen said:
Could you please post your code? That would make helping much easier.
Click to expand...
Click to collapse
Of course. Thanks for the interest.
This is the onCreate method of MainActivity.java, from where I handle the arrangement of fragments on the screen.
Also, place check my comment under the line "Log.d(TAG, "Orientation Portrait detected.");", where I try to explain why I handle fragments in that specific way. It's the way I understood it, but I'm not sure if that's correct.
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that goes all right, we have our fragment.
// Else, null will be returned.
mContactListFragment = (ContactListFragment) fm.findFragmentById(R.id.portraitFragmentContainer);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.replace(R.id.portraitFragmentContainer, mContactListFragment)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentById(R.id.landscapeFragmentContainer);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentById(R.id.contactsPagerFragmentContainer);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.replace(R.id.contactListFragmentContainer, mContactListFragment)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.replace(R.id.contactsPagerFragmentContainer, mContactsPagerFragment)
.commit();
}
}
}
This are the relevant pieces of the ContactListFragment.java, that have something to do with the menu
Note that I changed the way I checked for double menu entries.
Now I check if (menu.size() != 1), because I have just one item in there.
If I remove that clause, there will be two item in the menu after rotating to landscape mode, and if I take the device back to portrait mode, the two items will remain two. That's so even if I change from landscape to portrait and vice versa a hundred times from now, the menu items will always be two.
Code:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
Bundle args = getArguments();
mDatabase = (ContactsDatabase) args.getSerializable(DATABASE);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
if (menu.size() != 1) {
inflater.inflate(R.menu.contact_list_fragment_menu, menu);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addContactMenu:
mCallback.onAddContactMenuOptionSelected();
default:
return super.onOptionsItemSelected(item);
}
}
domenicop said:
I just discovered how to use the action bar to have a OptionsMenu. I just solved a problem with it and I wanted to know if I did it the right way.
What I did
So, I added the menu to a fragment started by an activity, adding to it the setHasOptionsMenu(true) in the onCreate method and setting up the two convenience methods public void onCreateOptionsMenu() and public boolean onOptionsItemSelected() of course setting up the xml first.
The problem
Now, if I rotate my device in landscape mode the button in the action bar duplicates. If I put it in portrait mode again, the number of items stays the same (I'm sure it doesn't actually increase, checked the size in different ways) though.
What I thought and how I solved it
So, I was thinking about some fragment overlaps, but if they actually overlap then I shouldn't notice anything, right?
Is the menu being recreated, while not destroyed when the fragment is destroyed?
I solved the problem removing the item in the menu, in the Fragment.onDestroy() method manually.
Is the menu supposed to be cleared manually, or there is something wrong with my code (eg. fragments overlapping, etc..) ?
Click to expand...
Click to collapse
I agree with nikwen but broadly the idea is...
- the menu belongs to the Activity not the Fragment.
- for an Activity for which you'd like an options menu you override onCreateOptionsMenu and do 2 things...
1/ call menu.add(...) for each menu item
2/ return 'true' at the end, so that your menu can be displayed
Also, see the Activity docs for onCreateOptionsMenu()
"This is only called once, the first time the options menu is displayed.
To update the menu every time it is displayed, see onPrepareOptionsMenu(Menu)."
If you want to add menu options to the Activity menu from within a Fragment you can also..
- override setHasOptionsMenu() in Fragment to return true
- override onCreateOptionsMenu() to add any items you like (just like you did at the Activity level)
- override onDestroyOptionsMenu()
The key thing here is that onCreateOptionsMenu() in Fragment is adding to the Activity menu.
It's hard to see without debugging exactly what's going on here but watch for calls to all of the above methods in Activity and Fragment and that will probably tell you what's going on.
If it is possible to control all menu options at the Activity level instead of the Fragment level, I would do that.
If not, and you need to use the Fragment menu methods, beware of Android's Fragment management (saving / restoring state)
Also, make sure your Fragments have an ID and/or tag.
(from the docs..)
"The fragment being instantiated must have some kind of unique identifier so that it can be re-associated with a previous instance if the parent activity needs to be destroyed and recreated. This can be provided these ways:
If nothing is explicitly supplied, the view ID of the container will be used.
android:tag can be used in <fragment> to provide a specific tag name for the fragment.
android:id can be used in <fragment> to provide a specific identifier for the fragment."
Finally, if all else fails, using Menu's findItem() before calling add() would be a safeguard, I suppose.
---------- Post added at 10:14 PM ---------- Previous post was at 09:52 PM ----------
domenicop said:
Of course. Thanks for the interest.
Click to expand...
Click to collapse
Sorry caught in the crossfire - have only just seen your code.
I think much of the above applies.
Set the menu up in the Activity instead of the Fragment, if you can.
I would also consider using layout-port and layout-land to control your two different layouts.
PicomatStudios said:
I agree with nikwen but broadly the idea is...
- the menu belongs to the Activity not the Fragment.
- for an Activity for which you'd like an options menu you override onCreateOptionsMenu and do 2 things...
1/ call menu.add(...) for each menu item
2/ return 'true' at the end, so that your menu can be displayed
Also, see the Activity docs for onCreateOptionsMenu()
"This is only called once, the first time the options menu is displayed.
To update the menu every time it is displayed, see onPrepareOptionsMenu(Menu)."
If you want to add menu options to the Activity menu from within a Fragment you can also..
- override setHasOptionsMenu() in Fragment to return true
- override onCreateOptionsMenu() to add any items you like (just like you did at the Activity level)
- override onDestroyOptionsMenu()
The key thing here is that onCreateOptionsMenu() in Fragment is adding to the Activity menu.
It's hard to see without debugging exactly what's going on here but watch for calls to all of the above methods in Activity and Fragment and that will probably tell you what's going on.
If it is possible to control all menu options at the Activity level instead of the Fragment level, I would do that.
If not, and you need to use the Fragment menu methods, beware of Android's Fragment management (saving / restoring state)
Also, make sure your Fragments have an ID and/or tag.
(from the docs..)
"The fragment being instantiated must have some kind of unique identifier so that it can be re-associated with a previous instance if the parent activity needs to be destroyed and recreated. This can be provided these ways:
If nothing is explicitly supplied, the view ID of the container will be used.
android:tag can be used in <fragment> to provide a specific tag name for the fragment.
android:id can be used in <fragment> to provide a specific identifier for the fragment."
Finally, if all else fails, using Menu's findItem() before calling add() would be a safeguard, I suppose.
---------- Post added at 10:14 PM ---------- Previous post was at 09:52 PM ----------
Sorry caught in the crossfire - have only just seen your code.
I think much of the above applies.
Set the menu up in the Activity instead of the Fragment, if you can.
I would also consider using layout-port and layout-land to control your two different layouts.
Click to expand...
Click to collapse
Wow. thanks for that detailed answer. :good: (Why have I used all my thanks?)
I've always put it into the Activity as well but it might make sense to add it to the Fragment sometimes. For example if you need the same Fragment in multiple Activities...
In that case you'd need to add a listener to the item in the Fragment method though.
@PicomatStudio Thank you for the detailed answer, I really appreciate that =)
Now I'm creating the menu in the activity and I don't have to worry about the fragments life cycle anymore.
The only problem is: I didn't get the menuInflater for free here, I guess it's because of the fact that in the Fragment scenario, I had to use the Activity inflater, whereas here in the activity, I can get my own, with getMenuInflater().
Here's the way I modified it, now is in MainActivity.java.
Please report back if you find something strange
Code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getSupportFragmentManager().findFragmentByTag(CONTACT_LIST_FRAGMENT) != null)
getMenuInflater().inflate(R.menu.contact_list_fragment_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addContactMenu:
onAddContactMenuOptionSelected();
default:
return super.onOptionsItemSelected(item);
}
}
domenicop said:
@PicomatStudio Thank you for the detailed answer, I really appreciate that =)
Now I'm creating the menu in the activity and I don't have to worry about the fragments life cycle anymore.
The only problem is: I didn't get the menuInflater for free here, I guess it's because of the fact that in the Fragment scenario, I had to use the Activity inflater, whereas here in the activity, I can get my own, with getMenuInflater().
Here's the way I modified it, now is in MainActivity.java.
Please report back if you find something strange
Code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getSupportFragmentManager().findFragmentByTag(CONTACT_LIST_FRAGMENT) != null)
getMenuInflater().inflate(R.menu.contact_list_fragment_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addContactMenu:
onAddContactMenuOptionSelected();
default:
return super.onOptionsItemSelected(item);
}
}
Click to expand...
Click to collapse
I don't tend to use MenuInflater (just menu.add()..)
But looking at the docs it takes a Context so could you do..
Code:
new MenuInflater(this);
.. from your Activity ?
On a general design point the less your Activity depends on its Fragments the better, I reckon.
domenicop said:
The only problem is: I didn't get the menuInflater for free here, I guess it's because of the fact that in the Fragment scenario, I had to use the Activity inflater, whereas here in the activity, I can get my own, with getMenuInflater().
Click to expand...
Click to collapse
Well, you can get one:
Code:
getActivity().getMenuInflater();
The titles explains all of the problem, I'll provide extra info here.
I have a code in my MainActivity that calls a
Code:
mContactListFragment.notifyInvalidated();
method.
This is the method
Code:
public void notifyInvalidated() {
Log.w(MainActivity.TAG, "" + _viewExists);
Log.w(MainActivity.TAG, "The not still casted object is " + getListAdapter());
Log.w(MainActivity.TAG, "The casted object is " + (BaseAdapter)getListAdapter());
((BaseAdapter) getListAdapter()).notifyDataSetInvalidated();
}
All of the above prints false, null, null, and then the program crashes at the 4th instruction.
_viewExists is a variable that's initialized to false as soon as it's created and it's touched in no other part but in the onCreateView() method that sets it to true.
So while debugging, I arrived to the conclusion that nothing works because onCreateView() is not actually called, even though my Fragment is on the screen.
This happens after I rotated the device and I'm in landscape mode.
If I report the device in portrait mode (from landscape to portrait again) and try to call that method, all is good.
I am not sure what other code you would want to see, just ask.
I have to admin I am tired of problems involving fragments and rotations (configuration changes), what would you suggest me to read?
domenicop said:
The titles explains all of the problem, I'll provide extra info here.
I have a code in my MainActivity that calls a
Code:
mContactListFragment.notifyInvalidated();
method.
This is the method
Code:
public void notifyInvalidated() {
Log.w(MainActivity.TAG, "" + _viewExists);
Log.w(MainActivity.TAG, "The not still casted object is " + getListAdapter());
Log.w(MainActivity.TAG, "The casted object is " + (BaseAdapter)getListAdapter());
((BaseAdapter) getListAdapter()).notifyDataSetInvalidated();
}
All of the above prints false, null, null, and then the program crashes at the 4th instruction.
_viewExists is a variable that's initialized to false as soon as it's created and it's touched in no other part but in the onCreateView() method that sets it to true.
So while debugging, I arrived to the conclusion that nothing works because onCreateView() is not actually called, even though my Fragment is on the screen.
This happens after I rotated the device and I'm in landscape mode.
If I report the device in portrait mode (from landscape to portrait again) and try to call that method, all is good.
I am not sure what other code you would want to see, just ask.
I have to admin I am tired of problems involving fragments and rotations (configuration changes), what would you suggest me to read?
Click to expand...
Click to collapse
I've had these problems, too. They're really annoying.
Could you please post your code where the Fragment is created, the onCreate method of the Fragment and the onCreate method of the Activity?
You have to use (override) onActivityCreated for that.
Taptalked u see .. əəs n pəʞlɐʇdɐʇ
nikwen said:
I've had these problems, too. They're really annoying.
Could you please post your code where the Fragment is created, the onCreate method of the Fragment and the onCreate method of the Activity?
Click to expand...
Click to collapse
Sure, here they are.
Fragment
Code:
public static ContactListFragment newInstance(ContactsDatabase database) {
ContactListFragment f = new ContactListFragment();
Bundle args = new Bundle();
args.putSerializable(DATABASE, database);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mDatabase = (ContactsDatabase) args.getSerializable(DATABASE);
}
Activity
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentByTag(CONTACTS_PAGER_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
}
Zatta said:
You have to use (override) onActivityCreated for that.
Taptalked u see .. əəs n pəʞlɐʇdɐʇ
Click to expand...
Click to collapse
Could you elaborate a little bit on that? Where should I use onActivityCreated? I need to use notifyDataSetChanged() whenever a button is pressed. Maybe you're talking about the variable.
I don't really need the _viewExists variable, it was only created to debug the problem.
domenicop said:
Sure, here they are.
Fragment
Code:
public static ContactListFragment newInstance(ContactsDatabase database) {
ContactListFragment f = new ContactListFragment();
Bundle args = new Bundle();
args.putSerializable(DATABASE, database);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mDatabase = (ContactsDatabase) args.getSerializable(DATABASE);
}
Activity
Code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize the mDatabase
mContactsDatabase = ContactsDatabase.getInstance(getApplicationContext());
// Determine device orientation
mDualPane = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Set the fragment that will be changed
mFragmentToReplace = mDualPane ? R.id.contactsPagerFragmentContainer : R.id.portraitFragmentContainer;
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentByTag(CONTACTS_PAGER_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
}
Click to expand...
Click to collapse
domenicop said:
Could you elaborate a little bit on that? Where should I use onActivityCreated? I need to use notifyDataSetChanged() whenever a button is pressed. Maybe you're talking about the variable.
I don't really need the _viewExists variable, it was only created to debug the problem.
Click to expand...
Click to collapse
After the fragment is created is stays created. When you rotated the device the onCreate of the activity is called again but not the onCreateView of the fragment. However, the onActivityCreated in the fragement is.
See for reference http://developer.android.com/guide/components/fragments.html#CoordinatingWithActivity
Your explanation was crystal clear.
However, the developer reference was not that help.
In the article you linked, it says to watch at figure 3 and notice how when the activity is created, the fragment will receive only the onActivityCreated() callback.
The flow of a fragment's lifecycle, as it is affected by its host activity, is illustrated by figure 3. In this figure, you can see how each successive state of the activity determines which callback methods a fragment may receive. For example, when the activity has received its onCreate() callback, a fragment in the activity receives no more than the onActivityCreated() callback.
Click to expand...
Click to collapse
This is Figure 3
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
I need to know which activity callback affects which fragment callback but I can't extrapolate anything from here.
Should I worry about my sight/cognitive decline?
Also, there is a main problem with the way I add fragments to the layout, I just noticed.
Basically, look at this code in MainActivity.java
Code:
// Set up the GUI
FragmentManager fm = getSupportFragmentManager();
if (!mDualPane) {
Log.d(TAG, "Orientation Portrait detected.");
// First, look for previously saved fragments
// findByFragmentId(int id) look for the fragment that was previously associated
// to the resource that has for id the argument passed in. Then, we try to cast it
// to the type of fragment we want, and if that's correct, we have our fragment
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.portraitFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
}
else {
Log.d(TAG, "Orientation Landscape detected.");
// First, look for previously saved fragments
mContactListFragment = (ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
mContactsPagerFragment = (ContactsPagerFragment) fm.findFragmentByTag(CONTACTS_PAGER_FRAGMENT);
if (mContactListFragment == null) {
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactListFragmentContainer, mContactListFragment, CONTACT_LIST_FRAGMENT)
.commit();
}
if (mContactsPagerFragment == null) {
final int FIRST_CONTACT_POSITION = 0;
mContactListFragment = ContactListFragment.newInstance(mContactsDatabase);
mContactsPagerFragment =
ContactsPagerFragment.newInstance(FIRST_CONTACT_POSITION, mContactsDatabase);
fm.beginTransaction()
.add(R.id.contactsPagerFragmentContainer, mContactsPagerFragment, CONTACTS_PAGER_FRAGMENT)
.commit();
}
}
When I am in dualPane mode, the mContactListFragment won't be on the screen.
That happens because
Code:
(ContactListFragment) fm.findFragmentByTag(CONTACT_LIST_FRAGMENT);
does not return null even though the fragment is not in the layout (it look for fragments in the BackStack in that case).
I fixed this explicitly checking for that case:
Code:
(mContactsPagerFragment == null || !mContactListFragment.isInLayout())
but I still have a doubt: Should the fragment be treated in another way when found in the BackStack?
Maybe I can take it back on top of the stack, refreshing its view?
I ask this because it seems like a candidate to performance issue, or worse, something that could result in the creation of double/triple fragment running on the activity (with just one of them visible, of course)
Sorry if the explanation was messy, bring that up and I'll try to reformulate the problem in other words.
Thank you guys
Zatta said:
After the fragment is created is stays created. When you rotated the device the onCreate of the activity is called again but not the onCreateView of the fragment. However, the onActivityCreated in the fragement is.
See for reference http://developer.android.com/guide/components/fragments.html#CoordinatingWithActivity
Click to expand...
Click to collapse
No, the Fragments are destroyed when the Activity is destroyed. However, you can call
Code:
setRetainInstance(true)
in the Fragment code/onCreate method so that it won't be destroyed. But in general Fragments are destroyed when the Activity is destroyed.
Aditionally, the setRetainInstance() method is meant to be used with Fragments without UI only. That way you can use it to execute background tasks. (It does work with UI Fragments, too, but it's bad practice.)
Evidence:
If an activity stops, its fragments are also stopped; if an activity is destroyed its fragments are also destroyed.
Click to expand...
Click to collapse
Source: http://www.vogella.com/articles/AndroidFragments/article.html#usingfragments_lifecycle
---------- Post added at 07:51 PM ---------- Previous post was at 07:38 PM ----------
domenicop said:
Also, there is a main problem with the way I add fragments to the layout, I just noticed.
Click to expand...
Click to collapse
Exactly, that's why the onActivityCreated() method isn't called.
You create the Fragments after the Activity has been created. So it wouldn't make sense to call that method. Maybe you could use onAttach() instead.
Try to do the dual pane implementation like this: http://developer.android.com/guide/components/fragments.html#Example
(Or use the template in Android Studio/Eclipse.)
nikwen said:
No, the Fragments are destroyed when the Activity is destroyed. However, you can call
Code:
setRetainInstance(true)
in the Fragment code/onCreate method so that it won't be destroyed. But in general Fragments are destroyed when the Activity is destroyed.
Aditionally, the setRetainInstance() method is meant to be used with Fragments without UI only. That way you can use it to execute background tasks. (It does work with UI Fragments, too, but it's bad practice.)
Evidence:
Source: http://www.vogella.com/articles/AndroidFragments/article.html#usingfragments_lifecycle
Click to expand...
Click to collapse
I should have replied before that all is good if I add the adapter from the onActivityCreated callback.
I also knew about fragment being destroyed when the activity is destroyed when setRetainInstance() was not called.
Maybe when fragments are recreated, the callbacks invoked are just a sub-set of the original one.
PS. Have you read my previous post?
domenicop said:
PS. Have you read my previous post?
Click to expand...
Click to collapse
I did. Check my answer. (Did it one by one.)
nikwen said:
Exactly, that's why the onActivityCreated() method isn't called.
You create the Fragments after the Activity has been created. So it wouldn't make sense to call that method. Maybe you could use onAttach() instead.
Click to expand...
Click to collapse
I didn't follow your line of thought, could you please re-elaborate?
nikwen said:
Try to do the dual pane implementation like this: http://developer.android.com/guide/components/fragments.html#Example
(Or use the template in Android Studio/Eclipse.)
Click to expand...
Click to collapse
I can't because I need to dynamically change them later and this wouldn't be possible with the static xml initialization.
Fragments present in XML, can't be .remove()'ed.
domenicop said:
I didn't follow your line of thought, could you please re-elaborate?
Click to expand...
Click to collapse
Sorry, forget about the first part of my post. Just checked the documentation:
onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
Click to expand...
Click to collapse
(Source: http://developer.android.com/reference/android/app/Fragment.html)
I can't because I need to dynamically change them later and this wouldn't be possible with the static xml initialization.
Fragments present in XML, can't be .remove()'ed.
Click to expand...
Click to collapse
Why can't you remove them?
---------- Post added at 08:13 PM ---------- Previous post was at 08:09 PM ----------
nikwen said:
Sorry, forget about the first part of my post. Just checked the documentation:
(Source: http://developer.android.com/reference/android/app/Fragment.html)
Click to expand...
Click to collapse
OK, don't forget about it. Checked it again. :laugh:
The commit() method of FragmentTransaction:
Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.
Click to expand...
Click to collapse
http://developer.android.com/reference/android/app/FragmentTransaction.html#commit()
This means that the Fragment is added after the Activity has finished the onCreate() method.
However, the onActivityCreated() method is just called when the onCreate() method of the Activity has finished. In this case the Fragments doesn't exist at that time. So the method cannot be called.
Does it make sense now?
---------- Post added at 08:17 PM ---------- Previous post was at 08:13 PM ----------
One more try:
Activity is created
FragmentTransaction is sheduled
onCreate() finishes
No Fragment whose onActivityCreated() method can be called exists
Fragment is created
onActivityCreated() isn't called as it's just called when the Activity's onCreate() method finishes (on all Fragments that exist at that time).
nikwen said:
Activity is created
FragmentTransaction is sheduled
onCreate() finishes
No Fragment whose onActivityCreated() method can be called exists
Fragment is created
onActivityCreated() isn't called as it's just called when the Activity's onCreate() method finishes (on all Fragments that exist at that time).
Click to expand...
Click to collapse
Nice catch man!
I tried to just initialize the adapter onCreate() and all is good.
Do you have any particular reason for indicating onAttach()?
I have to say if it wasn't for this list though, I thought you were just going crazy making things up
Also I've to ask one thing at this point, why do you say that the fragments are not created when the onCreate() method ends?
Aren't they initialized inside that method?
domenicop said:
Nice catch man!
I tried to just initialize the adapter onCreate() and all is good.
Do you have any particular reason for indicating onAttach()?
I have to say if it wasn't for this list I though you were just going crazy making things up
Click to expand...
Click to collapse
Haha. Great. :laugh:
Why I talked about onAttach(): At that point you can be sure that there's an Activity which is available via getActivity().
But if it works for you now, don't change it.
---------- Post added at 09:15 PM ---------- Previous post was at 09:10 PM ----------
domenicop said:
Also I've to ask one thing at this point, why do you say that the fragments are not created when the onCreate() method ends?
Aren't they initialized inside that method?
Click to expand...
Click to collapse
Ah, I haven't been accurate enough. Should have been like this:
Activity is created
Fragment is created
FragmentTransaction is sheduled
onCreate() finishes
No Fragment whose onActivityCreated() method can be called is attached to the Activity
Fragment is added to the Activity
onActivityCreated() isn't called as it's just called when the Activity's onCreate() method finishes (on all Fragments that exist at that time).
It's being created during onCreate() but it's added to the Activity later. That's why there's no attached Fragment whose onActivityCreated() method can be called.
And why it's added later:
The commit() method of FragmentTransaction:
Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.
Click to expand...
Click to collapse
http://developer.android.com/reference/android/app/FragmentTransaction.html#commit()