i have one activity which contains spinner control in appbar. in homeActivity i'm using fragment which have default fragment as parentoptionfragment, from that fragment there are 3 option to change the fragments, if i have choosen one fragment from parentoption fragment and i want to change spinner value then the fragment should be updated without adding to backstack means if i press back button then it should call parent optionfragment, but when i'm trying to do so i'm getting error.
public void GetChildData(String token) {
ParentOptionsFragment fragment =new ParentOptionsFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
tv_childClassname.setText(classNameArr[position]);
tv_childSchoolName.setText(schoolNameArr[position]);
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (f instanceof ChildMapFragment){
Toast.makeText(HomeActivity.this, "refreshing childmapfragment", Toast.LENGTH_SHORT).show();
ChildMapFragment fragment = new ChildMapFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStackImmediate (fragment.getClass().getName(), 0);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}else if(f instanceof ParentOptionsFragment){
Toast.makeText(HomeActivity.this, "spinner changed from ParentOptionsFragment", Toast.LENGTH_SHORT).show();
}
}
parentoptionfragment.java
public class ParentOptionsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_parent_options, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final ImageView img1=(ImageView)view.findViewById(R.id.imageView);
ImageView img2=(ImageView)view.findViewById(R.id.imageView2);
ImageView img3=(ImageView)view.findViewById(R.id.img_transport);
img3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ChildMapFragment fragment = new ChildMapFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
/*final ViewTreeObserver vto = img1.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int x;
img1.getViewTreeObserver().removeOnPreDrawListener(this);
x = img1.getMeasuredWidth();
img1.setLayoutParams(new LinearLayout.LayoutParams(x,x));
return true;
}
});*/
}
}
childfragment.java
public class ChildFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_child_map, container, false);
}
}
homeActivity ---> defaultfragment-- parentoptionfragment
parentoptiofragment---> childfragment
using spinner update childfragment without backstack
onbackpress of childfragment --> parentoptionfragment
replace
Toast.makeText(HomeActivity.this, "refreshing childmapfragment", Toast.LENGTH_SHORT).show();
ChildMapFragment fragment = new ChildMapFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStackImmediate (fragment.getClass().getName(), 0);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
with :
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack()
update :
on your child fragment add a method : update() and call it :
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container)
if(fragment isInstanceOf ChildMapFragment ){
((ChildMapFragment )fragment).update() //call your update method here
}
FragmentManager fragmentManager = getSupportFragmentManager();
// String f_name=fragment.getClass().getName();
if (!fragmentManager.popBackStackImmediate(tag, 0)) {
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
}
to Refresh fragment implement back stack in activity like this
#Override
public void onBackStackChanged() {
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fr = fragmentManager.findFragmentById(R.id.content_frame);
if (fr != null) {
fr.onResume();
}
}
here pass different tag base on different fragment
Related
I wanna inflate some fragment from an activity (which is not main but is activity).
I do exactly like this instruction:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
YourFragment fragment = new YourFragment();
fragmentTransaction.replace(android.R.id.content, fragment);//here is the error
fragmentTransaction.commit();
but in the one before last line, editor shows error saying:
2nd argument wrong type.Found:max.mzf.max.fragment.Required:android.app.fragment
this is my own code:
Activity
public class QuizCard extends FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_card);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
QcardFragment fragment = new QcardFragment();
fragmentTransaction.replace(R.id.your_placeholder, fragment );
fragmentTransaction.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.card_menu, menu);
return true;
}
and this is QcardFragment:
public class QcardFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//get data from Argument
}
public void onCardClick(View view) {
flipCard();
}
private void flipCard() {
View rootLayout = (View) getActivity().findViewById(R.id.main_activity_root);
View cardFace = (View) getActivity().findViewById(R.id.main_activity_card_face);
View cardBack = (View) getActivity().findViewById(R.id.main_activity_card_back);
FlipAnimation flipAnimation = new FlipAnimation(cardFace, cardBack);
if (cardFace.getVisibility() == View.GONE) {
flipAnimation.reverse();
}
rootLayout.startAnimation(flipAnimation);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.qcardfragment, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
What's wrong?
Make sure that your fragment class extends Fragment from android native library. If you are using external implementation try to change
FragmentManager fragmentManager = getFragmentManager();
to
FragmentManager fragmentManager = getSupportFragmentManager();
My code was working few hours ago but not anymore, I can't see what is the reason.
Here is my listener where I change fragment after a click :
CustomMarkRow.java
public void onClick(DialogInterface dialogInterface, int i){
Bundle bundle = new Bundle();
bundle.putInt("id", CustomMarkRow.this.mark.getId());
FragmentManager fragmentManager = CustomMarkRow.this.fragmentManager;
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); activity.getActionBar().setSelectedNavigationItem(CustomMarkRow.this.positionTab);
EditMarkFragment fragment = new EditMarkFragment();
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.fragmentContainer, fragment,"2");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
At this moment, fragment.getArguments() contains what I put inside :
{android.os.Bundle#3644} "Bundle[{id=1}]"
In my second file :
EditMarkFragment.java
public class EditMarkFragment extends Fragment {
public View view;
public EditMarkFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
this.view = inflater.inflate(getResources().getIdentifier("edit_mark", "layout",container.getContext().getPackageName()), container, false);
if(this.getArguments()==null){ // always null
...
}
return this.view
}
getArguments() always return null here, What is bad in this sample ?
* edit *
Here is my launcher class :
public class Launcher extends Activity implements ActionBar.TabListener {
private HomeFragment frag1 = new HomeFragment();
private EditMarkFragment frag2 = new EditMarkFragment();
private MarkListFragment frag3 = new MarkListFragment();
private EditCategoryFragment frag4 = new EditCategoryFragment();
private CategoryListFragment frag5 = new CategoryListFragment();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.launcher);
//Configuration de la barre d'onglet
getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = getActionBar().newTab().setTabListener(this).setTag("1").setText("Home"); //.setIcon(R.drawable.homew);
getActionBar().addTab(tab1);
ActionBar.Tab tab2 = getActionBar().newTab().setTabListener(this).setTag("2").setText("New Mark"); //.setIcon(R.drawable.addw);
getActionBar().addTab(tab2);
ActionBar.Tab tab3 = getActionBar().newTab().setTabListener(this).setTag("3").setText("My Marks"); //.setIcon(R.drawable.listw);
getActionBar().addTab(tab3);
ActionBar.Tab tab4 = getActionBar().newTab().setTabListener(this).setTag("4").setText("New Category"); //.setIcon(R.drawable.categoryw);
getActionBar().addTab(tab4);
ActionBar.Tab tab5 = getActionBar().newTab().setTabListener(this).setTag("5").setText("Categories"); //.setIcon(R.drawable.categoryw);
getActionBar().addTab(tab5);
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
if(tab.getTag().equals("1")){
ft.replace(R.id.fragmentContainer, frag1);
}
else if(tab.getTag().equals("2")){
ft.replace(R.id.fragmentContainer, frag2);
}
else if(tab.getTag().equals("3")){
ft.replace(R.id.fragmentContainer, frag3);
}
else if(tab.getTag().equals("4")){
ft.replace(R.id.fragmentContainer, frag4);
}
else if(tab.getTag().equals("5")){
ft.replace(R.id.fragmentContainer, frag5);
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
if(tab.getTag().equals("1")){
ft.remove(frag1);
}
else if(tab.getTag().equals("2")){
ft.remove(frag2);
}
else if(tab.getTag().equals("3")){
ft.remove(frag3);
} else if(tab.getTag().equals("4")){
ft.remove(frag4);
}
else if(tab.getTag().equals("5")){
ft.remove(frag5);
}
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
}
}
While your onClick() code is creating an arguments Bundle, your onCreate() is not. If that edition of your fragment calls getArguments(), the method will return null.
1-Update your EditMark fragment with as follows:-
public class EditMarkFragment extends Fragment {
public static View view;
public static EditMarkFragment newInstance(int id) {
EditMarkFragment fragment = new EditMarkFragment();
Bundle bundle = new Bundle();
bundle.putInt("id", id);
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
this.view = inflater.inflate(getResources().getIdentifier("edit_mark", "layout",container.getContext().getPackageName()), container, false);
int id=getArguments.getInt("id");
return this.view}
2- Inside CustomMarkRow update your code as :-
public void onClick(DialogInterface dialogInterface, int i){
FragmentManager fragmentManager = CustomMarkRow.this.fragmentManager;
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); activity.getActionBar().setSelectedNavigationItem(CustomMarkRow.this.positionTab);
EditMarkFragment fragment = EditMarkFragment.newInstance(CustomMarkRow.this.mark.getId()) ;
fragmentTransaction.replace(R.id.fragmentContainer, fragment,"2");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
Try this,hope this will hep you.
I'm trying to crate a viewpager transition inside a fragment class which itself derived from another fragment class. Whenever I'm trying to create the viewpager its showing the following error.
02-09 11:28:34.321: E/AndroidRuntime(8520): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gm.gakkmusic/com.gm.gakkmusic.MainActivity}: java.lang.IllegalStateException: Recursive entry to executePendingTransactions
02-09 11:28:34.321: E/AndroidRuntime(8520): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338)
02-09 11:28:34.321: E/AndroidRuntime(8520): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
After searching for a while in StackOverflow I found that I've to use getChildFragmentManager() while nesting a child fragment to its main fragment but I'm kinda confused about the whole process. It would be nice if anyone can figure this problem and give a quick solution.
Sources are given below,
This is where the Fragment1 is created from the MainActivity.class
#Override
public void onNavigationDrawerItemSelected(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
switch (position) {
case 0:
fragmentManager.beginTransaction()
.replace(R.id.container, new Fragment1())
.commit();
break;
}
}
Fragment1.class is the parent Fragment and inside it the child viewpager transition is created,
public class Fragment1 extends Fragment implements OnItemClickListener {
private Fragment contentFragment;
SliderFragment sliderFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
if (savedInstanceState != null) {
if (fragmentManager.findFragmentByTag(SliderFragment.ARG_ITEM_ID) != null) {
sliderFragment = (SliderFragment) fragmentManager
.findFragmentByTag(SliderFragment.ARG_ITEM_ID);
contentFragment = sliderFragment;
}
} else {
sliderFragment = new SliderFragment();
switchContent(sliderFragment, SliderFragment.ARG_ITEM_ID);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View content = inflater.inflate(R.layout.fragment1_layout, container,
false);
return content;
}
#Override
public void onSaveInstanceState(Bundle outState) {
if (contentFragment instanceof SliderFragment) {
outState.putString("content", SliderFragment.ARG_ITEM_ID);
}
super.onSaveInstanceState(outState);
}
public void switchContent(Fragment fragment, String tag) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
while (fragmentManager.popBackStackImmediate())
;
if (fragment != null) {
FragmentTransaction transaction = fragmentManager
.beginTransaction();
transaction.replace(R.id.content_frame, fragment, tag);
if (!(fragment instanceof SliderFragment)) {
transaction.addToBackStack(tag);
}
transaction.commit();
contentFragment = fragment;
}
}
public void onBackPressed() {
FragmentManager fm = getActivity().getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
super.getActivity().onBackPressed();
} else if (contentFragment instanceof SliderFragment
|| fm.getBackStackEntryCount() == 0) {
getActivity().finish();
}
}
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Log.i(LOG_TAG, "onItemClick: " + position);
Log.d(LOG_TAG, "checked items: " + listView.getCheckedItemCount());
Log.d(LOG_TAG,
"checked positions: " + listView.getCheckedItemPositions());
}
}
UPDATE: I've already solved the problem by replacing all getSupportFragmentManager() to getChildFragmentManager() but I'm still looking for an efficient way to solve this.
I have a NavigationDrawer which I use to switch between Fragments. What i would like to do is have a button in one of my fragments which acts as a 'shortcut' to another Fragment in the NavigationDrawer.
In the NavigationDrawer I switch fragments like this:
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
public void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager
.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
private FragmentBase createFragmentByPosition(int position) { // FragmentBase just extends Fragment
FragmentBase fragment = null;
if (position == 0) {
fragment = new Fragment1();
Bundle args = new Bundle();
fragment.setArguments(args);
} else if (position == 1) { // Reminder
fragment = new Fragment2();
Bundle args = new Bundle();
fragment.setArguments(args);
}
return fragment;
}
I'm not sure how I would go about doing this. I tried getting an instance of the NavigationDrawer class and then calling selectItem with the desired position, but this doesn't work as it gives an error "no view found".
In the NavigationDrawer class:
public Navigation_Drawer getInstance() {
if (null == instance) {
instance = new Navigation_Drawer();
}
return instance;
}
In FragmentB (position 1):
//onClick
Navigation_Drawer nd = new Navigation_Drawer().getInstance();
nd.selectItem(0); // Try to go to FragmentA
This seems far too simple so no wonder it doesn't work!
First, on selectItem method, using add method instead of replace method:
public void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
// fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
Second, getInstance method in Navigation_Drawer should not create a new Navigation_Drawer when instance is null, set instance to this in onCreate in Navigation_Drawer, then return instance when call getInstance:
private static Navigation_Drawer mInstance;
public static Navigation_Drawer getInstance() {
return mInstance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
mInstance = this;
// other codes here:
}
The id to the QuickNoteFragment is 0, and to PendViewPager is 1. You can turn to PendViewPager in QuickNoteFragment:
Navigation_Drawer.getInstance().selectItem(1);
-
update1: how to pass data to fragment:
QuickNoteFragment and HistoryFragement have the same parent Class: FragmentBase, we add a method named onDataIn to receive data:
public class FragmentBase extends Fragment {
public void function onDataIn(Object data) {
}
}
We should change selectItem, add a paraments to receive data:
public void selectItem(int position, Object data) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
// call onDataIn() method.
fragment.onDataIn(data);
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
// fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
In order to make selectItem compatible, we should add a overloaded selectItem method.
public void selectItem(int postion) {
selectItem(position, null);
}
In this way, we do not need to change the old code where called selectItem and did not need pass a data to fragement.
I have created just sample application for fragment hiding and showing.At the first fragment is added into the view properly.But on menu press to hide fragment it don't get hide.I posted my code as follows..
public class SwapfragActivity extends Activity
{
FrameLayout fr;
FragmentManager fm = getFragmentManager();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fr = (FrameLayout) findViewById(R.id.fm1);
frag f = new frag();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("SHOW");
menu.add("HIDE");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
frag f = new frag();
if (item.getTitle() == "SHOW")
{
if (!f.isAdded())
{
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fm1, f);
ft.commit();
}
else if (f.isHidden())
{
FragmentTransaction ft = fm.beginTransaction();
ft.show(f);
ft.commit();
}
}
else
{
if (f.isAdded())
{
FragmentTransaction ft = fm.beginTransaction();
ft.hide(f);
ft.commit();
}
}
return true;
}
}
class frag extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.a, container, false);
}
}