Android - how to place one fragment on another - android

I am looking for a hint/way how to achieve such a "layout" in android. What I have so far is layout of mainActivity, on which is embedded fragment A. What I wanna do, is place above fragment A next one (Fragment B). For better illustration image is included.
How should I implement such a composition ? Also, after click on "Save" it should process inserted information a fragment should be hidden/removed.
Thanks in advance

You can use DialogFragment. You may refer to this or this tutorial

Create layout (your editview and button), e.g. fragment_register_account.xml
Inflate the layout in a class e.g. RegisterAccountDialog that extend DialogFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register_account, container);
mEditText = (EditText) view.findViewById(R.id.txt_your_name);
getDialog().setTitle("Hello");
return view;
}
3.Register onClick to your 'Create new Account' button and show the DialogFragment.
FragmentManager fm = getSupportFragmentManager();
RegisterAccountDialog dialog = new RegisterAccountDialog();
dialog.show(fm, "fragment_edit_name");
A good tutorial here

Related

Changing DialogFragment Layouts while dialog is open

I have an Android Activity, from which I want to show a Dialog. It would probably be a custom DialogFragment. Now when the user clicks on specific buttons I want the layout's inside the dialog to change with the data from the previous DialogFragment and so that it would have an ability to also go back to previous Layout.
I dont think there is an easy way to change views inside of the same DialogFragment so what would be the best way to do this?
I have tried doing it in method onViewCreated and when a button is clicked, but nothing happens.
In my activity I call the fragment like this at the moment:
FragmentManager fm = getSupportFragmentManager();
NewDialog newDialog = NewDialog.newInstace(userId, loc, currentId);
newDialog.setNewClickListener(new NewDialog.OnNewClickListener() {
#Override
public void onCancelClicked() {
finishAdd();
}
#Override
public void onAcceptClicked() {
...
}
});
newDialog.show(fm, "new_frag");
And the fragment:
public class NewDeliveryPointDialog extends DialogFragment {
private LayoutInflater inflater;
private ViewGroup container;
public NewDialog(){
}
public static NewDialog newInstace(){
...
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
this.inflater = inflater;
this.container = container;
return inflater.inflate(R.layout.dialog_layout_1, container);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
saveButton.setOnClickListener(v -> {
View.inflate(getContext(), R.layout.dialog_layout_2, container);
view.invalidate();
view.refreshDrawableState();
}
});
}
}
A DialogFragment is not made to have navigation to other fragments within the same dialog.
You basically have these options:
On your button click you close the Dialog and open another Dialog. But this seems odd. If there is so much happening, probably dialogs are not the best shot.
Instead of DialogFragments have another fragment container overlaying the original one (basically what a Dialog fragment does for you). Within the second container you can easily navigate to other fragments and set it to gone when the user finished interaction.
If there are just a few Views in the Dialog, you could consider setting the old ones to gone and the new ones to visible
I think your code didn't work, because container is null. Method onCreateView gives you #Nullable ViewGroup container, which is null for DialogFragment (but non null for Fragment). So when you call View.inflate(getContext(), R.layout.dialog_layout_2, container), it just creates a view in memory and doesn't attach it to container, cause it is null. See LayoutInflater.inflate, cause View.inflate is just a convenience wrapper for this function.
I dont think there is an easy way to change views inside of the same DialogFragment so what would be the best way to do this?
Instead of changing dialog root you can just manipulate child views inside dialog root layout (add, remove them, or change visibility).
Also my advice is to use recommended way to create dialog with custom layout (onCreateDialog + setView), but if you don't want to do that, you can refer view you've created in onCreateView as dialog root.
You can try creating a dialog fragment with an empty shell layout in which you would replace your two different fragments with ChildFragmentManager and regular fragment transactions
passing data between them can be done using the activity's view model since they both live in the same activity.
So add the ShellDialogFragment using the activity's FragmentManager and in the shell fragment class change between NewDialog & NewDeliveryPointDialog on your button click listener with ChildFragmentManager

