how to change fragment inside a dialogfragment - android

I want to make an empty DialogFragment with a LinearLayout and then change fragments inside the LinearLayout. For example, a login where the first fragment is 3 button (facebook, google+, email login) and when somebody pressed email then the 2. fragment has a layout with EditTexts if Google or Facebook was pressed then the other fragment appears with a ProgressBar.
this is my empty dialog layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#drawable/dialog_background">
<LinearLayout
android:id="#+id/testFragmentController"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_margin="15dp"></LinearLayout>
</RelativeLayout>
And this is the first fragment's code (I am using android annotations):
#EFragment(R.layout.dialog)
public class FragmentGeneralDialog extends ClickDialogFragment {
#ViewById
LinearLayout testFragmentController;
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
this.setStyle(R.style.Dialog_No_Border, getTheme());
return dialog;
}
#AfterViews
void afterViews() {
loadActivity();
GlobalData.setFragmentContainer(testFragmentController);
activity.loadMenuFragment(FragmentSocialDialog_.class, new SlideLeftAnimation());
}
}
loadMenuFragments(...) is this:
public <T extends Fragment> T loadMenuFragment(final Class<T> cls,
final IAnimation a) {
T fragment = null;
try {
fragment = cls.newInstance();
} catch (Exception ex) {
throw new RuntimeException("Fragment " + cls.toString()
+ " has no empty constructor");
}
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (a != null) {
transaction.setCustomAnimations(a.getInId(), a.getOutId(), a.getInId(),
a.getOutId());
}
transaction.replace(R.id.testFragmentController, fragment);
try {
transaction.commit();
} catch (Exception e) {
}
return fragment;
}

You need to get the childFragmentManager from the dialogfragment link, then from the child fragments you can change the fragments via getParentFragment().getChildFragmentManager()

I found a better way than getParentFragment. You can in parent fragment add public static FragmentManager and use it in nested fragment:
In parent:
public class SelectProductDialogFragment extends DialogFragment {
public static FragmentManager fragmentManager;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dialog_add_product,container,false);
fragmentManager = getChildFragmentManager();
return v;
}
}
In child: for example for replace transaction:
ProductsGridFragment productsGridFragment = new ProductsGridFragment();
FragmentTransaction transaction = SelectProductDialogFragment.fragmentManager.beginTransaction()
.replace(R.id.dialog_order_container,productsGridFragment)
.addToBackStack(null);
transaction.commit();

Related

How to communicate from Mainactivity to Fragment using callback interface?

