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.
Related
I'm new Android programming. Earlier I was working with activities, where i could implement onClick on an ImageButton and go to a different activity.
Now I need to do the same but using Fragments. I have a prototype with a menu that always appear on screen and can show different activities to the user. The different lactivities would be inside this container.
Now I want to place an ImageButton inside a fragment and make that the screen shows the next fragment. But I'm confused how to do it.
I have the following components:
Activity_main(java)+activity_main.xml (with menu)
Fragment1(java)+fragment1.xml(working normal)
Inside this layout I have an ImageButton and want to show Fragment2
Fragment2(java)+fragment2.xml
How should look Fragment1 to can call Fragment2?
I will be glad if the answer could be the clearest possible because I'm new on it, and maybe I could forgot an obvious step. Thanks
Simply make a method in your activity which will always change/replace fragment when you invoke it. something like
public void updateFragment(Fragment fragment){
//add fragment replacing code here
}
in your fragment, invoke it some thing like this
((YourActivity)getActivity()).updateFragment(new YourFragment());
since, it is just an idea which works fine but still you can improve the logic.
Actually, going from one fragment to another is almost similar to going from one activity to another. There are just a few extra lines of code.
First, add a new Java class named SingleFragmentActivity which would contain the following code-
public abstract class SingleFragmentActivity extends AppCompatActivity
{
protected abstract Fragment createFragment();
#LayoutRes
protected int getLayoutResId()
{
return R.layout.activity_fragment;
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(getLayoutResId());
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null)
{
fragment = createFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
}
}
}
Make your activities in the following format-
public class SomeActivity extends SingleFragmentActivity
{
#Override
protected Fragment createFragment()
{
return SomeFragment.newInstance();
}
}
And your fragments like this-
public class SomeFragment extends Fragment
{
public static SomeFragment newInstance()
{
return new SomeFragment();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_some, container, false);
return v;
}
}
After this everything has the same code as you have for activities except for one small detail which is your onCreateView(LayoutInflater, ViewGroup, Bundle) class. This is how you would write it-
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_some, container, false);
mTextView = (TextView)v.findViewById(R.id.some_text);
mButton = (Button)v.findViewById(R.id.some_button);
mTextView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
check();
}
});
return v;
}
And that is it!
Hi i hope you are already aware about the fragments and their uses but still here is a brief. They are child to an activity and an activity can have more than one fragment so you can update your layout without changing activity just by changing fragments.
You can found more on fragment here : https://developer.android.com/training/basics/fragments/index.html
Back to the original problem, supposed you are in MainActivity.java and you want to load fragment in it, so you do this to load fragment first time.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame, new Fragment1);
transaction.addToBackStack(null);
transaction.commit();
You will need this method to change fragment from another fragment, so add this in your MainActivity
public void changeFragment(Fragment fragment){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame, new Fragment1);
transaction.addToBackStack(null);
transaction.commit();
}
Now from a button click in this fragment
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity)getActivity()).changeFragment(new Fragment2);
}
});
Hope it will help!
I want to know how to show and hide a fragment on a button click in Android. When button is in clicked state then fragment should appear, and when the button is clicked again then the fragment should disappear.
I tried this and it worked for me. First I added the fragment when button is clicked for first time and then on subsequent clicks I attached and detached it. So it created the fragment and then without destroying it only showed and hid it.
this is the code.... Initially count is 0 when the MainActivity is first created
public void Settings(View view){
if(count==0){
count++;
// add a fragment for the first time
MyFragment frag=new MyFragment();
FragmentTransaction ft=manager.beginTransaction();
ft.add(R.id.group,frag,"A");
ft.commit();
}else{
//check if fragment is visible, if no, then attach a fragment
//else if its already visible,detach it
Fragment frag=manager.findFragmentByTag("A");
if(frag.isVisible() && frag!=null){
FragmentTransaction ft=manager.beginTransaction();
ft.detach(frag);
ft.commit();
}else{
FragmentTransaction ft=manager.beginTransaction();
ft.attach(frag);
ft.commit();
}
}
You should use Dialog fragment for this purpose. Dialog Fragment has all life cycle as fragment has and has behavior like dialog.
For example to show, simply call dialogFragment.show() method, and to hide, call dialogFragment.dismiss() method.
Here is an example how to make a dialog fragment.
public class DialogFragmentExample extends DialogFragment{
#Override
public void onStart() {
super.onStart();
// To make dialog fragment full screen.
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
//
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
return inflater.inflate(R.layout.your_xml_layout, container, false);
}
// initialize your views here
}
And to show this dialog fragment;
DialogFragmentExample fragment = new DialogFragmentExample();
fragment.show();
similarly to dismiss,
fragment.dismiss();
Hope this will help you!
Fragment Transaction's internal show/hide flag will help.
FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.show(somefrag) //or hide(somefrag)
.commit();
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");
I have an application that is using fragments. The set up is like so:
Main Activity loads, loads fragment activity into right portion of parent activity
-From the Fragment, I launch a DialogFragment which displays a list of users
-From the DialogFragment, if you click on one of the users in the list, it hides the list of users DialogFragment .hide() and shows a new DialogFragment containing the details about the user
This all works great. However, when I click the Close button on the Details DialogFragment, I'd like to dismiss() that dialog, and re-show the List of Users dialog.
I realize this is somewhat difficult to follow.
Does anyone have any insight that may help me?
UPDATE
The code I use to display the DialogFragment is the following:
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(getFragmentManager(), "MyDialogFragment");
Then once in the dialog fragment, if I wanted to hide it and show the details fragment I call
dialog.hide();
MyDetailsFragment details = new MyDetailsFragment();
details.show(getFragmentManager(), "MyDetailsFragment");
Basically I need to be able to re-show the dialog above when I dismiss the details.
When a fragment transaction is performed, you can add it to the back stack which can be reversed on dismissing the dialog.
Begin a fragment transaction and use the DialogFragment.show(FragmentTransaction transaction, String tag) variant which takes the FragmentTransaction as parameter. It will take care of showing the Dialog, adding the fragment to the passed transaction and then committing the transaction. Later when the Dialog is dismissed, DialogFragment will itself take care of popping the transaction.
You can follow the first sample posted in the DialogFragment docs.
Here is the working code:
public void launchMyDialog(View v) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("mydialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(ft, "mydialog");
}
public static class MyDialogFragment extends DialogFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
Button b = (Button) v.findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("mydialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
MyDetailsFragment dialog = new MyDetailsFragment();
dialog.show(ft, "mydialog");
}
});
return v;
}
}
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.