Android DetailsFragment transitions on DialogFragment do not work

I am following android tv tutorials from here:
Now I am stuck on DetailsFragment. In these demos is DetailsFragment set like a content of VideoDetailsActivity. When I start this new activity from main activity then I see nice animations(or transitions) belong to DetailsFragment.
But, In my case, I really won't go away from the main activity. I want to stay there. So I created DialogFragment and I set DetailsFragment like its content.
However, I can't get work these animations (transitions). Detail is shown, but there are none transitions.
The original example creates Bundle object and sets it like a second parameter for startActivity of activity which holds DetailsFragment. Seems that's the key to getting work transitions. See:
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
((ImageCardView) itemViewHolder.view).getMainImageView(),
VideoDetailsActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
But how to do it for DialofFragment? I tried to create the same Bundle object and then I set it this way for DialogFragment:
fragmentDialog.setArguments(bundle);
fragmentDialog.show(getSupportFragmentManager(),"DetailsDialog");
But it won't work. I debugged DetailsFragment and in this way appropriate callbacks for onEntranceTransitionPrepare, onEntranceTransitionStart, onEntranceTransitionEnd are not called.
Then I tried to set the shared element in onCreateView of my FragmentDialog:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.details, parent, false);
detailFragment = new MyDetailsFragment();
((ImageCardView) itemViewHolder.view).getMainImageView().setTransitionName("transitionName");
getChildFragmentManager().beginTransaction()
.add(R.id.container, detailFragment)
//.addToBackStack(createItemFragment.TAG)
.addSharedElement(((ImageCardView) itemViewHolder.view).getMainImageView(), "??? what here")
.addToBackStack("ProfileMenuFragment")
.commit();
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
return view;
}
Now are callbacks called, but I still don't see transitions... Truly, I do not know what should I place like a parameter for setTransitionName of my card view or second parameter for addSharedElement. Maybe that's problematic. ItemViewHolder is shared element between two fragments (item of browsefragment and MyDetailsFragment).
If it can't work with DialogFragment then I can switch browsefragment and MyDetailsFragment on the same activity. But I really want these animations and I must stay on the same activity
Can someone help me?
EDIT :
I try to replace browsefragment and MyDetailsFragment with this code, but transitions are still not displayed.
if (detailFragment == null) {
detailFragment = new MyDetailsFragment();
}
ImageView logo = ((ImageCardView) itemViewHolder.view).getMainImageView();
logo.setTransitionName("transitionName");
context.getFragmentManager()
.beginTransaction()
.addSharedElement(logo, logo.getTransitionName())
.replace(android.R.id.content, detailFragment, "MyDetailFragment")
.addToBackStack("MyBrowseFragment")
.commit();
I set manually logo.setTransitionName because else it crashes. I think this is not correct way. DetailsFragment contains all transitions what I want. I must only somehow start them

Fragment button not opening new activity

I've incorporated a horizontal slide navigation component (which required making the class extend Fragment). The slide part works fine. Here i have respective onClick() buttons which open a new activity. If I add a button into one of those activities I'm not finding a way to have the displayed activity subsequently refresh. I would think inflating an activity from a button within a fragment would be possible but anything I try stops the emulator.
There's not much to my code so far, so I'm not going to clutter my question with the associated layout part. Any help is certainly appreciated.
Fragment #1’s Java code
public class TasksFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tasks, container, false);
Button ID = (Button) rootView.findViewById(R.id.button_create_appraisal_rpt);
ID.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AppraisalReportActivity appraisalRptAct = new AppraisalReportActivity();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.child_fragment, appraisalRptAct);
fragmentTransaction.setTransition(fragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return rootView;
}
}
Fragment #1 (portion), which has the button that should initiate aa refresh of this Fragment #1 with Fragment #2
Fragment #2 that's to supersede/refresh the previous fragment when Fragment #1's button is clicked
I don't really understand what you mean. Do you want to click Button in Fragment to jump to another Activity?
If it is,I think maybe you can try use getActivity() to make Activity are working.
for example:
getActivity().startActivity(new Intent(getActivity(),Activity.class))
I hope my answer will help you

