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.
Related
Theoretically, lets say i have two classes with corresponding XML files - Activity and Frag
Activity.java
public class Activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment fragment = new Frag();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragmentArea, fragment);
ft.commit();
}
}
Frag.java
public class Frag extends Fragment {
private TextView txtView;
public Frag() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_, container, false);
txtView = view.findViewById(R.id.textView);
return view;
}
public void setTextView(String str) {
txtView.setText(str);
}
}
activity xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.eksamen.chris.eksempelfragment.Activity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/fragmentArea">
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Fragment xml
<FrameLayout 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"
tools:context="com.eksamen.chris.eksempelfragment.Frag">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment"
android:id="#+id/textView"/>
</FrameLayout>
As you can see, i have the method setTextView() in my Frag class. Obviously enough, what i would like to do is to call that method from my Activity class.
I have tried grasping this for some hours now, and i really cannot figure out a way to do this. Every example/tutorial out there makes my app crash.
Could someone explain to me how this works, taken the example we have in hand into consideration? Or maybe there is a better way to provide the fragment with data from my activity?
I'd be grateful!
Edit: awful indentation, had some issues, trying to fix.
In order to pass data from Activity to Fragment , you have to use :
Bundle
which is a KEY VALUE data structure for passing values between fragments and activity so at your onCreate() in Activity class will be
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str = "your_string_here";
// 1 -
Bundle bundle = new Bundle();
// 2 -
bundle.putString("KEY", str);
Fragment fragment = new Frag();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// 3 -
fragment.setArguments(bundle);
ft.replace(R.id.fragmentArea, fragment);
ft.commit(); }
and at your fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_, container, false);
txtView = view.findViewById(R.id.textView);
// 4 - NOTE : Should hould the same key at the Activity class :
String str = getArguments().getString("KEY");
setTextView(str);
return view;
}
1/ activity_main in "layout" folder:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_normal"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.demofragment.MainActivity" >
</FrameLayout>
2/ activity_main in "layout-land" folder:
<FrameLayout 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:baselineAligned="false"
tools:context="com.example.demofragment.MainActivity" >
<com.example.supportlibrary.MenuLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_sliding_menu"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</com.example.supportlibrary.MenuLayout>
</FrameLayout>
3/ FragmentOne.class:
public class FragmentOne extends Fragment implements OnClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment_one_layout, container,false);
return v;
}
}
4/ FragmentTwo.class:
public class FragmentTwo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment_two_layout, container,false);
return v;
}
}
5/ MainActivity.class:
public class MainActivity extends FragmentActivity {
FragmentTransaction transaction;
FragmentOne frg1;
FragmentTwo frg2;
FragmentManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frg1 = new FragmentOne();
manager = getFragmentManager();
transaction = manager.beginTransaction();
transaction.add(R.id.layout_normal, frg1, "Frag_One");
transaction.commit();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
frg1 = new FragmentOne();
frg2 = new FragmentTwo();
transaction.add(R.id.layout_sliding_menu, frg1, "Frag_One");
transaction.add(R.id.layout_sliding_menu, frg2, "Frag_Two");
transaction.commit();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
frg1 = new FragmentOne();
transaction.add(R.id.layout_normal, frg1, "Frag_One");
transaction.commit();
}
}
The problem is I get this exception when rotate the screen:
12-30 06:54:40.062: E/AndroidRuntime(1641): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.demofragment/com.example.demofragment.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f090000 for fragment FragmentOne{53512438 #1 id=0x7f090000 Frag_Top_tag}
Please show me how to fix it!Thanks!
Call setContentView again when configuration changes.
Since you handle config changes yourself, you need to set content view again so that the right layout is used.
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!
I have a fragment that executes or display a dialog fragment once a button is clicked. This dialog fragment displays a table generated by code, however when I try to click the button on this is displayed
And when I trace it in the LogCat the dialog fragments onCreateView is not called. Can somebody help or explain this to me?. Im not that good in android programming yet and I know i still have a lot to learn.
Here is the code of the fragment that calls the dialog fragment
public class fragment_schedule extends Fragment {
...............
public fragment_schedule(ArrayList<SubjSchedule> subj){
subject = subj;
}
#SuppressWarnings("deprecation")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
..................
showlstbtn = (Button) rootView.findViewById(R.id.button_showlstschd);
showlstbtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
ft.addToBackStack(null);
DialogFragment dialog = ShowLstDialog.newInstance(subject);
dialog.show(ft, "dialog");
}
});
..........
and heres my dialog fragment
public class ShowLstDialog extends DialogFragment {
private static final String TAG = ShowLstDialog.class.getSimpleName();
public static Context mContext;
public static TableLayout tl;
public static TableRow trh;
private static ArrayList<SubjSchedule> subject= new ArrayList<SubjSchedule>();
public static DialogFragment newInstance(ArrayList<SubjSchedule> subj) {
// TODO Auto-generated method stub
DialogFragment f = new DialogFragment();
subject = subj;
Log.v(TAG, subject.size()+"");
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.v(TAG, "OnCreateView: " + subject.size()+"");
View rootView = inflater.inflate(R.layout.fragment_dialog_showlst, container);
//mEditText = (EditText) view.findViewById(R.id.txt_your_name);
Log.v(TAG, "OnCreateView: " + subject.size()+"");
getDialog().setTitle("");
tl = (TableLayout) rootView.findViewById(R.id.tablelayout_schedlst);
trh = new TableRow(getActivity());
TextView[] tvh = new TextView[3];
for(int i=0; i<3; i++){
tvh[i] = new TextView(getActivity());
tvh[i].setBackgroundResource(R.drawable.green2);
tvh[i].setTextColor(getResources().getColor(R.color.LightCyan));
tvh[i].setGravity(Gravity.CENTER);
tvh[i].setPadding(30, 3, 30, 3);
//tvh[i].setLayoutParams(params);
trh.addView(tvh[i]);
}
tvh[0].setText("Subject");
tvh[1].setText("Description");
tvh[2].setText("Instructor");
TableRow[] tr = new TableRow[subject.size()];
for(int i=0; i<subject.size();i++){
tr[i] = new TableRow(getActivity());
TextView[] tv1 = new TextView[3];
for(int k=0; k<3; k++){
tv1[k] = new TextView(getActivity());
tv1[k].setBackgroundResource(R.drawable.btn_default_disabled_holo_dark);
tv1[k].setTextColor(getResources().getColor(R.color.list_background_pressed));
tv1[k].setGravity(Gravity.CENTER);
tv1[k].setPadding(30, 3, 30, 3);
//tvh[i].setLayoutParams(params);
tr[i].addView(tv1[i]);
}
tv1[0].setText(subject.get(i).getcn());
tv1[1].setText(subject.get(i).getd());
tv1[2].setText(subject.get(i).geti());
tl.addView(tr[i]);
}
return rootView;
}
}
and here is the xml file of the dialog fragment
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#color/LightCyan"
android:scrollbars="vertical" >
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TableLayout
android:id="#+id/tablelayout_schedlst"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="*" >
</TableLayout>
</RelativeLayout>
</HorizontalScrollView>
</ScrollView>
</RelativeLayout>
thank you so much in advance.
Change this
public static DialogFragment newInstance(ArrayList<SubjSchedule> subj) {
// TODO Auto-generated method stub
DialogFragment f = new DialogFragment();
subject = subj;
Log.v(TAG, subject.size()+"");
return f;
}
to
public static ShowLstDialog newInstance(ArrayList<SubjSchedule> subj) {
// TODO Auto-generated method stub
ShowLstDialog f = new ShowLstDialog();
subject = subj;
Log.v(TAG, subject.size()+"");
return f;
}
And do read
http://developer.android.com/reference/android/app/DialogFragment.html
Instead of (or in addition to) implementing onCreateView(LayoutInflater, ViewGroup, Bundle) to generate the view hierarchy inside of a dialog, you may implement onCreateDialog(Bundle) to create your own custom Dialog object
So you should use:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
to replace:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
Instead of
public static DialogFragment newInstance(...) {
DialogFragment f = new DialogFragment();
return f;
}
write
public static DialogFragment newInstance(...) {
DialogFragment f = new ShowLstDialog();
return f;
}
and also use Bundle and setArguments, getArguments to pass arguments.
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();