The Fragment is part of a Tabbed Activity. I was able to succesfully modify the Tabbed Activity template of Android Studio 2.1.2. Now I have changed it to the point where all the Fragments inside it have a FAB of their own. When Floating Action Button is clicked it is supposed to show a dialog. I have created a DialogFragment following the instruction from the official docs. The FAB uses setOnClickListener to refer to the method in the java file. I can't use
newEdQua.show(getSupportFragmentManager(), "createNewEdQua")
to show the dialog. it says it cannot resolve it
I also noticed that it won't load the ListView with the content of the Stinrg Array.
In summary I want to show a dialog from a Fragment(thats part of Tabbed Activity).
I have tried to clean and rebuild, sync gradle files with project. I dont want to mess with IDE configuration files. At least not now cause I'm far into a very important project(so suppressing warnings is not an option).
This is my code. It includes only areas with problem.
Dialog Fragment (to be shown):
public class createNewEdQua extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle saveSavedInstanceState){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.createnewEdQua);
builder.setMessage("New Qualification HERE!!");
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return builder.create();
}
}
Fragment (placed as tab in Tabbed Activity):
public class edSET_Dashboard_Teachers extends Fragment {
FragmentManager fm;
//neInstance() method return reference to fragment
public static edSET_Dashboard_Teachers newInstance(){
edSET_Dashboard_Teachers fragment = new edSET_Dashboard_Teachers();
return fragment;
}
public edSET_Dashboard_Teachers() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//following code is in public View onCreateView() method
String[] edqua={"Conten Here","Contend Here","Content Here"};
//had to use this cause findViewById() method was not working as it should
View view = inflater.inflate(R.layout.fragment_edset__dashboard__teachers, container, false);
ArrayAdapter<String> listOfEdqua2 = new ArrayAdapter<String>(getContext(), R.layout.list_item_edqua, edqua);//i tried using this as the context but error
ListView listView = (ListView)view.findViewById(R.id.edu_info);
listView.setAdapter(listOfEdqua2);
//had to use setOnClickListener cause android:onClick in xml does not work with Fragments ive learned
FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab_edset);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DialogFragment newEdQua = new createNewEdQua();
newEdQua.show(getActivity().getFragmentManager(), "createNewEdQua");
//addEdQua(view);
}
});
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_edset__dashboard__teachers, container, false);
}
//the method to show the dialog
/*
public void addEdQua(View view){
}*/
}
When I run it on a real device while connected to my computer, and I tap the FAB nothing at all happens, no crash no error nothing.
I figured it out
return inflater.inflate(R.layout.fragment_edset__dashboard__teachers, container, false);
should be
return view;//it already inflates the Fragment layout
you are reinflating new view
First declare a FragmentManager variable:
FragmentManager fm;
Then initialise it
fm = getFragmentManager();
then call it wherever you want..
createNewEdQua dialogFragment = new createNewEdQua ();
dialogFragment.show(fm, "Your title");
Related
What I ought to do is change the view/layout of Fragment without creating another class for fragment on click of a button.
For example I have an activity - ContactsActivity and I have a fragment - ContactsFragment.
The Standard way of using Fragments:
From ContactsActivity I call ContactsFragment by -
getFragmentManager().beginTransaction().replace(android.R.id.content, new ContactsFragment())
.commit();
Code for setting View in ContactsFragment class -
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.contacts_primary, container, false);
return rootView;
}
**Now comes how I do what I want to do ** (Change the view of fragment)
I change only the view of ContactsFragment by doing a bad kind of hack.
I change the onCreateView() shown above to this -
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
//Set the view to R.layout.contacts_primary
rootView = inflater.inflate(R.layout.contacts_primary, container, false);
//Set the view to R.layout.contacts_secondary
if(getActivity().getIntent()!=null && getActivity().getIntent().getBooleanExtra("s", false)) {
rootView = inflater.inflate(R.layout.contacts_secondary, container, false);
Log.e(tag,getActivity().getIntent().getExtras().toString());
return rootView;
}
//This is the onClickListener which again calls the ContactsActivity class,
//this time with an Intent which I used above to change the view from
//R.layout.contacts_primary to R.layout.contacts_secondary
Button button = (Button)rootView.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getActivity(), ContactsActivity.class).putExtra("s",true));
}
});
Now everything works as I want and flawlessly.
But I have a very strong feeling that either all of it is wrong and Fragments aren't supposed to work this way or I am using a hectic hack to achieve what can be done by few lines of code.
So please let me know what is it? And if there is a standard way of doing what I am trying to do.
For me passing additional argument on which base fragment decides wich layout to use seems totally ok. But there is cleaner way of doing what you want to achieve without starting another activity.
First of all pass argument to fragment by making standard static new instance method in fragment (we cannot pass this argument in constructor as android always recreates fragments using empty constructor). Something like this:
public static ContactsFragment newInstance(boolan firstView) {
ContactsFragment fragment = new ContactsFragment();
Bundle args = new Bundle();
args.putBoolean("yourArg", firstView);
fragment.setArguments(args);
return fragment;
}
Every time you have to initiate your fragment do this with this method.
Then declare interface in your fragment to communicate with your activity. Like this
public interface NewViewListener {
public void showNewView(boolen firstView);
}
Than make your activity implement it so your activity han a method where it can place new fragment in container view. In your fragments onAttach and onDetach methodsmake sure your activity implements this interface and hold reference to your activity in private NewViewListener field in your fragment. Like this:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (NewViewListener ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement NewViewListener ");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
Then in on button click method call showNewView method on your activity with whatever argument you want indicating which view you want in new fragment instance. And in your activity method showNewVew fragment in the container. Like this:
#Override
public void showNewView(boolean firstView) {
getFragmentManager().beginTransaction().replace(android.R.id.content, ContactsFragment.newInstance(firstView)
.commit();
}
In your fragments onCreateView you may get passed arguments and decide which view you want to use.
I have a view pager that has 3 fragments inside.
However, the first fragment has a listview.
I want to open a new fragment when I click on a ListView item.
I was able to make it work succefully with this code:
Fragment FullBrand = new FullBrand();
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.replace(R.id.framebrands, FullBrand);
Bundle bundle = new Bundle();
FullBrand.setArguments(bundle);
ft.addToBackStack(null);
ft.commit();
However, when the new fragment launches, the viewpager is still there!
What to do? how can I get rid off them??
Thanks!
Seems like you're trying to replace one fragment inside the view pager.
If you want to replace the view pager fragment (with it's 3 child) and to show other fragment you need to call the transaction in the FragmentActivity and replace it in the current container.
Add callback to the activity and replace the whole container in the activity when listview item clicked.
Example to add listener
in view pager fragment, declare your interface:
public interface OnViewPagerClickListener {
public void onBlaBla(Object arg);
}
in your Fragment Activity:
public class MyFragmentActivity implement ViewPagerFragment.OnViewPagerClickListener
in your view pager fragment override onAttach & declare interface member
private OnViewPagerClickListener mCallback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallback =(OnViewPagerClickListener) activity **try catch this code**
}
And wherever you want call the mCallback.onBlaBla(...)
and do the rest in the activity....
This is very summarize lesson for interfaces :)
More info about interface and callback here
Good luck.
You shouldn't try to remove the ViewPager instead better you can show the new Fragment (i.e FullBrand) in a DialogFragment . so If you click back it will bring you to old ViewPager only, it won't exit the app
To show a Dialog Fragment with FullScreen try the following code:
public class NewFragment extends DialogFragment {
private Dialog dialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.new_fragment_xml_here, container,
false);
return view;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
dialog = new Dialog(getActivity(),
android.R.style.Theme_Black_NoTitleBar);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
Then call this NewFragment from your ListView item click to show this as NewScreen which will look like a new screen:
NewFragment fragment = new NewFragment();
fragment.show(fragmentManager, "NewFragment");
I hope it would help you.
I have a few Actiobar with 5 tabs each with a fragment. In 3 of this fragments I want to show a Dialog so I've created a new class:
public static class MyDialogFragment extends DialogFragment {
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
static MyDialogFragment newInstance() {
return new MyDialogFragment();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int style = DialogFragment.STYLE_NORMAL;
int theme = android.R.style.Theme_Holo_Dialog;
setStyle(style, theme);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_dialog, container, false);
View tv = v.findViewById(R.id.textV);
((TextView)tv).setText("Dialog using style Normal - Theme AlertDialog - NoActionBar");
return v;
}
}
In every onCreate method of this 3 fragments I'm trying to show the Dialog by using this method:
private void showPopup()
{
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
DialogFragment newFragment = MyDialogFragment.newInstance();
newFragment.show(ft, "dialog");
}
Now the problem is that this dialog is displayed on tabs that should not.
For example I want tabs 1 3 and 5 to display the Dialog - and sometimes it displays it - but sometimes when I tap the tab 2 this dialog appears and if I tap 3 the Dialog is not showed.
What could be the problem and how should I fix it? Thanks
Have you try to move your showPopup() call in onCreateView() or in onActivityCreated() methods, instead of in onCreate() one ?
EDIT: According to comments below, the problem is linked to the use of a ViewPager, which prepare some next Fragments to be viewed, and then call onCreate() methods.
So I've found a solution - in every fragment I override a method called setMenuVisibility - and test if the the fragment is visible. If it is - I call my method.
First time posting here and also a new developer for Android Apps.
Desire Function of Example App:
1) Activity starts in fullscreen A
2) Fragment B then populates/inflates container of A fullscreen
3) Fragment B has a button, button is press
4) Fragment B is now replaced with Fragment C
5) Fragment C is now full screen and has data that is inputted by users, user then hits button to send to next Fragment
6) Fragment C is replaced with Fragment D and presents data to view which was inputted from Fragment C
Summary Functionality:
I am trying to keep everything on one screen going from
A (Activity) -> B (Fragment replace) -> C (Fragment replace to type data) -> D (Fragment replace and see last fragment data)
Problem/Issue
My code crashes when I try to populate the last screen with data obviously. It seems to throw an error in MainActivity at this specific line when I debug it
CartFragmentCode addCartInfoTextFragment = (CartFragmentCode) getSupportFragmentManager().findFragmentById(R.id.maincontainer);
I am definitely passing the values correctly through the interface I created, but during the debug process, I found out that my current program is trying to populate information into the same container since it seems like it didn't commit yet to replace the fragment to assign the variables to the right UI.
I was checking if I was able to replace the Fragment C with D, and I was able to only if I remove that above line of code.
Code Below
Main
public class MainActivity extends FragmentActivity implements OrderFragmentCode.FragUIListeners{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment AllMenu = new AllMenuFragmentCode();
FragmentManager fragManager = getSupportFragmentManager(); //getSupportFragmentManager setup
FragmentTransaction ft = fragManager.beginTransaction(); //setup fragmentTranscation = ft
ft.add(R.id.maincontainer, AllMenu);
ft.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onCartButtonClicked(String editFood, String editType, String editName){
CartFragmentCode addCartInfoTextFragment = (CartFragmentCode) getSupportFragmentManager().findFragmentById(R.id.maincontainer);
addCartInfoTextFragment.UpdateCartTexts(editFood, editType, editName);
}}
Fragment A
public class AllMenuFragmentCode extends Fragment implements OnClickListener {
private Button Order;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.all_menu_fragment, container, false);
Order = (Button) view.findViewById(R.id.orderButton);
Order.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
Fragment OrderFragmentCode = new OrderFragmentCode();
FragmentManager fragManager = getFragmentManager(); //getSupportFragmentManager setup
FragmentTransaction ft = fragManager.beginTransaction(); //setup fragmentTranscation = ft
ft.replace(R.id.maincontainer, OrderFragmentCode);
ft.addToBackStack(null);
ft.commit();
}}
Fragment C
public class OrderFragmentCode extends Fragment implements OnClickListener {
FragUIListeners activityCallback;
public interface FragUIListeners {
public void onCartButtonClicked(String foodText, String typeText, String nameText);
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
activityCallback = (FragUIListeners) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement FragUIListeners");
}
}
private EditText editTextFood;
private EditText editTextType;
private EditText editTextName;
private Button AddToCartButton;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.order_fragment, container, false);
editTextFood = (EditText) view.findViewById(R.id.editText);
editTextType = (EditText) view.findViewById(R.id.editText2);
editTextName = (EditText) view.findViewById(R.id.editText3);
AddToCartButton = (Button) view.findViewById(R.id.addToCart);
AddToCartButton.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
Fragment Cart = new CartFragmentCode();
FragmentManager fragManager = getFragmentManager();
FragmentTransaction ft = fragManager.beginTransaction();
ft.replace(R.id.maincontainer, Cart);
ft.addToBackStack(null);
ft.commit();
activityCallback.onCartButtonClicked(editTextFood.getText().toString(), editTextType.getText().toString(), editTextName.getText().toString());
}}
Fragment D
public class CartFragmentCode extends Fragment{
private TextView foodView;
private TextView typeView;
private TextView nameView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.cart_fragment, container, false);
foodView = (TextView) view.findViewById(R.id.foodView);
typeView = (TextView) view.findViewById(R.id.typeView);
nameView = (TextView) view.findViewById(R.id.nameView);
return view;
}
public void UpdateCartTexts(String editfood, String edittype, String editname)
{
foodView.setText(editfood);
typeView.setText(edittype);
nameView.setText(editname);
}}
--Final Say--
Sorry for the long post, this has been bugging me for HOURS and I even tried to use bundles and setting the arguements but I wasnt able to get that working either (I thought if i were able to obtain values correctly I could work around and use this to assign values to my textviews through getArguments on my last Fragment).
Please help!!!! Thanks!!!
In the line CartFragmentCode addCartInfoTextFragment = (CartFragmentCode) getSupportFragmentManager().findFragmentById(R.id.maincontainer);
findFragmentById sholule be passed that you use as 2nd argument in add while adding fragment to container for e.g. ft.add(R.id.maincontainer, AllMenu); if you want to get this fragment then you use findFragmentById(AllMenu) which is the tag that is associated with the fragment. R.id.maincontainer is the container in which that fragment is being displayed.
I guess the problem is you call onCartButtonClicked inside fragment C (where fragment C still exist) so the fragment D isn't created and take C place yet.
Try to call onCartButtonClicked by a Handler in your MainActivity
This is was one of my resource at the time to mimic a solution (he was using two fragments in one activity, while my app is trying to use one activity and replacing the main framelayout): http://www.techotopia.com/index.php/Using_Fragments_in_Android_-_A_Worked_Example
After playing around with example codes and using the available documentations. I cannot use these two lines to transfer the information as suggested in my MainActivity:
CartFragmentCode addCartInfoTextFragment = (CartFragmentCode) getSupportFragmentManager().findFragmentById(R.id.maincontainer);
addCartInfoTextFragment.UpdateCartTexts(editFood, editType, editName);
I think I finally found a workaround or a solution? I am not sure if this is the correct way of passing information to fragments or other classes, but here it is...
I basically Took away those two lines and rework my MainActivity's Click method and changed it to this...
public void onCartButtonClicked(String editFood, String editType, String editName){
CartFragmentCode.passFood = editFood;
CartFragmentCode.passType = editType;
CartFragmentCode.passName = editName;
}
I then went to my last fragment Code which was OrderFragmentCode.java and declared my Strings to retrieve them at the top of the Class and they were...
public static String passFood;
public static String passType;
public static String passName;
I then took the those values and setText them to my textViews. Wallah! It works as intented, however I am not sure if this is the right way to do things... If you guys are able to find a more professional way to handle data across multiple fragments, please let me know!
I am trying to implement fragment communication in android like the one in the android guide http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
but my application is crashing as the getSupportFragmentManager().findFragmentById() returns null. What is the issue with my implementation.
The code is given below:
The program is just to send an input text from one fragment to another fragment textView area through a button click from first fragmnet.I have an activity_main.xml and two fragment layout (two separate xml files rather than part of in activity_main.xml)
Frag1.java
public class Frag1 extends Fragment {
public Frag1(){
}
buttonClickListener buttonListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
buttonListener = (buttonClickListener) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnButtonPressListener");
}
}
View myFragmentView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.frag1, container, false);
//SetValue Button
Button setValueButton = (Button) myFragmentView.findViewById(R.id.setValueButton);
setValueButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
buttonListener.onButtonPressed("Message received");
}
});
return myFragmentView;
}
}
Frag2.java
public class Frag2 extends Fragment {
View myFragmentView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.frag2, container, false);
return myFragmentView;
}
void setMessage(String msg){
TextView txt=(TextView)myFragmentView.findViewById(R.id.textView1);
txt.setText(msg);
}
}
buttonClickListener.java
public interface buttonClickListener {
public void onButtonPressed(String msg);
}
MainActivity.java
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener, buttonClickListener {
SectionsPagerAdapter mSectionsPagerAdapter;
#Override
public void onButtonPressed(String msg) {
// TODO Auto-generated method stub
Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.layout.frag2);
fragmentObj.setMessage(msg);
}
Please tell me where did I go wrong?
EDIT:
I am using fragment creation using the template generated by Android Plug-in eclipse IDE.
So the fragments are created using android.support.v4.app.Fragment
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch(position)
{
case 0:
return new Frag1();
case 1:
return new Frag2();
}
return fragment;
}
The codebase is kept here for reference
https://skydrive.live.com/redir?resid=D37E0F56FEC9B499!259
Try This it works for me How to put Google Maps V2 on a Fragment Using ViewPager
<fragment
android:id="#+id/map"
android:layout_width="wrap_content"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
You should have added the fragment Frag2 by calling
getSupportFragmentManager().beginTransaction().add(R.id.frag2_view, new Frag2(), "tag").commit();
at your MainActivity, where R.id.frag2_view is a layout defined in your main_layout.
To get that Fragment, you should then call
Frag2 obj = (Frag2)getSupportFragmentManager().findFragmentById(R.id.frag2_view);
passing the layout id you used to add the fragment in the main_layout.
Hope it helps.
EDIT:
Since you use a ViewPager, you should use R.id.pager as the ID.
I just tried with your example and it worked.
Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.id.pager);
EDIT 2:
Despite it worked, I don't really think this is the correct way, since R.id.pager its from ViewPager and you can't find, let's say, frag4 or frag5.
Ignore my answer please. I'm not sure how to do that with ViewPager, sorry.
I was having a similar problem and here is the solution.
To get the reference to the proper fragment inside the viewpager just call:
getSupportFragmentManager().findFragmentByTag(tag);
The tag param you can build it using the following syntax: "android:switcher:pager_id:index", where pager_id is the id of the ViewPager in the XML layout and the index is the position of your fragment inside the ViewPager starting by zero. See the original response here: https://stackoverflow.com/a/7393477/2423274
Found the right solution for this question.
Hope more people see this.
Frag2 fragmentObj=(Frag2) mSectionsPagerAdapter.getItem(2);
You should use your Adapter (where you populate your fragments) as a source for get the Fragment reference.
I used this to get a child fragment from a fragment adapter...
Fragment parent = MainActivity.this.getSupportFragmentManager().findFragmentById(R.id.main_container);
if (parent instanceof PagerFragment) {
// do something with parent
Fragment child = ((PagerFragment) f).adapter.getItem(childPosition);
}