Pass fragments between activities - android

I want to make an application that can support portrait and landscape. The layout has two panes, on the left is the options and the right shows the result. When an option is selected the right pane shows it. But for portrait there is not enough room, so a separate activity is needed. Each option produces a different type of fragment, so I don't want to make an activity for each option when all that changes between activities is what fragment is being added there. I want to pass a fragment from the main activity to the new one, how would I do this?

EDIT: Moved what asker actually wants to top.
If you want to pass data to an Activity when creating it, call a version of Intent.putExtra() on the intent that is used in startActivity(). You can then use getIntent().getStringExtra() to (for example) get a string extra in the activity.
Say you have a piece of string data in your first activity called myString.
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra(EXTRA_NAME_CONSTANT, myString);
startActivity(intent);
Now in your new activity in onCreate you would do:
String myString = this.getIntent()
.getStringExtra(EXTRA_NAME_CONSTANT, "default return value here");
A few notes:
For that EXTRA_NAME_CONSTANT, I do mean to make a string constant of the form "your.package.name.SomeString" for example "com.example.MyString". Personally I'd even use a resource (accessed in the form getString(R.string.extra_my_string)) for the extra's name. They recommend you prefix it with your package name.
You can put and get many types of data from strings to arrays to even serializable data.
Instead of making a separete activity for different layout orientations consider using resource qualifiers to provide alternative layouts.
To summarize, make two layouts in a structure like so:
/res/layout/yourlayout.xml
/res/layout-land/yourlayout.xml
Where both XML files are named the same. Then make your default portrait layout in one and a landscape version in the other.
When you inflate the layout in onCreate (and when it does so automatically on a layout change during runtime) it will select the correct layout for you.

I want to pass a fragment from the main activity to the new one, how would I do this?
You wouldn't. At most, you would follow #Ribose's answer -- pass a flag into the activity via an extra to indicate what set of fragments to create.

Related

many activities with same content (adview, reward adview, functions...) how to avoid repeating code?

