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.
Related
I'm using ViewPager and TabLayout. And ViewPager is consisted with 4 fragments(for example, I'll call the fragments' name 1, 2, 3, 4). My 2(second fragment) has a ListView, and if I click a list-item, the 2(second fragment) will be changed another view. At that time, another view is not 1, 3 or 4. That is a new view.
It is purpose to make board's category(like, sports-soccer-midfielder). So when I select sport item, the view will show another list-item(like, soccer, baseball, basketball an so on). The category will be consisted with 3 step. So i will prepare second and third view of 2(second fragment).
But I don't know how to change view or fragment. I found some clue to solve this problem in google.
That is
FragmentManager fm = getFragmentManager();
FragmentTransaction fmt = fm.beginTransaction();
View2 v2 = new View2(); // View2 is another view
fmt.replace(R.id.view1, v2);
fmt.commit();
I used that code and it succeed to change view. But only a part of view is changed. What is the problem? How can I solve that?
Here is Pic of second fragment
and this is a view when I click list-item. only a part of view is changed.
(I can't attach picture directly, so someone help please ^^ )
And this is my code of second fragment.
public class MatchingFragment extends Fragment {
View2 v2;
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.matching_fragment, container, false);
final MatchingListViewAdapter adapter = new MatchingListViewAdapter();
ListView listView = (ListView) view.findViewById(R.id.matching_list1);
listView.setAdapter(adapter);
adapter.addItem(ContextCompat.getDrawable(getActivity(), R.drawable.lock), "LOCK", "This is lock icon");
adapter.addItem(ContextCompat.getDrawable(getActivity(), R.drawable.setup), "SETUP", "This is setup icon");
adapter.addItem(ContextCompat.getDrawable(getActivity(), R.drawable.user), "USER", "This is user icon");
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FragmentManager fm = getFragmentManager();
FragmentTransaction fmt = fm.beginTransaction();
v2 = new View2();
fmt.replace(R.id.view1, v2);
fmt.commit();
adapter.notifyDataSetChanged();
}
});
return view;
}
}
Thanks.
I think you need to start a activity when you click item on listview. because if you replace new fragment with viewpager how can you go back to previous fragment. and why you create View2() object, what is the purpose of that?
if you want to replace fragment with viewpager use this code for it, don't replace viewpager by viewpager
Fragment fragment = new FragmentOne();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.view, fragment);
ft.commit();
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 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);
I'm faced with following problem:
MainActivity is mainly a ViewPager where I can slide through cards (Fragment). This cards have a placeholder ViewGroup where another content (Fragment) is placed in during runtime. The problem is that the content is placed only in one card.
MainActivity
public class MainActivity extend FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ...
// init ViewPager
getViewPager().setAdapter(new CardSelectionAdapter(getSupportFragmentManager()));
}
// ...
private class CardSelectionAdapter extends FragmentPagerAdapter {
// ...
public Fragment getItem(int position) {
return new CardFragment(someData);
}
}
}
CardFragment
public class CardFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.card, container, false);
rootView.findViewById(R.id.actionSheet).setVisibility(View.GONE);
return rootView;
}
public void populate() {
// ...
Fragment f;
switch (type) {
case TYPE_A: f = new ActionsAFragment(); break;
case TYPE_B: f = new ActionsBFragment(); break;
default: f = null;
}
if (f != null) {
// Here should be the main problem when adding Fragment to container/placeholder
getFragmentManager().beginTransaction().add(R.id.actionSheet, f).commit();
getView().findViewById(R.id.actionSheet).setVisibility(View.VISIBLE);
}
}
}
I think because all cards belong to MainActivity, FragmentTransaction can only add to one ViewGroup with id R.id.actionSheet.
Is there another way how I can add content to layout with same ids?
I don't see where you are calling populate. You should change populate to accept the parent view (instead of adding the fragment to R.id.actionsheet every time) and call it from onCreateView and pass it the view you just created. That way you don't have a problem with multiple views inside actionSheet with the same ID. However there is so much code missing I can't be exactly sure what to do here.
By the way, when you are dealing with nested fragments - inside of populate, you should use getChildFragmentManager() instead of getFragmentManager().
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.