I am working on Fragments in Android and would like to programmatically inflate my view - without the LayoutInflater. In my class, which extends Fragment, I would like to do something basic, like this:
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return new View(inflater.getContext());
}
However in my FragmentActivity with this onCreate method:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
and this main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<fragment class="edu.self.myFragment"
android:id="#+id/titles"
android:tag="foo"
android:layout_width="50px"
android:layout_height="50px" />
</LinearLayout>
I am getting an error with the layout:
11-11 23:25:18.142: E/AndroidRuntime(1162): Caused by: java.lang.IllegalArgumentException: Binary XML file line #12: Duplicate id 0x7f050000, tag foo, or parent id 0x0 with another fragment for edu.self.myFragment
What do I need to do to fix this error?
You can't inflate an xml containing a fragment inside another fragment. You have to add the sub-fragment manually.
Related
I have made a ListView on a Fragment.
public class MyList extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.mylist, container, false);
return view;
}
}
This is the xml file where is the ListView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ddffff"
xmlns:app="http://schemas.android.com/apk/res-auto"
>>
<android.support.wearable.view.WearableListView
android:id="#+id/mylist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"></android.support.wearable.view.WearableListView>
</android.support.wearable.view.BoxInsetLayout>
When I run my app the listview does not appear. The entire screen is black. What I want to know is why this is happening.
Because of the typo in the following line:
xmlns:app="http://schemas.android.com/apk/res-auto"
>>
It cannot read >>. Android doesn't throw an exception for this typo
I have a Fragment in my MainActivity, that displays a Digital Clock. It works: It shows the current system time. But it looks rather simple. So before I start trying to style this clock I wanted to ask, if there is a way, to use the systems Digital-Clock Widget?
Screenshot of the widget, that I'd like to use in my Fragment:
FragmentClock.java:
public class FragmentClock extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_clock, container, false);
return view;
}
}
fragment_clock.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayoutClockDisplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000000">
<DigitalClock
android:id="#+id/digital_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"/>
</LinearLayout>
I am trying to implement a basic fragment in and activity and it is throwing an error:
Here are my classes:
fragment class:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout._fragment_dds_image, container, false);
return view;
}
}
My Fragment XML file:
<?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:background="#0000FF"
android:orientation="vertical" >
My activity that is trying to display the fragment:
public class DDSViewActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ddsview);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.ddsview, menu);
return true;
}}
The XML file for the activity:
<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" >
<fragment
android:id="#+id/fragment1"
android:name="dds.MyFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
When i run this, it gives em the following error:
Unable to start activty ComponentInfo{com.example.electronicmenu/dds.DDSViewActivity}: android.view.InflateException: binary xml file line #10: Error inflating class fragment.
link to full stack trace:
Use the fully qualified name of your fragment class, e.g. com.example.myapp.dds.MyFragment
<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" >
<fragment
android:id="#+id/fragment1"
android:name="com.example.myapp.dds.MyFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
I tried changing the background color of a fragment, but a small problem occurred.
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
So, shown above is the code I had for my main class that calls the XML file for the fragment.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/fragment1"
android:name="com.northreal.practice.FirstFragment"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#CBA" />
</LinearLayout>
Above is the main.xml layout that is called by the main class (MainActivity).
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main, parent, false);
}
}
Above the XML file with the fragment calls this class.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BLAHHHH"
android:layout_gravity="center_vertical" />
</LinearLayout>
This layout above is inflated by the class FirstFragment
So, why doesn't this actually change the color of the background of my fragment?
Fragments don't inherit from View and thus don't have a set background method.
Any easy fix is to just grab the root view of fragment and set its background
fragment.getView().setBackgroundColor(Color.WHITE);
The reason why that doesn't work is because fragment is treated similar to an activity. It is a container that is the child of the main activity, and is used to display other items.
You need to put the android:background="#CBA" in the actual layout that holds the TextView and NOT the fragment itself.
Like so:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CBA"
android:orientation="horizontal" >
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="BLAHHHH" />
</LinearLayout>
Get the fragment object like:
Fragment fragment = (Fragment) getFragmentManager().findFragmentById(R.id.fragmentId);
Change it's background like:
fragment.getView().setBackgroundColor(Color.WHITE);
In AndroidX you can use a FragmentContainerView instead of a Fragment to set a background:
<androidx.fragment.app.FragmentContainerView
...
android:background="#FFFFFF"/>
I have faced the same problem but my requirement was to set or change background drawable image of fragment. As Adam answered the approach is right and I would like to show the connection from fragment to activity.
The best practice is to use an interface named 'Connector'(or any name).Then from your fragment:
Connector connector = (Connector) getActivity();
connector.setIt(this);
Then in your activity which will implement 'Connector' interface and have the method.
#Override
public void setIt(Fragment fragment){
FirstFragment firstFrag = (FirstFragment) getSupportFragmentManager().findFragmentByTag("first");
firstFrag.getView().setBackgroundDrawable(getResources().getDrawable(R.drawable.app_background));
//or for color set
firstFrag.getView().setBackgroundColor(Color.WHITE);
}
This is related to several posts, but I don't see anything that explains the order of view creation in the view hierarchy (static - xml and dynamic - in code).
I have a FragmentActivity hosting an Activity and a Fragment. I'm getting a runtime error from a view not being created for the fragment before the fragment's onCreateView is called. It's difficult to determine what the calling method is that can't find the view as the debugger can't seem to find the right line-numbers during step-through.
I can't get the source to attach correctly to see inside FragmentManager as there seems to be a mismatch between the dl'd source and .jar
I placed a Log.i entry in StreamingActivity.onCreateView and the error occurs before that.
Here is the relevant LogCat:
07-19 10:13:36.091: I/StreamingActivity(9886): onCreate
07-19 10:13:42.271: W/dalvikvm(9886): threadid=1: thread exiting with uncaught exception (group=0x40020560)
07-19 10:13:42.281: E/AndroidRuntime(9886): FATAL EXCEPTION: main
07-19 10:13:42.281: E/AndroidRuntime(9886): java.lang.RuntimeException: Unable to start activity
ComponentInfo{kesten.fragmentstestbed/kesten.fragmentstestbed.FragmentsMainActivity}:
java.lang.IllegalArgumentException: No view found for id 0x7f05002e for fragment
StreamingActivity{4052f810 #0 id=0x7f05002e}
caused by
java.lang.IllegalArgumentException: No view found for id 0x7f05002e for fragment
StreamingActivity{40530948 #0 id=0x7f05002e}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:865)
my java file snippets:
public class FragmentsMainActivity extends FragmentActivity {
public final static int STARTUP_ACTIVITY_RESULT=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragments_main);
if(savedInstanceState == null) {
Intent intentStartupActivity = new Intent(this, StartupActivity.class);
if(intentStartupActivity != null)
startActivityForResult(intentStartupActivity, STARTUP_ACTIVITY_RESULT);
// get an instance of FragmentTransaction from your Activity
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
//add a fragment
StreamingActivity streamingActivity = new StreamingActivity();
if (streamingActivity != null) {
fragmentTransaction.add(R.id.streamingactivity, streamingActivity);
fragmentTransaction.commit();
}
}
}
my Fragment:
public class StreamingActivity extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StreamingActivity","onCreate")
}
my layout files:
"res/layout/main.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"
>
<FrameLayout
android:id="#+id/streamingactivity"
android:layout_width="0px"
android:layout_height="match_parent">
</FrameLayout>
<!-- IMU -->
<TextView
android:id="#+id/imu_label"
style="#style/Label.Title"
android:text="#string/imu"
/>
<kesten.fragmentstestbed.ImuView
android:id="#+id/imu_values"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imu_label"
android:text=""
/>
<!-- Accelerometer -->
<TextView
android:id="#+id/accelerometer_label"
style="#style/Label.Title"
android:text="#string/accelerometer"
android:layout_below="#+id/imu_values"
/>
<!-- Filtered -->
<kesten.fragmentstestbed.CoordinateView
android:id="#+id/accelerometer_filtered_coordinates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/accelerometer_label"
android:text="#string/filtered"
/>
</RelativeLayout>
and "activity_fragments_main.xml" for my FragmentActivity
<RelativeLayout 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" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="#dimen/padding_medium"
android:text="#string/hello_world"
tools:context=".FragmentsMainActivity" />
</RelativeLayout>
Possible causes of id not found error gleaned from other Stackoverflow threads:
wrong layout in setContentView() of the onCreate() method of the FragmentActivity.
I checked and my xml files are all there. Maybe there's a syntax error or missing linked resource, but i can't see it. I understand the HierarchyViewer would be a useful tool to debug the UI, but i can't get it working.
the id passed into FragmentTransaction.add must be a child of the layout specified in setContentView.
my FragmentActivity's onCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragments_main);
my Fragment's onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("StreamingActivity","onCreateView");
View view = inflater.inflate(R.layout.main, container, false);
I presume that the LayoutManager passes the correct value for container, i.e., the one set in FragmentActivity's setContentView(). But we never make it there anyway. The error in the logCat occurs before we enter onCreateView().
The only thing i can think of atm is that the startupActivity (which is closed third party) called after setContentView and before StreamingActivity sets the content view to something besides R.layout.activity_fragments_main which is not a parent of my fragment's view.
The problem seems to stem from the fact that while Activity has setContentView which can be called whenever, Fragment only has onCreateView() which gets called after fragment transactions that start the fragment.
Why and what is trying to access the fragment's view before onCreateView() is called?
darKoram
The TextView in activty_fragments_main has no id. I ran into a similar error, and added an id, and all of a sudden things started working...
the following FrameLayout should be in activty_fragments_main
<FrameLayout
android:id="#+id/streamingactivity"
android:layout_width="0px"
android:layout_height="match_parent">
</FrameLayout>
the below function adds a fragment inside the layout provided in the first aurgument:
fragmentTransaction.add(R.id.streamingactivity, streamingActivity);
So try changing:
<RelativeLayout 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" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="#dimen/padding_medium"
android:text="#string/hello_world"
tools:context=".FragmentsMainActivity" />
</RelativeLayout>
to:
<RelativeLayout 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" >
<FrameLayout
android:id="#+id/streamingactivity"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
In FragmentMainActivity you are adding fragment to to id streamingactivity
fragmentTransaction.add(R.id.streamingactivity, streamingActivity);
and "activity_fragments_main.xml" for my FragmentMainActivity
<RelativeLayout 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" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="#dimen/padding_medium"
android:text="#string/hello_world"
tools:context=".FragmentsMainActivity" />
</RelativeLayout>
//your layout must contains a FrameLayout with id streamingactivity .you Activity must contains
<FrameLayout
android:id="#+id/streamingactivity"
....
..>
And your StreamingActivity which is a Fragment must import android.support.v4.Fragment. And must implement onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main, container, false);
}
Or One more problem may be . Your have interchanged the LayoutId of Fragment and Activity. As your names look like