EAMax EAMax -4 years ago 166
Android Question

The error of inflating class fragment android kotlin

So, firstly I answer at your question "Are you really? There are lots of answers on it.". Yes, I know, but I really try to resolve this problem like a third day: in all SOF there are no question on my error. I have 2 similar projects: in Java and in Kotlin. But this f@#^%!@ing error only in Kotlin. But XML is identity 100%.

So, error is:

android.view.InflateException: Binary XML file line #8: Error inflating class fragment
.

My activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/layoutMain"
android:orientation="vertical">

<fragment
android:id="@+id/top_fragment"
android:name="com.example.weatherapp_kotlin.fragments.TopFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</fragment>

<fragment
android:id="@+id/bottom_fragment"
android:name = "com.example.weatherapp_kotlin.fragments.BottomFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4">
</fragment>
</LinearLayout>


What i tried to do:


  • To change
    android:name =""
    in XML to
    class = ""

  • To set
    android:name
    or
    class
    on a first position

  • To change
    LinearLayout
    to
    RelativeLayout
    and
    ConstraintLayout

  • To change class
    extends
    to
    FragmentActivity
    (now is
    Fragment
    and in
    Java it works fine)

  • To clean project



My
LinearLayout
has an
id
, an
orientation
. Path to classes in
android:name
are true.

I try to use fragments by this class:

class StartActivity: Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}}


Maybe it's a hardcode, but in Java it works fine.
I think that I don't need to show
TopFragment.kt
and
BottomFragment.kt
because I tried to tell you everything that I found in SOFs themes. But if you need - I'll show. However, an error is in XML file, so probably XML is the reason.

The complete stacktrace:

06-14 15:24:10.161 25861-25861/com.example.weatherapp_kotlin E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.weatherapp_kotlin, PID: 25861
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.weatherapp_kotlin/com.example.weatherapp_kotlin.StartActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2472)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2534)
at android.app.ActivityThread.access$800(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5550)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)
Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:418)
at android.app.Activity.setContentView(Activity.java:2172)
at com.example.weatherapp_kotlin.StartActivity.onCreate(StartActivity.kt:9)
at android.app.Activity.performCreate(Activity.java:6003)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2425)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2534) 
at android.app.ActivityThread.access$800(ActivityThread.java:174) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5550) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750) 
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
at com.example.weatherapp_kotlin.fragments.TopFragment.onCreateView(TopFragment.kt:0)
at android.app.Fragment.performCreateView(Fragment.java:2069)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:875)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1050)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1152)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2142)
at android.app.Activity.onCreateView(Activity.java:5347)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:418) 
at android.app.Activity.setContentView(Activity.java:2172) 
at com.example.weatherapp_kotlin.StartActivity.onCreate(StartActivity.kt:9) 
at android.app.Activity.performCreate(Activity.java:6003) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2425) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2534) 
at android.app.ActivityThread.access$800(ActivityThread.java:174) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5550) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)  


TopFragment.class:

class TopFragment : Fragment(), SwipeRefreshLayout.OnRefreshListener {

private var outputCity: String = getString(R.string.output_city)
private var outputClouds: String = getString(R.string.output_clouds)
private var outputHumidity: String = getString(R.string.output_humidity)
private var outputPressure: String = getString(R.string.output_pressure)
private var outputWindspeed: String = getString(R.string.output_windspeed)
private var outputMmhg: String = getString(R.string.output_mmHg)
private var outputMs: String = getString(R.string.output_ms)

private var date: Date = Date()
private var dateFormat: SimpleDateFormat = SimpleDateFormat("E, dd.MM")

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle): View? {
return inflater.inflate(R.layout.fragment_top, container, false)
}

override fun onStart() {
super.onStart()

swipeToRefresh.setOnRefreshListener(this)
swipeToRefresh.setColorSchemeColors(Color.GREEN, Color.RED, Color.BLUE, Color.CYAN)

checkInternetConnection(activity)
}

override fun onRefresh() {
Handler().postDelayed({
getData(activity)
swipeToRefresh.setRefreshing(false)
}, 2500)
}

fun checkInternetConnection(c: Context) {
if (InternetConnection().isNetworkAvailable(activity)) {
getData(activity)
} else {
Toast.makeText(activity, "Internet Connection Error", Toast.LENGTH_LONG).show()
}
}

fun getData(c: Context) {
val apiServiceWeather = RetrofitClient().getApiServiceWeather()
val call: Call<WeatherModel> = apiServiceWeather.getMyJSON();
call.enqueue(object: Callback<WeatherModel> {

override fun onResponse(call: Call<WeatherModel>?, response: Response<WeatherModel>?) {
val humidity: Int? = response!!.body().getMainWeather().humidity
val pressure: Float? = response.body().getMainWeather().pressure
val temperature: Float? = response.body().getMainWeather().temp
val windspeed: Float? = response.body().getWind().windspeed
val clouds: Int? = response.body().getClouds().clouds

textViewDate.setText((dateFormat!!.format(date).toString()))
textViewCity.setText(outputCity)
textViewTemp.setText(((Math.rint(temperature!! - 273.15) * 10.0) / 10.0).toString()
+ "°C")
textViewCondition.setText(response.body().getWeather().get(0).description)
textViewClouds.setText(outputClouds + " " + clouds.toString() + "%")
textViewPressure.setText(outputPressure + " " + (Math.round(pressure!! / 1.3332239))
.toString() + " " + outputMmhg)
textViewHumidity.setText(outputHumidity + " " + humidity.toString() + "%")
textViewWindspeed.setText(outputWindspeed + " " + windspeed.toString() + outputMs)
}

override fun onFailure(call: Call<WeatherModel>?, t: Throwable?) {
Toast.makeText(activity, "onResponse Error", Toast.LENGTH_LONG).show()
}
})
}


}

Answer Source

Caused by: java.lang.IllegalStateException: Fragment TopFragment{37d52abb} not attached to Activity
...
at com.example.weatherapp_kotlin.fragments.TopFragment.(TopFragment.kt:24)

I expect that would be the first line of the private vars, where you call getString() to get a String from the resources.

These fields are initialised during object construction, but at this time the fragment is not attached to any Context. getString() needs a Resources objects which comes from the Context.
This crash would happen also if you just create an instance yourself (ie. call it's constructor).

The reason its wrapped an inflate exception is because these fragments are created while parsing the xml layout. It finds the instruction to create and include the fragment, it does so but fails.

Possible solutions

1) Wrap the calls to getString in a lazy delegate. This will delay the call to when the property is first accessed, so you just have to make sure you only access these properties when you are sure the fragment is attached. For example, inside onCreateView().

private var outputCity: String by Delegates.lazy { getString(R.string.output_city) }

2) Mark the variables with lateinit, and initialise when first attached to context. Now you have to make sure you never access the properties before that, or you are greeted with a PropertyNotInitialisedException.

private lateinit var outputCity: String

override fun onAttach(context: Activity) {
    super.onAttach(context)
    outputCity = getString(R.string.output_city)
    ...
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download