MyFragment.java
public class MyFragment extends Fragment {
private onItemSelectedListener listener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container,
false);
btn_myButton = (Button) view.findViewById(R.id.btn_new_client);
btn_myButton .setOnClickListener(new OnClickListener() {
public void onClick(View v) {
updateDetail("New Layout");
}
});
return view;
}
Button btn_myButton;
public interface onItemSelectedListener {
public void onItemSelected(String link);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof onItemSelectedListener) {
listener = (onItemSelectedListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet OnItemSelectedListener");
}
}
public void updateDetail(String s) {
listener.onItemSelected(s);
}
}
MainActivity.java
public class MainActivity extends Activity implements
onItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.main_activity);
super.onCreate(savedInstanceState);
}
public void onItemSelected(String link) {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
Fragment fragment;
if ("New Layout".equals(link)) {
fragment = new Fragment1();
transaction.replace(R.id.detailFragment, fragment);
transaction.commit();
}
}
}
Fragment1.java
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.newfragmentt, container,
false);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
fragment.xml
<?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" >
<Button
android:id="@+id/btn_new_client"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="8"
android:gravity="center|center_vertical"
android:padding="2dp"
android:text="@string/new_client"
android:textColor="#FFFFFF" >
</Button>
</LinearLayout>
main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#4B6C9E"
android:baselineAligned="false"
android:orientation="horizontal" >
<fragment
android:id="@+id/FragmentId"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
class="com.examples.MyProject.MyFragment" >
</fragment>
<FrameLayout
android:id="@+id/detailFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" >
</FrameLayout>
</LinearLayout>
LogCat error:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.elintsys.iCaseDiary/com.examples.MyProject.MainActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
at android.app.Activity.setContentView(Activity.java:1862)
at com.examples.MyProject.MainActivity.onCreate(CaseEntryActivity.java:15)
at android.app.Activity.performCreate(Activity.java:4492)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
... 11 more
Caused by: java.lang.IllegalStateException: Fragment com.elintsys.iCaseDiary.CaseEntryFragment did not create a view.
at android.app.Activity.onCreateView(Activity.java:4293)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
... 21 more
Sending signal. PID: 16275 SIG: 9
Please help me friends.
Using the support library, fragments are supported back to all relevant Android versions. Fragments encapsulate views and logic so that it is easier to reuse within activities. Fragments are standalone components that can contain views, events and logic.
If the fragment does not have any UI, it will return null.
However, a fragment is not required to be a part of the activity layout; you may also use a fragment without its own UI as an invisible worker for the activity.
You can return null if the fragment does not provide a UI.
You need to reverse this:
setContentView(R.layout.main_activity);
super.onCreate(savedInstanceState).
into this:
super.onCreate(savedInstanceState).
setContentView(R.layout.main_activity);
in your activity's onCreate
.
I was also getting this error, even though I was calling setContentView after super.onCreate. In my case I was setting up a worker fragment in my super class' onCreate method, which was being called before setContentView and triggering the bug documented here:
https://code.google.com/p/android/issues/detail?id=22564
I had to move initialization of the worker fragment into a separate method called later in the activity lifecycle to work around this.
By request, here is what that code looks like:
public class BaseActivity extends ActionBarActivity {
private static final String TAG_TASK_FRAGMENT = "task_fragment";
protected TaskFragment taskFragment; // Used to hold a reference to the active activity between config changes
protected void setupTaskFragment() {
// It would be great if we could just do this in onCreate, but setting up the task fragment
// before calling setContentView() triggers the bug described here:
//
// https://code.google.com/p/android/issues/detail?id=22564
//
// So we just need to make sure Activities that run async tasks call this setup function
// before they do.
FragmentManager fm = getSupportFragmentManager();
taskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);
// If the Fragment is non-null, then it is currently being
// retained across a configuration change.
if (taskFragment == null) {
taskFragment = new TaskFragment();
fm.beginTransaction().add(taskFragment, TAG_TASK_FRAGMENT).commit();
fm.executePendingTransactions();
}
}
}
public class ChildActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // If this call adds a fragment, you will have problems
setContentView(R.layout.activity_child);
setupTaskFragment(); // So we have to add our task fragment here, after we've called setContentView()
// further initialization here
}
}
/**
*
* TaskFragment
*
* We use this fragment to manage async tasks between configuration changes. The fragment calls
* setRetainInstance(true) in its constructor, which makes it so that it will not be recreated
* between configuration events (like screen rotation). Async tasks running from the fragment
* can then be kept up to date on which activity they belong to.
*/
public class TaskFragment extends Fragment {
private ArrayList<AsyncTask> asyncTasks = new ArrayList<AsyncTask>();
public TaskFragment() {
super();
setRetainInstance(true);
}
public void addTask(AsyncTask task) {
asyncTasks.add(task);
}
public void removeTask(AsyncTask task) {
asyncTasks.remove(task);
}
public Application getApplication() {
Activity activity = getActivity();
if (activity != null)
return activity.getApplication();
else
return null;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
for (AsyncTask task : asyncTasks) {
task.onAttach(activity);
}
}
@Override
public void onDetach() {
super.onDetach();
for (AsyncTask task : asyncTasks) {
task.onDetach();
}
}
}
In addition to what Mel Stanley said you also need to ensure that you add the android:tag to your xml activity where the fragment is loaded:
<fragment
android:id="@+id/fragment_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:name="com.your_app.name.fragments.NameOfFragment"
android:tag="fragment_tag"
tools:layout="@layout/layout_fragment"
/>
This ensures that when the fragment is being loaded for the first time using the xml it is not reloaded using Mel's code. If you left this out you would have 2 loads of the fragment on first run - this is a problem if you have asynchronous requests that change the layout upon completion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With