I'm having navigation drawer with four menu's and each menu has own fragments
, Inside first fragment has view pager sliding tab with 2 fragments,
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#color/white"
app:tabIndicatorHeight="4dp" />
</android.support.design.widget.AppBarLayout>
////////////// Here I'm replacing each fragments ////////////////
<FrameLayout
android:id="#+id/main_content_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_done"
android:visibility="gone"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_view"/>
</android.support.v4.widget.DrawerLayout>
ManinActivity- DrawerSelection
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass = null;
switch (menuItem.getItemId()) {
case R.id.nav_home:
fragmentClass = Home_Tab_Fragment.class;
break;
case R.id.nav_myorders:
fragmentClass = SecondFragment.class;
break;
case R.id.nav_myoffers:
fragmentClass = ThirdFragment.class;
break;
case R.id.nav_notification:
fragmentClass = FourthFragment.class;
break;
}
fragment = (Fragment) fragmentClass.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.main_content_framelayout, fragment).commit();
mDrawerLayout.closeDrawers();
}
HomeTabFragment
public class Home_Tab_Fragment extends Fragment {
private FragmentActivity myContext;
ViewPager viewPager;
TabLayout tabLayout;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_viewpager, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.view_pager);
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SlidingTabAdapter adapter = new SlidingTabAdapter(getChildFragmentManager());
adapter.addFragment(new FirstTabFragment(), "First TAB");
adapter.addFragment(new SecondTabFragment(), "Second Tab");
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) getActivity().findViewById(R.id.tabs);
tabLayout.setVisibility(View.VISIBLE);
tabLayout.setupWithViewPager(viewPager);
}
}
SlidingTabAdapter
public class SlidingTabAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public SlidingTabAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
layout_viewpager.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
FirstFragment
public class FirstTabFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
getActivity().setTitle("Foodies");
return rootView ;
}
public void updateFirstFragmentValues(){
//Doing some operations
}
}
Inside MainActivity , I want to call FirstTabFragment method [updateFirstFragmentValues()]
I tried adding TAG in FirstTabFragment ,
public static final String TAG ="FirstTabFragment.TAG";
Then I invoked in MainActivity like below , but Fragment always null.
public void invokeMethodFromFirstTabFragment() {
FragmentManager fm = this.getSupportFragmentManager();
FirstTabFragment fb=(FirstTabFragment)fm.findFragmentByTag(FirstTabFragment.TAG);
if (null != fb) {
fb.updateFirstFragmentValues();
}else{
L.m("Fragment is null===========");
}
}
Kindly advise , How to call "FirstTabFragment" method from inside "MainActivity"
Please note FirstTabFragment is not added directly to MainActivity ,
its added through "Home_Tab_Fragment".
Alright, reading all of the responses of yours, I get that you just simply need to pass data to a fragment upon creation and be able to execute some of Fragment's methods. Ok, simple enough:
IMessageFragment interface
public interface IMessageFragment {
/**
* Method to receive new message text
* #param text Message text to receive
*/
void updateMessageText(String text);
}
MessageFragment
public class MessageFragment extends Fragment implements IMessageFragment {
/**
* Bind views using ButterKnife
*/
#BindView(R.id.textView) TextView mTextView;
/**
* Bundle data
*/
private String mMessageText;
/**
* Unique id of bundle data
*/
private static final String MESSAGE_EXTRA_KEY = "f_message";
/**
* New fragment pattern. This is pretty much all the magic PLUS this
* looks by far better than `new Fragment()` upon instatiation
*/
public static MessageFragment newFragment(String message) {
// 1. Create new fragment
MessageFragment auctionFragment = new MessageFragment();
// 2. Create bundle for fragment params
Bundle args = new Bundle();
// 3. Put position
args.putString(MESSAGE_EXTRA_KEY, message);
// 4. Set arguments
auctionFragment.setArguments(args);
return auctionFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tutorial_fragment, container, false);
/**
* Bind views
*/
ButterKnife.bind(this, view);
// Update UI
updateUI();
return view;
}
/**
* Method to update value of mTextView
*/
private void updateUI() {
if(!mMessageText.equals("")) {
mTextView.setText(mMessageText);
}
}
#Override
public void updateMessageText(String text) {
mMessageText = text;
updateUI();
}
}
Stuff is pretty simple and the interface exists only for good code style and to support design patterns.
Edit:
You cannot directly access FirstTabFragment method from your MainActivity. Firstly you have to call Home_Tab_Fragment method from activity. Then from that method you can call FirstTabFragment method.
Here is strategy:
Step 1: Home_Tab_Fragment to FirstTabFragment communication
define an interface like this
public interface IHomeToFirstFragmentController{
void firstFragmentMethod();
}
Now implements the IHomeToFirstFragmentController in your FirstTabFragment. then you have to implements the firstFragmentMethod().
#overrride
void firstFragmentMethod(){
}
Call this firstFragmentMethod method from Home_Tab_Fragment using this way
YOUR_fragmentInstance.firstFragmentMethod();
Step 2: Activity to Home_Tab_Fragment:
define an interface like this
public interface IActivityToHomeTabController{
void callFirstFragment();
}
Now implements the IFragmentController in your Home_Tab_Fragment. then you have to implements the callFirstFragment().
#overrride
void callFirstFragment(){
YOUR_fragmentInstance.firstFragmentMethod();
}
Edit 2:
Call fragment using this way
((IFragmentController)YOUR_fragmentInstance).firstFragmentMethod();
Hope this will give you an idea about this topics. For more info visit this answer
First for all, you create interface :
public interface CallBackListener{
void onCallBack();
}
In Fragment
public MyFragment extends Fragment{
private CallBackListener mCallBack;
#Override
public void onAttach(Context context) {
AppCompatActivity activity;
if (context instanceof AppCompatActivity) {
activity = (AppCompatActivity) context;
try {
mCallBack= (CallBackListener ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " class must be implement" +
" OnBackFragmentListener");
}
}
super.onAttach(context);
}
}
Use :
mCallBack.onCallBack();
And in Activity, you must implements interface :
public MyActivity extends AppCompatActivity implements CallBackListener{
#Override
public void onCallBack(){
// Do somethings here...
}
}

java.lang.IllegalArgumentException: No view found for id 0x7f0a002b (com.sapplication:id/content) for fragment ManagemntPageFragment

