i am calling fragment from custom dialog. but i cant call fragment.
my onClick calling function
public void text_noteClick(View v){
Fragment fragments = new Text_Note_Fragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.layout.note_text, fragments);
transaction.addToBackStack(null);
Toast.makeText(getApplicationContext(),"text",Toast.LENGTH_SHORT).show();
}
Toast is works successfully.
Text_Note_Fragment class is
public class Text_Note_Fragment extends Fragment {
public Text_Note_Fragment() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view;
view = inflater.inflate(R.layout.note_text,container,false);
return view;
}
}
i think problem is Fragment replacing function.
sorry for my English :) TNX
I guess this line is the root cause.
transaction.replace(R.layout.note_text, fragments);
I see you use R.layout.note_text in onCreateView function, that's the layout xml for your fragment. but why you use it in replace function? you should use a container(often a FrameLayout), like this.
transaction.replace(R.id.container, fragments);
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 am learning fragments and i am stuck in how to dynamically change layout in the main activity where i want to call different fragments according to the list text i choose from a listview.
This is the Fragment extension class. Do i have to do any if else here so that i can return my desired layout?Lets say i click another option in listview and i want Layout.arts instead of Layout.sports to be shown in the main activity, how can it be done?
public class MenuFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.sports, container, false);
}
}
here is the onclick listener for the listview
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("Hello","Clicked");
// update the main content by replacing fragments
MenuFragment frag = new MenuFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MenuFragment fragment = new MenuFragment();
fragmentTransaction.replace(R.id.drawer_layout, fragment, String.valueOf(position));
fragmentTransaction.commit();
mDrawerLayout.closeDrawer(mDrawerList);
}
}
If the business logic is same other than only layout, you can write the if - else condition in the onCreateView() of Fragment
If the business logic is different for sports and arts then create two different fragments for sports and arts and onItemClick() method replace the appropriate fragment.
I think you can do it with Layout Inflater:
public void changeView(int layoutId){
container.removeAllViewsInLayout();
inflater.inflate(layoutId, container, true);
}
container and inflater are from onCreateView.
I have an issue with fragment navigation in frame-layouts. Namely I cannot find out in which frame the fragment is currently being displayed in.
My setup is the following:
I have 3 parent fragments (PA, PB, PC), each with their own unique framelayouts. Additionally I have 3 Childfragments (CA,CB, CC) and two Grandchildfragments (GA, GB)
The parent fragments call the childfragments into the appropriate framelayouts (works fine), but now I want the childfragments to replace themselves with the appropriate grandchildren, but I have no way of finding out in which framelayout the childfragments are currently displayed in. (I hope that makes sense)
Pseudo-code example:
public class Parent extends Fragment{
//lots of stuff here
public void replaceFragmentWithChild(){
Fragment frg = new childFragment();
FragmentManager mgr = ((FragmentActivity) getActivity()).getSupportFragmentManager();
FragmentTransaction trx = mgr.beginTransaction();
trx.addToBackStack(null);
trx.replace(R.id.content_view_a, childFragment).commit();
}
}
public class Child extends Fragment{
//lots of stuff here
public void replaceFragmentWithGrandChild(){
Fragment frg = new GrandChildFragment();
FragmentManager mgr = ((FragmentActivity) getActivity()).getSupportFragmentManager();
FragmentTransaction trx = mgr.beginTransaction();
trx.addToBackStack(null);
//here is the problem. I would like to call trx.replace(GET-CURRENT-CONTENT-VIEW, frg)
trx.replace(???, frg).commit();
}}
Any input would be much appreciated.
Edit: Ok, I have found a possible solution by saving the ViewGroup Container in the onCreateView and passing that to the trx.replace function.
But unfortunately I am getting the following Message: java.lang.IllegalArgumentException: No view found for id 0x7f0c0057 (de.tel.quenference.activities:id/sara_content_view) for fragment PaperviewFragment{421da470 #2 id=0x7f0c0057} which makes little sense to me, because the view is the same one I am in,or?
What am I missing?
Ok, I figured it out and I sort of want to shoot myself.
First off, the 'No View Found' error stems from the fact, that my parentfragment did not call transaction.addToBackStack (I added it into my example code but not my production code...)
Just putting that in unfortunately did not fix everything, but I had to also change the ParentFragment to not call getChildFragmentManager, but rather the normal FragmentManager
otherwise the grandchildfragment would not appear in the frameLayout.
Basically my working code looks like this:
public class Parent extends Fragment{
//lots of stuff here
public void replaceFragmentWithChild(){
Fragment frg = new childFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
trx.addToBackStack(null);
trx.replace(R.id.content_view_a, childFragment).commit();
}
}
public class Child extends Fragment{
private ViewGroup locContainer;
//lots of stuff here
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
locContainer = container;
return super.onCreateView(inflater, container, savedInstanceState);
}
public void replaceFragmentWithGrandChild(){
Fragment frg = new GrandChildFragment();
FragmentTransaction trx = getFragmentManager().beginTransaction();
trx.addToBackStack(
trx.replace(locContainer.getId(), frg).commit();
}}
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've been trying to get ActionBarSherlock working with Google's fragment tutorial and run into a problem when trying to add the "content" fragment to the view. This line produces the following exception
getFragmentManager().beginTransaction().add(android.R.id.content, content).commit();
The method add(int, Fragment) in the type FragmentTransaction
is not applicable for the arguments (int, ContentFragment)
The code is identical to Google's (http://developer.android.com/guide/components/fragments.html) except I've extended to SherlockActivity where needed. ContentFragment/Activity is merely what I've called Details activity.
Even if I take out all of the ABS references to make it a normal example, I get the same problem. I have a feeling its to do with the android support library, but I cant for the life of me figure it out.
Use getSupportFragmentManager() instead of getFragmentManager().
How does your fragment class look like? This code works fine for me:
android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
FragmentADetail frag = new FragmentADetail();
ft.replace(android.R.id.content, frag);
ft.addToBackStack(null);
ft.commit();
And my FragmentADetail class looks like this:
public class FragmentADetail extends SherlockFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getSherlockActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(true);
View v = inflater.inflate(R.layout.fragment_a_detail_layout, container, false);
v.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//left empty on purpose to capture the onClick event.
}
});
return v;
}
#Override
public void onStop()
{
super.onStop();
getSherlockActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
}