I have a gallery app, with some categories: animals, flowers... each gallery I created one activity, this activity in all galleries has the same content:
onCreate:
tSpeak = new TextToSpeech(this, new TextToSpeech.OnInitListener() { ...
AdView adView = new AdView(MainActivity.this); ...
//some checks to change images:
if(fase == 1) { imageView1.setImageResource(R.drawable.flower1); ...
if(fase == 100) ...
some setOnClickListener
after that some onRewardedVideo functions, a next() function that will intent to the same activity to show next image on this gallery (`fase` + 1)
What I'd like to know is, can I instead of repeating all this things (TextToSpeech, listeners, rewardedvideos functions, adview functions) just change the if checks in each activity gallery? this is the only thing that will change in each activity gallery, and I don't want to use just one activity for all categories because in this case I may have more than 2000 ifs and it is not good to work.
I'd like to just inject in each category the ifs to set imageresources there, without need to copy all activity again and again in each category. Any ideas?
You can create your common functionalities in a BaseActivity and extend your activities from this BaseActivity.
For the ifs conditional checking you can have a boolean field in your BaseActivity which you can override in your each subclass (In this case, your actual activities).
A better option could be having one activity only where your category is passed in the Bundle. Now based on your category, you can switch over the value and keeps your variations.
I suggest you use a single activity and pass a gallery ID as a parameter to your activity via an Intent extra.
You could get the image resource ids of the current gallery from a static map in your activity.
You could also use a ViewPager with one gallery per fragment, to enable your user to navigate quickly accross galleries.
Look at this for more info:
https://developer.android.com/training/animation/screen-slide

Getting fragment instance in my activity

Is there some way I get already created currently displayed same instance of fragment in my activity. I DON'T to use
findFragmentById(int id), simply I never created that
findFragmentByTag(String tag), because I am not adding tag in every fragment .offcourse due to some requirement.
getFragment(Bundle bundle, String key), because I never am putting in bundle.
Although I may look like fool to mention that, but I want something like this. Is activity keep some fragment instance somewhere.??
What can be the best approach I can take to achieve this requirement.
UPDATE
Okay, so let me tell you why I can't use above methods. If I am adding various fragment in one activity, where I always want to come back to one fragment when back is clicked. (As we have in navigation drawer, u know). And unless there are inner fragment. so for that I don't want to add in the back stack.
Now even if I have the tag associated with my fragments, I cant say for 8 fragment if- else-if-else for getting the tag. That I know is not correct. So first two ways goes out of my option. Now third one. I exactly don't know where to keep it. And even if I keep it where will I get the bundle and key every time I just want my fragment.
You can get from fragment Manager
List<Fragment> fragList=fManager.getFragments();
for(Fragment fr: fragList){
String fragClassName = fr.getClass().getName();
if(fragClassName.equals(Abc.class.getName())){
Log.i("Fragment:","Abc");
}else if (fragClassName.equals(Xyz.class.getName())) {
Log.i("Fragment:","Xyz");
}
}

Load Activity with dynamic view and content in Android

I am very new to Android development and I'm trying to figure out the best way to achieve the following goal:
I want to have a main menu that holds several buttons. Each of those buttons should load a second Activity and pass some data to this Activity.
The Secondary Activity should display a tabbar that switches between three different views or activities:
1. A static view created for each element (button on main menu)
2. An image gallery with a set of images associated with that element
3. Another page with dynamic content like a map and images.
My thought: Create a json file for each element and pass the name of that file to the Secondary Activity with could then create the views using that data.
Problem: Can you store the name of a layout.xml file as a string and then load it?
So what would be the best Practice to approach this?
Pass the information of which layout/which views you want to display in the second activity as an extra on the intent used to start the activity:
Intent i = new Intent(FirstActivity.this, SecondActivity.class);
i.putExtra("layout_identifier", 5);
startActivity(i);
Then extract this information in the receiving activity onCreate():
Bundle b = getIntent().getExtras();
int layout = b.getInt("layout_identifier", 0);
switch (layout) {
case 5:
setContentView(R.layout.activity_second_layout5);
break;
Note that the datatype passed does not necessarily have to be int, you can pass all primitives, strings and a third option called Parcelable (https://developer.android.com/reference/android/os/Parcelable.html) which can be thought of as a container for objects.

Passing data from one activity to another in Android [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to pass a value from one Activity to another in Android?
I have an activity with a list of titles and their bodies(content) (list6 example from ApiDemos). And I have an activity, where I add a note. When I click on "Add" button, I want the title of my note to appear on the list. Same with body. The problem is, that in List activity there are two String[] arrays with predefined hard-coded titles and bodies. What should I do to be able to add my own new titles with a content instead of having these hard-coded values?
I know I must use intents with startActivityForResult, but that's probably all I know...
You have two option:
1) make the listview and the two arraylists static
This way you can use the same instances of it from the activity with add button and modify the listview as:
FirstActivity.listTitlesArrayList.add(listTitleString);
FirstActivity.listDescriptionArraylist.add(listDescriptionString);//this is probably your note
FirstActivity.listView.invalidateViews();
2)if you want to use intents:
while going to the ListActivity pass data by..
intent.putExtra("Title", listTitleString);
intent.putExtra("Content", listDescriptionString);
startActivity(intent);
and to recover it in second activity use:
title= getIntent().getExtras().getString("Title");
...and so on..
There are several ways to share data between activities.
In your case probably the easiest way is to have a reference to list in Application. This answer summs it up nicelly: Making data obtained in one activity available to all the activities

How to use intent between tabs in java/Android?

I would need to know how to handle the intent between tabs. For example, I have a tab activity with two tabs. First on content is a text view. another one is a map view. When i click that text view it redirects to the tab2. it can be easily achieved by setCurrentTab(1) or setCurrentTabByTag("tab2") methods. But i want to pass lat and long values to that Map Activity to drop pin. What is the better way to use intents or getter/setter in java? What do you prefer? if your answer is "Intents". How?
A interesting problem. I understand it that you want to change to the second tab on a click in the first tabview but also pass special data to the second tab that is dependent on the action in the first tab.
I would generally start your views inside the tabs with an activity. However this is done at the moment the tab host is configured. That means both intents the one for the activity that lets the user choose lat long and the one that shows lat long are openend at the same time.
Therefore you can't add the information to the intent used to intialize the tab host.
I don't like the solution but the only thing that comes to my mind (using different activities for the tabs) is using a custom application that stores a reference to an object containing the data that you need to update the view in the second tab. You have to extend application with an own class and add this class in you manifest, now you can call getApplication in the first tab cast it to your application class set lat and long just before you call setCurrentTab. In the second tab you can call getApplication() again and you will then get the application object that is the same for every activity at every moment of your app running. You then have cast it again to your application object and retrieve lat and long value. See this page in the google refs on how to use a custom application class.
To use a custom application class add the following to your application tag in your manifest:
<application
...
android:name=".somepackage.CustomAppClass"
This will tell Android to instantiate the CustomAppClass as your Application class at the moment your app starts. You need to extend Application to avoid errors on start up.
Another solution but not the one I would prefer is to initialize the views yourself and initialize the tabhost with views and not activities. With a map view in one of the tabs this could be very memory heavy.
If you want to pass values between activities, I suggest looking at
http://developer.android.com/reference/android/content/SharedPreferences.html
the best way to get values from one itent to another.
With sharedPrefrences, there is only one instance of the class for the whole application, which means that you can store values in the files, switch intents or activities, and then recall those sharedPrefrence files that have the data in them.
The only downside is that you have to pass primitive types (int, string, boolean) but I'm sure you'll figure ways around this :).
I dont see the Problem here:
Maybe its a little bit of hackish but following Code works for me:
public boolean onClick(View v) {
//get your data you wanna send.
//If it is an Object it would be good if it is Parcelable
Object o = getYourData();
// or Parcelable p = getYourData
Activity activity = getParent();
//I'm assuming were inside an Activity which is started by TabActivity
if (activity instanceof TabActivity){
TabActivity ta = (TabActivity)activity;
//now determine the Tab you wanna start
ta.getTabHost().setCurrentTabByTag("yourTag");
//or ta.getTabHost().setCurrentTab(yourID);
Activity current = ta.getCurrentActivity();
//check if the Activity is the one you wanna start
if (current instanceof YOUR_ACTIVITY_YOU_WANNA_START){
//Cast to your Activity
YOUR_ACTIVITY_YOU_WANNA_START yourActivity =
(YOUR_ACTIVITY_YOU_WANNA_START)current;
// you only need to put Data inside your Intent
Intent intent = new Intent();
intent.putExtra("EXTRA_DATA_TAG", o);
//your Activity must Override onNewIntent and make it public,
//or simply add another method
//with whatever You like as parameter
yourActivity.onNewIntent(intent);
return true;
}
}
return false;
}
this way you don't have to mess with Application, SharedPrefs or other unnessesary stuff mentioned here
If you make the intent you are using to start the second tab activity a global intent.
You can then add extra's to this intent in the onPause() of the first tab. Note: you have to define all your tabs in separate activitys than your tabhost TabActivity as this activity's onPause() is never called.
This also help's with the answer above, if you are using a global variable saved in your activity that extends application, you can set this in the onPause() as it is fired before the activity is switched, which you might find an issue if setting this elsewhere

Categories

Resources