Referring to Views from different Fragments in same Activity

Let say the target application is built from 3 fragments which are all in the same activity public class MainActivity extends android.support.v4.app.FragmentActivity implements ActionBar.TabListener. Starting fragment is public class ButtonSectionFragment extends Fragment where there is a Button:
public class ButtonSectionFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.btn, container, false);
Button mybutton = (Button) rootView.findViewById(R.id.mybutton);
mybutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
????????????????????
}
});
}
There are ?? in the onClick method, I will get to that. And there is another fragment like this:
public static class TextSectionFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tv, container, false);
TextView textv = (TextView) rootView.findViewById(R.id.texty);
}
Both of the fragments are using different layouts so this is why rootView is being used right in front of findViewById.
The outcome I would like to achieve is: by Button from 1st fragment click set the TextView from 2nd fragment to Hello. What should I put in the ??? part to make it all work?
You need to use interface as callback to the activity then set the textview in fragment.
Two framgents should never communicate directly.
http://developer.android.com/training/basics/fragments/communicating.html.
Framgent1 -->Activity -->Fragment2.
You can comunicate value from fragment2 to activity first then from activity to fragment2. Then set text in fragment2
You just have to use getActivity().findViewById() instead of getView().findViewById()
final TextView tv = (TextView) getActivity().findViewById(R.id.texty);
if (tv != null)
tv.setText("Hello");
Fragments are just branches inside the common layout tree of activity. All fragment views of a common activity can be accessed through Activity.findViewByXXX(). The only complication is that fragments can be dynamically added, removed, replaced, etc. So you to be sure that the needed fragment is already inflated into the layout hierarchy. You can make initialization of the UI in onViewCreated() of the other fragment. That guarantees you the layout has been loaded already.
Fragment frag1 = new ButtonSectionFragment ();
Fragment frag2 = new TextSectionFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(layout, frag1);
ft.add(layout, frag2);
ft.commit();
View frag1RootView = frag1.getView();
View frag2RootView = frag2.getView();
Button btn = (Button)frag1RootView.findViewById(id);
TextView tv = (TextView)frag2RootView.findViewById(id);
untested but... I think that would do it...
EDIT: You should get the root views onActivityCreated(); or it'll throw you a null...
In continuation to Raghunandan's answer, you could check similar implementation in the link.
update TextView in fragment A when clicking button in fragment B
Do not forget to get a reference of the textview of the TextSectionFragment into the MainActivity.

Check if fragment displayed as dialog to change click listener behavior

I am creating an app in which the user should be able add people for meetings.
The structure consists of several fragments managed in the same activity (list_people, person_detail, create_meeting).
I would like to reuse the fragment showing the list of people as a dialog in the create_meeting fragment. And add a person to a meeting by clicking on the person item.
When the list_people fragment is embedded in the view, a click on a person item replace the list_people fragment with a person_detail fragment. This behavior is already implemented with an interface for the main activity.
I am looking for a solution to change the behavior of the click listener whether the list_people fragment is displayed as an embedded fragment or as a dialog. Any ideas of how I could do that?
Any help would be greatly appreciated.Thanks.
Ok I have found a solution. It is to use a constructor (newInstance) for the fragment in which you can pass variables.
public class ListPeopleFragment extends Fragment {
public static ListPeopleFragment newInstance(boolean nested){
ListPeopleFragment f = new ListPeopleFragment();
Bundle args = new Bundle();
args.putBoolean("nested", nested);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_list_people, container, false);
boolean nested = false;
Bundle arguments = getArguments();
if (arguments != null)
{
nested = getArguments().getBoolean("nested");
}
displayListViewPeople(view, nested);
return view;
}
}
The displayListViewPeople set the click listener depending on the value of nested.
You instantiate the fragment this way:
ListPeopleFragment nestedFrag = ListPeopleFragment.newInstance(true);

Categories

Resources