![](/img/trans.png)
[英]java.lang.IllegalStateException: Fragment not attached to a context
[英]How to fix java.lang.IllegalStateException: Fragment not attached to a context
我的應用程序有一個帶有一堆片段的 ViewPager,當在 Fragment1 中單擊一個按鈕時,執行操作並出現一個 TransitionFragment,當在 TransitionFragment 中單擊一個按鈕時,ViewPager 過渡到 Fragment3,這就是我實現它的方式: MainActivity .class
class MainActivity : AppCompatActivity() {
private var mAdView: AdView? = null
@SuppressLint("ResourceType")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adRequest = AdRequest.Builder().build()
mAdView = findViewById(R.id.adView)
mAdView!!.loadAd(adRequest)
initTab()
}
fun initTab() {
tab_layout.addTab(tab_layout.newTab().setIcon(R.drawable.image1)
tab_layout.addTab(tab_layout.newTab().setIcon(R.drawable.image2)
tab_layout.addTab(tab_layout.newTab().setIcon(R.drawable.image3)
tab_layout.tabGravity = TabLayout.GRAVITY_FILL
val adapter = MyPagerAdapter(supportFragmentManager, tab_layout.tabCount)
pager.adapter = adapter
pager.offscreenPageLimit = 2
pager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tab_layout))
tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
pager.currentItem = tab.position
if (tab.position == 0) {
tab_layout.getTabAt(0)!!.setIcon(R.drawable.image1_focus)
if (getSupportFragmentManager().findFragmentById(R.id.frame) != null) {
getSupportFragmentManager().popBackStack();
}
}
if (tab.position == 1) {
tab_layout.getTabAt(1)!!.setIcon(R.drawable.image2_focus)
if (getSupportFragmentManager().findFragmentById(R.id.frame) != null) {
getSupportFragmentManager().popBackStack();
}
}
if (tab.position == 2) {
tab_layout.getTabAt(2)!!.setIcon(R.drawable.image3_focus)
if (getSupportFragmentManager().findFragmentById(R.id.frame) != null) {
getSupportFragmentManager().popBackStack();
}
}
}
override fun onTabUnselected(tab: TabLayout.Tab) {
if (tab.position == 0) tab_layout.getTabAt(0)!!.setIcon(R.drawable.image1)
if (tab.position == 1) tab_layout.getTabAt(1)!!.setIcon(R.drawable.image2)
if (tab.position == 2) tab_layout.getTabAt(2)!!.setIcon(R.drawable.image3)
}
override fun onTabReselected(tab: TabLayout.Tab) {
}
})
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/mainlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@color/transparent"
app:adSize="SMART_BANNER"
app:adUnitId="@string/banner_key"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
style="@style/MyToolbar"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_marginTop="2dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/adView"
app:popupTheme="@style/AppTheme.PopupOverlay">
<TextView
android:id="@+id/toolbar_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="@font/sf_pro_display_regular"
android:textColor="@color/black"
android:textSize="24sp"
tools:layout_editor_absoluteX="206dp"
tools:layout_editor_absoluteY="7dp" />
</androidx.appcompat.widget.Toolbar>
<androidx.viewpager.widget.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@+id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
</LinearLayout>
</FrameLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#fff"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:tabBackground="@drawable/tab_color_selector"
app:tabIndicatorColor="#2196F3"
app:tabIndicatorGravity="top"
app:tabIndicatorHeight="4dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
片段1.class
class Fragment1 : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment1, container, false)
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
optbutton.setOnClickListener {
val transitionFragment: TransitionFragment = TransitionFragment().newInstance(2)!!
val trans = fragmentManager!!.beginTransaction()
trans.replace(R.id.frame, transitionFragment)
trans.addToBackStack(null)
trans.commit()
}
}
}
Fragment1和TransitionFragment只有一個按鈕TransitionFragment.class
class TransitionFragment() : Fragment() {
private var index: Int = 0
fun newInstance(index: Int): TransitionFragment? {
val fragment = TransitionFragment()
val args = Bundle()
args.putInt("index", index)
fragment.setArguments(args)
return fragment
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.transition_fragment, container, false)
val trans_btn: Button = view.findViewById(R.id.trans_btn)
if (getArguments() != null) {
index = getArguments()!!.getInt("index")
}
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
trans_btn.setOnClickListener {
val tabs: TabLayout = activity!!.findViewById(R.id.tab_layout)
tabs.getTabAt(index)!!.select()
}
}
}
一切正常,但在極少數情況下,指標會收到如下崩潰通知:
java.lang.IllegalStateException: Fragment e{2dc5257 (30032337-24f8-4d9a-9da9-9db92da88082)} not attached to a context.
at androidx.fragment.app.d.q(Unknown Source)
at androidx.fragment.app.d.u(Unknown Source)
at androidx.fragment.app.d.a(Unknown Source)
at {packageWithFragment}.e.aE(Unknown Source)
at {packageWithFragment}.e.c(Unknown Source)
at {packageWithFragment}.e$f.b(Unknown Source)
at com.hookedonplay.decoviewlib.b.a.n(Unknown Source)
at com.hookedonplay.decoviewlib.a.b$2.a(Unknown Source)
at com.a.a.j.n(Unknown Source)
at com.a.a.j.c(Unknown Source)
at com.a.a.j$a.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:6102)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:961)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:822)
我無法弄清楚錯誤在哪里以及導致崩潰的原因。 請告訴我可能出了什么問題以及如何正確解決?!
我有一種類似的情況:當我從一個片段返回時,我崩潰了,並且遇到了和你一樣的錯誤。
我做了一個簡單的檢查並將Log.i ("info", x)
放在fragment
代碼中的每幾行之后,並且還覆蓋onStop
並將Log
放入其中(每次增加 x)。 令人驚訝的是,我發現片段代碼在onStop
之后繼續運行,並且在獲得Textview
等view
時崩潰了,因為Fragment Context
現在是 NULL ......(在我的情況下,這是因為我有一個調用firebase 數據庫,拉取數據然后寫入視圖。需要一段時間,如果我在此過程結束之前離開片段,則視圖為空)。
我進行了很多搜索,但找不到任何信息或其他有關它的問題……很奇怪。
我的靈魂:我做了一個 boolean 標志,在onCreateView
用true
初始化它,在onStop
給它分配false
。 現在,在我調用代碼的任何視圖之前,我驗證標志不是假的。 這解決了我的崩潰問題。
我仍然很高興了解這個生命周期以及為什么Fragment
代碼在onStop
之后繼續運行......我希望我能幫助你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.