i want to redirect activity to fragment when clicking button but it gives me error.
here is my activity class
public class EventDetailsNotif extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.eventdetails);
ImageButton imgmenu = (ImageButton) findViewById(R.id.imgmenu);
imgmenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadFragmentObj = new LoadFragment(getFragmentManager());
loadFragmentObj.initializeFragment(new ManagemntPageFragment());
}
});
}
}
and my load fragment class is here.
public class LoadFragment {
FragmentManager fragmentManager;
FragmentManager fragmentManager1;
public LoadFragment(FragmentManager fragmentManager2) {
this.fragmentManager = fragmentManager2;
}
public void initializeFragment(Fragment resultFragment) {
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.content, resultFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
and my content.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and my fragment class.
public class ManagemntPageFragment extends Fragment {
ImageView footervie;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = (RelativeLayout) inflater.inflate(R.layout.managmntpg,
container, false);
footervie = (ImageView) view.findViewById(R.id.footervie);
advtimagepath = Utility.getSharedKey("advertiseFooter_image",
getActivity());
if (!TextUtils.isEmpty(advtimagepath)) {
if (advtimagepath.endsWith(".jpeg")
|| advtimagepath.endsWith(".jpg")
|| advtimagepath.endsWith(".gif")
|| advtimagepath.endsWith(".png")) {
imageLoader = new ImageLoader(getActivity());
imageLoader.DisplayImage(advtimagepath, footervie);
} else {
}
}
return view ;
}
}
please reply if have solution
are you sure you have below code
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
in eventdetails layout file because you set content menu in activity to this layout
setContentView(R.layout.eventdetails);
and if you don't use support library for fragment you will have compatibility with older android version!

Fragment's onDestroyView called but view is not being destroyed

The Android fragment lifecycle shows that when a fragment is added to the backstack and then removed/replaced, onDestroyView() is called, and later on, when the fragment returns to the layout from the backstack, onCreateView() is called.
From my understanding it means that the fragment's view is being destroyed and recreated. If the user has input text in an EditText in fragment A and goes to fragment B and then back to A, when the fragment comes back the EditText's contents will have been erased.
However, this is not happening in the following code; can anybody explain why? I have already verified that FragmentA's onDestroyView() is being called.
MainActivity.java
public class MainActivity extends FragmentActivity {
private Fragment currentFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
addFragment(new FragmentA());
}
}
public void setCurrentFragment(Fragment fragment) {
this.currentFragment = fragment;
}
#Override
public void onBackPressed() {
if (currentFragment instanceof FragmentB) {
getSupportFragmentManager().popBackStackImmediate();
} else {
super.onBackPressed();
}
}
public void addFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).addToBackStack(null).commit();
setCurrentFragment(fragment);
}
}
FragmentA.java
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
final EditText editText = (EditText)view.findViewById(R.id.editText);
Button button = (Button)view.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentB fragmentB = new FragmentB();
Bundle arguments = new Bundle();
arguments.putString("text", editText.getText().toString());
fragmentB.setArguments(arguments);
((MainActivity)getActivity()).addFragment(fragmentB);
}
});
return view;
}
#Override
public void onDestroyView() {
super.onDestroyView();
Log.d("Tag", "FragmentA.onDestroyView() has been called.");
}
}
FragmentB.java
public class FragmentB extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
TextView textView = (TextView)view.findViewById(R.id.textView);
textView.setText(getArguments().getString("text"));
return view;
}
}
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.fragmenttest.MainActivity"
tools:ignore="MergeRootFrame" />
fragment_a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
fragment_b.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Fragments in back stack retain their state in a Bundle. This includes the view hierarchy state with the current contents of EditTexts and such.
To destroy The Fragment .. Use This onDestroyView
or in onDetach
if (fragment != null) {
fragment = new YourFragment();
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}

No view found for id - DialogFragment + Fragment

