I have 2 Fragments that both pass an intent to an Activity (through an event listener). How can the Activity know which of these 2 fragments passed the intent? There's a method called getCallingActivity(), I need the equivalent for fragments.
I Attempted to determine which Fragment Called the Activity with the onAttachFragment() method, But it doesn't work:
public class DetailsActivity extends Activity {
static final String POSITION = "position";
private Movie movie;
private int position;
private static final String TAG = "app";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
}
#Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
Log.v(TAG, "fragment_src");
position = (int) getIntent().getExtras().get(POSITION);
if (fragment instanceof PopularFragment) {
movie = PopularFragment.movieList.get(position);
setData();
} else if (fragment instanceof TopRatedFragment) {
movie = TopRatedFragment.movieList.get(position);
setData();
}
}
public void setData() {
TextView original_title = (TextView) findViewById(R.id.original_title);
original_title.setText(movie.getOriginal_title());
...
}
}
You could send different int values with your intent for both fragment and check in your activity..or you could get your fragment by using
Fragment fragment = getFragmentManager().findFragmentByTag("yourtag");
Why don't you pass some parameters through the Intent itself
For first fragment-
Intent intent=new Intent(getActivity(),DetailsActivity.class);
intent.putExtra("fragName","PopularFragment");
startActivity(intent);
For Second Fragment-
Intent intent=new Intent(getActivity(),DetailsActivity.class);
intent.putExtra("fragName","TopRatedFragment");
startActivity(intent);
In your Activity
String fragName=getIntent().getStringExtra("fragName");
And then just check using if..else.
Related
After seeing this question, it got me thinking. I can get a Intent in a Fragment by calling this inside onCreateView:
String Item = getActivity().getIntent().getExtras().getString("name");
the problem with this is that getActivity might return null, to counter that I can call:
if(getActivity() != null)
String Item = getActivity().getIntent().getExtras().getString("name");
}
this will work fine, but..
I was thinking of creating a static method in my Activity and then accessing the Intent in my fragment by calling that method, like this (In my Activity):
public class DemoActivity extends Activity{
static String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
//Getting the Intent from the previous Activity
name = getIntent().getStringExtra("name");
}
public static String Name(){
//returning the Intent
return name;
}
}
Then in my Fragment I can call this like this:
String name = DemoActivity.Name();
My Question:
Can I do it like this? Will it cause any issues and why?
Currently
It is working fine.
try like this:
Activity class:
Bundle bundle = new Bundle();
bundle.putString("your_key", "your_value");
your_fragment.setArguments(bundle);
Fragment class:
String your_variable = getArguments().getString("your_key");
Set in first activity fragment:
Bundle bundle = new Bundle();
bundle.putString("your_string_key", "your_value");
startActivity(new Intent(getActivity() your_second_activity.class).putExtra("bundle_key", bundle));
Get bundle value second activity:
fragment.setArguments(getIntent().getBundleExtra("bundle_key"));
In Second Activity Fragment:
getArguments().getString("your_string_key")
I have a ViewPager with 3 fragments in it, each fragment has a next and prev. button, and you can also swipe left and right to navigate through fragments. and although I'm able to get the input from each fragment when the next button is clicked, I sill can't figure out a way to get the input when the user scrolls between fragments.
this is the code in my first fragment:
public class signupfrag1 extends Fragment {
private TextInputEditText fName, lName;
public Spinner spncountry, spncity;
private Button next1;
private String vfName, vlName, vcountry, vcity;
private String method;
signupfrag1Listener activityCommander;
public interface signupfrag1Listener{
public void getDataFromFrag1(String fName, String lName, String countryName, String cityName);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
activityCommander = (signupfrag1Listener) context;
}catch (ClassCastException e){
throw new ClassCastException(context.toString());
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.signupfrag1, container, false);
fName = (TextInputEditText) view.findViewById(R.id.edtFName);
lName = (TextInputEditText) view.findViewById(R.id.edtLName);
spncountry = (Spinner) view.findViewById(R.id.cmbCountry);
spncity = (Spinner) view.findViewById(R.id.cmbCities);
next1 = (Button) view.findViewById(R.id.btnNext2);
next1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
vfName = fName.getText().toString();
vlName = lName.getText().toString();
if(vfName.equals("") || vfName.length()==1){
fName.setError("please enter a correct first name!");
}
else if(vlName.equals("") || vlName.length()==1){
lName.setError("Please enter a correct first name!");
}
else
startFrag2(view);
}
});}
public void startFrag2(View view){
activityCommander.getDataFromFrag1(vfName, vlName, vcity, vcountry);
}
this is the code from my main activity:
public class Main2Activityforfragments extends AppCompatActivity implements signupfrag1.signupfrag1Listener, signupfrag2.signupfrag2Listener {
private ViewPager fragsViewPager;
private SectionsPagerAdapter1 sectionsPagerAdapter1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2_activityforfragments);
fragsViewPager = (ViewPager) findViewById(R.id.fragsViewPager);
sectionsPagerAdapter1 = new SectionsPagerAdapter1(getSupportFragmentManager());
fragsViewPager.setAdapter(sectionsPagerAdapter1);
}
//this get called when the next button is clicked
#Override
public void getDataFromFrag1(String fName, String lName, String cityName, String countryName) {
if(fragsViewPager.getCurrentItem() == 0){
fragsViewPager.setCurrentItem(1);}
}
if you are in the first fragment then create ref. of interface and call its method and pass the values on Click what you want and it is needed to implement Two interface in SecondFragment. call its method in the First Fragment. you can create interface Two in SecondFragment
Two Second=new SecondFragment(); // it will be called on click of firstFragment which pass the value.
Second.two("Value one","Value two");
interface Two{
void two(String value,String value); // implement this inteface in SecondFragment and call it in FirstFragment
}
When you reach to second you get the value from the first fragment and continue with the third fragment as same.
I have an Activity that has a section where a Fragment is shown. A button is clicked on the Fragment and a new Activity launches with some buttons. Depending on which button is clicked, that activity closes and the Fragment should be updated accordingly but I'm having trouble accessing the views on the Fragment to edit them.
It seems that in the onResume() of the Fragment, I'm unable to access the view using getView(). I've also tried passing in the view from the Activity that the Fragment lives in, but that also returned null.
So I'm wondering if Fragments are static after onCreateView() is called?
SecondActivity calling back into MainActivity:
#Override
protected void onResume() {
super.onResume();
rvAdapter.setOnItemClickListener(new RVAdapter.MyClickListener() {
#Override
public void onItemClick(View v, int position) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("key", value);
startActivity(intent);
}
});
}
MainActivity handling the call back and calling a function in the Fragment:
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
String value = intent.getStringExtra("key");
if (value != null) {
((ExampleFragment) exampleFragment).updateFragment(value);
}
}
Fragment attempting to update itself:
public void updateFragment(String value) {
TextView textView = (TextView) getView().findViewById(R.id.profile_text_view);
if (value != null) {
textView.setText(value);
}
}
And the result would be NPE on getView() call in the Fragment. I've tried passing in the view from MainActivity via: exampleFragment.getView() but also no luck.
I want to pass some data from one activity to another and set it in dynamically created TextView over frame layout of that activity..I'm using intent for that but at second activity the data is not getting extracted..Can any one tell me the simple way for this..
Following is my code..
Hidden.java
public class Hidden extends Activity implements OnClickListener {
Button btnnameadd, btnnameremove, btnmobileadd, btnmobileremove, btndone;
EditText etname, etmobile;
ImageView ivlogo;
private AlertDialog dialog;
private Uri mImageCaptureUri;
Intent jump;
//options for image selection
private static final int PICK_FROM_CAMERA = 1;
private static final int CROP_FROM_CAMERA = 2;
private static final int PICK_FROM_FILE = 3;
LinearLayout llname, llmobile, llimage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hidden);
captureImageInitialization();
init();
}
private void init() {
etname=(EditText)findViewById(R.id.editTextname);
etmobile=(EditText)findViewById(R.id.editTextmobile);
btnnameadd=(Button)findViewById(R.id.buttonnameadd);
btnnameremove=(Button)findViewById(R.id.buttonnameremove);
btnmobileadd=(Button)findViewById(R.id.buttonmobileadd);
btnmobileremove=(Button)findViewById(R.id.buttonmobileremove);
btndone=(Button)findViewById(R.id.buttondone);
llname=(LinearLayout)findViewById(R.id.name);
llmobile=(LinearLayout)findViewById(R.id.mobile);
btnnameadd.setOnClickListener(this);
btnnameadd.setOnClickListener(this);
btnnameremove.setOnClickListener(this);
btnmobileadd.setOnClickListener(this);
btnmobileremove.setOnClickListener(this);
btndone.setOnClickListener(this);
}
#Override
public void onClick(View v) {
jump=new Intent(Hidden.this,Framelayout.class);
if(v.getId()==R.id.buttonnameadd)
{
String strname=etname.getText().toString();
Log.d("Log",strname);
jump.putExtra("Name",strname);
}else if(v.getId()==R.id.buttonnameremove)
{
btnnameremove.setEnabled(false);
llname.removeView(findViewById(R.id.editTextname));
}else if(v.getId()==R.id.buttonmobileadd)
{
String strmobile=etmobile.getText().toString();
Log.d("Log",strmobile);
jump.putExtra("Mobile",strmobile);
Log.d("LOG",jump.putExtra("Mobile",strmobile).toString());
}else if(v.getId()==R.id.buttonmobileremove)
{
llmobile.removeView(findViewById(R.id.editTextmobile));
}else if(v.getId()==R.id.buttondone)
{
Log.d("LOG","1");
startActivity(jump);
}
}
}
FrameLayout.java
public class Framelayout extends Activity implements OnClickListener {
FrameLayout frameLayout;
Button b2,b3;
//private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_framelayout);
frameLayout = (FrameLayout)findViewById(R.id.f1);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.buttonload);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
}
public void onClick(View v) {
if(v.getId()==R.id.button2){
Intent i=new Intent(Framelayout.this,Hidden.class);
startActivity(i);
}else if(v.getId()==R.id.buttonload){
Log.d("Log",getIntent().getStringExtra("Name"));
editframelayout();
}
}
private void editframelayout() {
String name=getIntent().getExtras().getString("Name");
String mobile=getIntent().getExtras().getString("Mobile");
TextView tvname=new TextView(this);
tvname.setText(name);
tvname.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
tvname.setGravity(Gravity.CENTER);
TextView tvmobile=new TextView(this);
tvmobile.setText(mobile);
tvmobile.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
tvmobile.setGravity(Gravity.CENTER);
frameLayout.addView(tvname);
frameLayout.addView(tvmobile);
}
}
You must use one of putExtra() overloaded methods of the intent instance you created to add your data.
Here is a sample:
Intent intent = new Intent(this, SignoutActivity.class); // # this parameter is the context of the caller
intent.putExtra("PARAM_TEXTBOX_TEXT", textboxText);
startActivity(intent);
Edit for the code you added, your design is very poor and doesn't accomplish what is intended.
Every time you click a Button a new instance of Intent is created. you are calling startActivity() only in single case:
else if(v.getId()==R.id.buttondone)
{
Log.d("LOG","1");
startActivity(jump);
}
Now you assume that the parameters added in previous button clicks are still there, but they aren't. When you click buttondone you create a new instance of Intent with no extras at all.
You can work this around as follows:
...
else if(v.getId()==R.id.buttondone)
{
String strname = etname.getText().toString();
if (strname != null && !strname.equals(""))
{
jump.putExtra("Name",strname);
}
String strmobile = etmobile.getText().toString();
if (strmobile != null && !strmobile.equals(""))
{
jump.putExtra("Mobile",strmobile);
}
startActivity(jump);
}
It still isn't well structured, but might do the trick for you
Use getIntent().getStringExtra("Name") instead of getIntent().getExtras().getString("Name");
getIntent().getStringExtra("Name")
I am trying to figure out the best practice of communication between a TabActivity and the child activity embedded in this TabActivity.
In my TabActivity, there is a button. When the button is clicked, I want the child activity embedded in this TabActivity to be updated. I wrote the code like below, and just wonder whether it is a good practice. Thanks.
MyTabActivity.java
public class MyTabActivity extends TabActivity implements OnClickListener {
private TabHost m_tabHost;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ff_tab_activity);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
m_tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;
intent = new Intent().setClass(this, ChildActivity.class);
spec = m_tabHost.newTabSpec("Tab 1");
spec.setContent(intent);
tabView = (TextView) inflater.inflate(R.layout.tab_indicator, null);
spec.setIndicator(tabView);
m_tabHost.addTab(spec);
m_tabHost.setCurrentTab(0);
ImageView nextButtonIv = (ImageView) findViewById(R.id.next_button);
nextButtonIv.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.next_button:
synchronized (ChildActivity.class) {
if (null != ChildActivity.s_childActivity) {
ChildActivity.s_childActivity.changeUI();
}
}
break;
}
}
ChildActivity.java
public class ChildActivity extends Activity {
public static ChildActivity s_childActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
synchronized (MatchupsActivity.class) {
s_childActivity = this;
}
setContentView(R.layout.child_activity);
}
public void changeUi() {
code that changes UI
}
protected void onDestroy() {
super.onDestroy();
synchronized (MatchupsActivity.class) {
s_childActivity = null;
}
}
Since TabActivity is an ActivityGroup, I would use one of the following:
getCurrentActivity()
Returns the child tab activity being displayed. In your case, this method will return the instance of ChildActivity being used.
ChildActivity childActivity = (ChildActivity) getCurrentActivity();
getLocalActivityManager().getActivity(String)
Returns the child tab activity given its ID/tab spec name, whatever activity being displayed.
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
I suggest overriding onNewIntent(Intent) in your ChildActivity:
Intent intent = new Intent();
intent.putExtra("xyz", "whatever"); // or a serializable
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
childActivity.onNewIntent(intent);
Let me know if it works!
Seems fine. A couple of notes:
- I see no reason for synchronization.
- I'd replace
ChildActivity.s_childActivity.changeUI();
with
if(ChildActivity.s_childActivity != null){
ChildActivity.s_childActivity.changeUI();
}
or even
try{
ChildActivity.s_childActivity.changeUI();
} catch(Exception e){
//log
}
for added paranoid safety. :)
The way above with
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
childActivity.onNewIntent(intent);
is not very nice. Instead of invoking your activity method directly (it can be null!!!) better do it this way:
Intent intent = new Intent(this, ChildActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(AlbumBrowser.INTENT_EXTRA_FILTER, mediaTitle);
getLocalActivityManager().startActivity("activityIdHere", intent);
Couple of design issues with this, but overall it seems reasonable.
I would forgo the static instance in the ChildActivity class. Why? Well, think about the relationship you're modeling. A TabActivity has a ChildActivity. This is textbook composition, and would be accomplished by adding a ChildActivity field to the TabActivity class, like so:
public class TabActivity {
private ChildActivity child;
//remember to initialize child in onCreate
//then, call methods using child.changeUI();, for example
}
This is better, because A) now I can have multiple instances of TabActivity and ChildActivity that won't interfere with each other (before, it was just a static variable, so only one ChildActivity could be used), and B) the ChildActivity is encapsulated inside the TabActivity class... before, it was a public field, meaning anything can use and modify it (might not be desirable; can often lead to some strange runtime bugs as well as messy, tied-together code) - we changed it to a private field, because we don't really want other classes accessing it in unexpected ways.
The only thing you may need access to from the ChildActivity is the parent (TabActivity). To do this, add the following methods and field to the ChildActivity class, and call the registerParent() method after constructing the ChildActivity:
public class ChildActivity ...{
private TabActivity parent;
public void registerParent(TabActivity newParent){
if (newParent != null){
parent = newParent;
}
}
}
So, if you need access to the parent TabActivity from the child, just call parent.someMethod();
It would also be wise to access fields like parent and child through getters and setters; it might save you some time in the long run.
You can use getParent() to obviate the need to do any of this.
Here's my launcher child class with buttons that switch between activities handled by the tabHost:
public class LaunchPadActivity extends Activity implements OnClickListener {
private static final int ICON_PROFILE = 0;
private static final int ICON_SEARCH = 1;
private static final int ICON_MAP = 2;
private static final int FAVOURITES = 3;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.launchpad);
GridView launchPad = (GridView) findViewById(R.id.launchpad);
launchPad.setAdapter(new LaunchIconAdapter(this));
}
public class LaunchIconAdapter extends BaseAdapter {
private Context mContext;
// references to our images
private Integer[] mThumbIds = { R.drawable.user, R.drawable.find,
R.drawable.map, R.drawable.favourites, R.drawable.reviews,
R.drawable.news, R.drawable.tutorial, R.drawable.info,
R.drawable.options, };
public String[] texts = { "Profile", "Search", "Map", "Favourites",
"Reviews", "News", "Tutorial", "Info", "Options" };
public LaunchIconAdapter(Context c) {
mContext = c;
}
// Number of thumbs determines number of GridView items
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
// Icon elements
LinearLayout launchIcon;
ImageView launchImage;
TextView launchText;
if (convertView == null) {
launchIcon = (LinearLayout) ((LayoutInflater) mContext
.getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(
R.layout.launchicon, null);
} else {
launchIcon = (LinearLayout) convertView;
}
// Add ClickListener with metadata
launchIcon.setTag(new Integer(position));
launchIcon.setOnClickListener(LaunchPadActivity.this);
// Get subviews
launchImage = (ImageView) launchIcon
.findViewById(R.id.launch_image);
launchText = (TextView) launchIcon.findViewById(R.id.launch_text);
// Configure subviews
launchImage.setImageResource(mThumbIds[position]);
launchText.setText(texts[position]);
return launchIcon;
}
}
#Override
public void onClick(View v) {
int position = ((Integer) v.getTag()).intValue();
switch (position) {
case ICON_PROFILE:
Toast.makeText(this, "Profile", Toast.LENGTH_LONG).show();
break;
case ICON_SEARCH:
Toast.makeText(this, "Search", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(1);
break;
case ICON_MAP:
Toast.makeText(this, "Map", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(2);
break;
case FAVOURITES:
Toast.makeText(this, "Map", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(3);
break;
}
}
}
Works like a charm.