No view found for fragment on rotation - android

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.

Related

How can i call a method in my fragment from my activity?

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;
}

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();
}

Using findFragmentById with a ViewPager

My app has a list and detail view, where I allow the user to swipe between the different detail views, using a ViewPager in portrait. In landscape, I show both fragments on the screen.
I'm having an issue where, when the device is rotated, the icons are duplicating themselves over and over in the Actionbar. I've learned that I'm probably creating new fragments whenever the device is rotated and I should be checking if the fragment is in the FragmentManager and then create a new instance if it isn't.
I am able to do that easily using the landscape layout, however, I'm not sure how to check if the fragment exists in portrait mode, using the ViewPager. Do I do that in getItem() of the FragmentStatePagerAdapter?
This is the code I'm using:
public class Main extends SherlockFragmentActivity
{
private static List<Integer> mIds;
#Override
public void onCreate(final Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
mViewPager = (ViewPager)findViewById(R.id.viewpager); //view pager exists, so we are using the portait layout
if (mViewPager != null)
{
mIds = new ArrayList<Integer>();
mIds.add(0);
mIds.add(1);
mIds.add(2);
}
else //in landscape
{
ListFragment lf = (ListFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentList);
if (lf == null)
lf = new ListFragment();
DetailFragment df = (DetailFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentDetail);
if (df == null)
{
df = new DetailFragment();
df.setArguments(getIntent().getExtras());
}
getSupportFragmentManager().beginTransaction().add(R.id.fragmentList, lf).commit();
getSupportFragmentManager().beginTransaction().add(R.id.fragmentDetail, df).commit();
}
}
private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
//can't use getSupportFragmentManager().findFragmentById() here because I get a "Cannot make a static reference to the non-static method" error
if (index == 0)
return ListFragment.newInstance();
else
return DetailFragment.newInstance(mIds.get(index-1));
}
#Override
public int getCount() {
return 4;
}
}
}
Main Layout (portrait)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</RelativeLayout>
Main Layout (landscape)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:weightSum="3"
>
<FrameLayout
android:id="#+id/fragmentList"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="fill_parent"
/>
<FrameLayout
android:id="#+id/fragmentDetail"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="fill_parent"
/>
</LinearLayout>
List Fragment
public class ListFragment extends SherlockListFragment implements DialogKeywordAddListener
{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
public static ListFragment newInstance() {
return new ListFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.listing, container, false);
}
}
Detail Fragment
public class DetailFragment extends SherlockListFragment
{
private int mId;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
public static DetailFragment newInstance() {
DetailFragment df = new DetailFragment();
Bundle bundle = new Bundle();
bundle.putInt("id", id);
df.setArguments(bundle);
return df;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
if (getArguments() != null)
mId = getArguments().getInt("id");
return inflater.inflate(R.layout.detail, container, false);
}
}
Well, this question's solution seemed to work for me. Just setting:
super.onCreate(null);
in onCreate of the Activity solved my fragment issue.

achartengine: How to add chart to fragment in Tabs

I want to show a Button and a PieChart below in a tab.
Thats the code I worked with: https://github.com/JakeWharton/ActionBarSherlock/blob/master/samples/fragments/src/com/actionbarsherlock/sample/fragments/FragmentTabs.java
Instead of the CountingFragment etc. I implemented my own.
I'm not sure what to
My xml:
fragment_graph_categories.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_graph_categories"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_filter" />
</LinearLayout>
And that's my "Tab" attached to the TabManger
public class GraphCategories extends SherlockFragmentActivity {
GraphCategoriesFragment mCategoriesFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_graph_categories);
if (savedInstanceState == null) {
// Do first time initialization -- add initial fragment.
mCategoriesFragment = GraphCategoriesFragment.newInstance(1);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment_graph_categories, mCategoriesFragment).commit();
} else {
//mStackLevel = savedInstanceState.getInt("level");
}
}
#Override
protected void onResume() {
if(mCategoriesFragment != null) {
//mCategoriesFragment.onResumeRedraw();
}
}
//notice Inner class
public static class GraphCategoriesFragment extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//View mChartView = inflater.inflate(R.layout.hello_world, container, false);
View rlayout = inflater.inflate(R.layout.fragment_graph_categories, container, false);
//? rlayout = new LinearLayout(getActivity());
return rlayout;
}
}
}
But im not sure what to inflate at the fragments onCreateView or if I need a FrameLayout in my xml?
I tried some options but don't figured it out.

Categories

Resources