I have a DialogFragment with a simple layout. I want to add a fragment (and in the future replace this fragment with another) to a FrameLayout that is inside the DialogFragment's layout. However, the method of adding the new fragment fails with the error:
"No view found for id 0x7f0b004f com.kennel39.diabeteslive_adtdev:id/frameAlertsContainer) for fragment Fragment_AlertsManage {41e7cb68}"
I have checked my xml, attempted different methods and have read a number of similar issues on stackoverflow but I cannot find a solution.
public class DialogManageAlerts extends DialogFragment{
static int patient_id;
public static DialogManageAlerts newInstance(int given_patient_id){
DialogManageAlerts frag = new DialogManageAlerts();
patient_id = given_patient_id;
Bundle bund = new Bundle();
bund.putInt("Patient_id", patient_id);
frag.setArguments(bund);
return frag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.dialog_alerts_master, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
FragmentManager myFragmentManager = getFragmentManager();
FragmentTransaction myTransact = myFragmentManager.beginTransaction();
Fragment_AlertsManage manageAlertsFragment = new Fragment_AlertsManage();
myTransact.add(R.id.frameAlertsContainer, manageAlertsFragment);
myTransact.commit();
return mainView;
}
layout.dialog_alerts_master:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/white_regular" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#drawable/lower_border_background_white">
<TextView
android:id="#+id/tvManageAlertsTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/manage_alerts_title"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_horizontal" />
</LinearLayout>
<FrameLayout
android:id="#+id/frameAlertsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</FrameLayout>
</LinearLayout>
And the Fragment_AlertsManage class:
public class Fragment_AlertsManage extends Fragment implements OnClickListener {
int patient_id;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_alerts_manage, container, false);
//Get buttons
Button btnAdd = (Button)myView.findViewById(R.id.btnAddAlert);
btnAdd.setOnClickListener(this);
Button btnBack = (Button)myView.findViewById(R.id.btnBack);
btnBack.setOnClickListener(this);
//FILL CONTENT
populateContent(myView);
return myView;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnAddAlert: {
//Switch fragment
FragmentManager myFragmentManager = getFragmentManager();
FragmentTransaction myTransact = myFragmentManager.beginTransaction();
Fragment_AlertsAdd addAlertFragment = new Fragment_AlertsAdd();
myTransact.addToBackStack("Previous");
myTransact.replace(this.getView().getId(), addAlertFragment);
myTransact.commit();
break;
}
case R.id.btnBack: {
FragmentManager myFragmentManager = getFragmentManager();
FragmentTransaction myTransact = myFragmentManager.beginTransaction();
myTransact.remove(Fragment_AlertsManage.this);
//Launch Home
Intent homeIntent = new Intent(this.getActivity(), HomeActivity.class);
homeIntent.putExtra("patient_id", patient_id);
startActivity(homeIntent);
getActivity().finish();
break;
}
}
}
public void populateContent(View myView){
try {
ArrayList<Alert> alerts = new RetrieveAlerts(patient_id).execute().get();
ListView list = (ListView) myView.findViewById(R.id.reminder_listview);
AlertsListAdapter alertsAdapter = new AlertsListAdapter(this.getActivity(), alerts);
list.setAdapter(alertsAdapter);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Why am I getting this error, and what can I do to solve it?
The doc on getFragmentManager():
Return the FragmentManager for interacting with fragments associated
with this fragment's activity.
R.id.frameAlertsContainer is in the DialogFragment's layout, not the activity's layout, so it can't find it. Try using getChildFragmentManager() instead. However I can't tell if this will work inside the onCreateView() method since the view isn't associated with the fragment yet. You may need to put it in onStart() or something else.
I had this problem, for resolved, i can the getFragmentManager() in method OnStart() and work perfect.

recreate view of fragment via button

I've got a FragmentActivity which show the correct fragment, using a ViewPager. I added a Fragment StatePagerAdapter to the ViewPager. If I push a button at a Fragment, it should be recreated (onCreateView should be called again). The fragments are articles and if the user is offline, I'll show him "please check your networkconnection" and a button to reload. The button called a method in the FragmentActivity, but I don't know how implement it. Maybe I can destroy and recreate the current Fragment?
here the important part of the FragmentActivity:
private ArrayList<Fragment> fragments;
protected void onCreate(Bundle savedInstanceState)
{
context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article_page_slider);
...
pages = datahandler.getCount(...);
viewPager = (ViewPager) findViewById(R.id.articlePager);
PagerAdapter pagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(startPosition);
fragments = new ArrayList<Fragment>(pages);
}
public void reloadData(View v)
{
// TODO
((ArticlePageFragment)fragments.get(viewPager.getCurrentItem())).refresh();
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
Fragment fragment = new ArticlePageFragment();
Bundle args = new Bundle();
...
fragment.setArguments(args);
fragments.add(position, fragment);
return fragment;
}
public int getCount()
{
return pages;
}
}
and the Fragment itself:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
activity = getActivity();
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_article_page, container, false);
CacheDataHandler cdh = new CacheDataHandler(activity);
cdh.open();
String htmlData = cdh.loadData();
rootView.findViewById(R.id.btn_reload_article_data).setVisibility(View.GONE);
webView = ((WebView) rootView.findViewById(R.id.articleFragment));
refresh();
...
return rootView;
}
public void refresh()
{
...
if (htmlData == null)
{
rootView.findViewById(R.id.btn_reload_article_data).setVisibility(View.VISIBLE);
webView.loadData(defaultdata,"text/html", "UTF-8");
}
else
{
webView.loadData(htmlData,"text/html", "UTF-8");
}
}
and the fragment_article_page.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<WebView
android:id="#+id/articleFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:id="#+id/btn_reload_article_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:onClick="reloadData"
android:text="#string/btn_txt_reload_data"
android:visibility="gone" />
</RelativeLayout>
EDIT
added a private ArrayList<Fragment> fragments in FragmentActivity and transfer the code for manipulating the view in an extra refreshMethod, look ahead. All works fine, if I only click on the first or second Fragment (index 0 and 1). Otherwise I get an IndexOutOfBoundsException. How to initialize and fill the ArrayList?

Categories

Resources