在类似条件下转换时出现 textView Nullpointer 异常
textView Nullpointer exception when casted in similar conditions
背景
我正在为标准化片段动态填充 textview 和 imageview。
我没有创建 6 个片段布局和活动,而是创建了 3 个并根据需要设置 text/images。当唯一改变的是 textView 和 imageView 中的文本时,这样我就可以节省时间和内存,而不是为每个 activity 创建一个片段。
问题
当它到达片段 3 时,当实现与 FragmenFirst、FragmentSecond 相同时我得到一个空指针,但我不知道为什么。
代码
填充表格布局的页面适配器
package com.company.app
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
class CustomPageAdapter(FragManager:FragmentManager): FragmentPagerAdapter(FragManager) {
var fragManagerItems:ArrayList<Fragment> = ArrayList()
var fragManagerTitles:ArrayList<String> = ArrayList()
fun removeFragments()
{
fragManagerItems.clear()
}
fun addFragments(fragmentItem:Fragment,fragmentTitle:String)
{
fragManagerItems.add(fragmentItem)
fragManagerTitles.add(fragmentTitle)
override fun getItem(position: Int): Fragment {
return fragManagerItems[position]
}
override fun getCount(): Int {
return fragManagerItems.size
}
override fun getPageTitle(position: Int): CharSequence {
return fragManagerTitles[position]
}
碎片是标准的,没有任何变化
class FragmentFirst : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment "
return inflater!!.inflate(R.layout.fragment_fragment_first, container, false)
}
第二
class FragmentSecond : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_fragment_second, container, false)
}
}
第三
class FragmentThird : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_fragment_third, container, false)
}
}
Main Activity 更改每个
的 textView 的部分
import android.os.Bundle import android.support.design.widget.NavigationView import android.support.design.widget.TabLayout import android.support.v4.view.GravityCompat import android.support.v7.app.ActionBarDrawerToggle import android.support.v7.app.AppCompatActivity import android.view.Menu import android.view.MenuItem import com.company.app.fragments.* import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.app_bar_main.* import kotlinx.android.synthetic.main.content_appbar_main.* import kotlinx.android.synthetic.main.fragment_fragment_first.* import kotlinx.android.synthetic.main.fragment_fragment_second.* import kotlinx.android.synthetic.main.fragment_fragment_third.*
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
var objPageAdapter:CustomPageAdapter?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
...
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
objPageAdapter = CustomPageAdapter(supportFragmentManager)
when (item.itemId) {
R.id.nav_fruits -> {
objPageAdapter!!.removeFragments()
objPageAdapter!!.addFragments(FragmentFirst(),getString(R.string.txt_tab_fruits_Element_1))
objPageAdapter!!.addFragments(FragmentSecond(),getString(R.string.txt_tab_fruits_Element_2))
objPageAdapter!!.addFragments(FragmentThird(),getString(R.string.txt_tab_fruits_Element_3))
ViewPagerMain.adapter = objPageAdapter
TabLayoutMain.setupWithViewPager(ViewPagerMain)
this.textViewFragment_1.text = getString(R.string.txt_txtView_fruits_Element_1)
this.textViewFragment_2.text = getString(R.string.txt_txtView_fruits_Element_2)
this.textViewFragment_3.text = getString(R.string.txt_txtView_fruits_Element_3)
...
错误
Xml 片段 2 和 3 作为样本
片段 2
<?xml version="1.0" encoding="utf-8"?> <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"
tools:context=".fragments.FragmentSecond">
<ImageView
android:id="@+id/imageViewFragment_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_banana" />
<TextView
android:id="@+id/textViewFragment_2"
android:layout_width="match_parent"
android:layout_height="261dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
片段 3
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".fragments.FragmentThird">
<ImageView
android:id="@+id/imageViewFragment_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_banana" />
<TextView
android:id="@+id/textViewFragment_3"
android:layout_width="match_parent"
android:layout_height="261dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
使用的方法
1. Clear/Rebuild 项目
2.Shutdown/Restart电脑
编辑:根据请求,我粘贴我得到的堆栈跟踪
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.company.app, PID: 6790
java.lang.IllegalStateException: this.textViewFragment_3 must not be null
at com.company.app.MainActivity.onNavigationItemSelected(MainActivity.kt:111)
at android.support.design.widget.NavigationView.onMenuItemSelected(NavigationView.java:154)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
at android.support.design.internal.NavigationMenuPresenter.onClick(NavigationMenuPresenter.java:342)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Edit2:致 Rahul 的答案
Main 中的嵌入代码Activity
...
ViewPagerMain.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
private lateinit var fr: Fragment
private lateinit var viewPager: ViewPager
private lateinit var textView1:TextView
private lateinit var textView2:TextView
private lateinit var textView3:TextView
override fun onPageSelected(position: Int) {
when (position) {
0 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.ViewPagerMain + ":" + ViewPagerMain.getCurrentItem())
textView1 = fr.textViewFragment_1
textView1.text= "test1"
}
1 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.ViewPagerMain + ":" + ViewPagerMain.getCurrentItem())
textView2 = fr.textViewFragment_2
textView2.text= "test2"
}
2 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.ViewPagerMain + ":" + ViewPagerMain.getCurrentItem())
textView3.text= "test3"
}
不要在 onCreate 中访问 textView,而是使用 onPageChangeListener 事件
private lateinit var fr: Fragment;
private lateinit var viewPager: ViewPager
private lateinit var textView1:TextView
private lateinit var textView2:TextView
private lateinit var textView3:TextView
override fun onPageSelected(position: Int) {
when (position) {
0 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.getCurrentItem())
textView1 = fr.textViewFragment_1
}
1-> {
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.getCurrentItem())
textView2 = fr.textViewFragment_2
textView2.text = "rr"
}
2-> {
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.getCurrentItem())
textView3= fr.textViewFragment_3
textView3.text = "tt"
}
}
}
override fun onPageScrollStateChanged(state: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
setContentView(R.layout.test_layout)
}
在 onPageselected 中使用这些行来获取当前可见片段的实例
Fragment fr = getSupportFragmentManager().findFragmentByTag(“android:switcher:” + R.id.pager + “:” + mViewPager.getCurrentItem());
现在您可以访问 textview 但请检查 fr instancOf Fragment1
textView1=fr.findViewById(textview1Id) 等等 os........
背景
我正在为标准化片段动态填充 textview 和 imageview。
我没有创建 6 个片段布局和活动,而是创建了 3 个并根据需要设置 text/images。当唯一改变的是 textView 和 imageView 中的文本时,这样我就可以节省时间和内存,而不是为每个 activity 创建一个片段。
问题
当它到达片段 3 时,当实现与 FragmenFirst、FragmentSecond 相同时我得到一个空指针,但我不知道为什么。
代码
填充表格布局的页面适配器
package com.company.app
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
class CustomPageAdapter(FragManager:FragmentManager): FragmentPagerAdapter(FragManager) {
var fragManagerItems:ArrayList<Fragment> = ArrayList()
var fragManagerTitles:ArrayList<String> = ArrayList()
fun removeFragments()
{
fragManagerItems.clear()
}
fun addFragments(fragmentItem:Fragment,fragmentTitle:String)
{
fragManagerItems.add(fragmentItem)
fragManagerTitles.add(fragmentTitle)
override fun getItem(position: Int): Fragment {
return fragManagerItems[position]
}
override fun getCount(): Int {
return fragManagerItems.size
}
override fun getPageTitle(position: Int): CharSequence {
return fragManagerTitles[position]
}
碎片是标准的,没有任何变化
class FragmentFirst : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment "
return inflater!!.inflate(R.layout.fragment_fragment_first, container, false)
}
第二
class FragmentSecond : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_fragment_second, container, false)
}
}
第三
class FragmentThird : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_fragment_third, container, false)
}
}
Main Activity 更改每个
的 textView 的部分import android.os.Bundle import android.support.design.widget.NavigationView import android.support.design.widget.TabLayout import android.support.v4.view.GravityCompat import android.support.v7.app.ActionBarDrawerToggle import android.support.v7.app.AppCompatActivity import android.view.Menu import android.view.MenuItem import com.company.app.fragments.* import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.app_bar_main.* import kotlinx.android.synthetic.main.content_appbar_main.* import kotlinx.android.synthetic.main.fragment_fragment_first.* import kotlinx.android.synthetic.main.fragment_fragment_second.* import kotlinx.android.synthetic.main.fragment_fragment_third.*
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
var objPageAdapter:CustomPageAdapter?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
...
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
objPageAdapter = CustomPageAdapter(supportFragmentManager)
when (item.itemId) {
R.id.nav_fruits -> {
objPageAdapter!!.removeFragments()
objPageAdapter!!.addFragments(FragmentFirst(),getString(R.string.txt_tab_fruits_Element_1))
objPageAdapter!!.addFragments(FragmentSecond(),getString(R.string.txt_tab_fruits_Element_2))
objPageAdapter!!.addFragments(FragmentThird(),getString(R.string.txt_tab_fruits_Element_3))
ViewPagerMain.adapter = objPageAdapter
TabLayoutMain.setupWithViewPager(ViewPagerMain)
this.textViewFragment_1.text = getString(R.string.txt_txtView_fruits_Element_1)
this.textViewFragment_2.text = getString(R.string.txt_txtView_fruits_Element_2)
this.textViewFragment_3.text = getString(R.string.txt_txtView_fruits_Element_3)
...
错误
Xml 片段 2 和 3 作为样本
片段 2
<?xml version="1.0" encoding="utf-8"?> <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"
tools:context=".fragments.FragmentSecond">
<ImageView
android:id="@+id/imageViewFragment_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_banana" />
<TextView
android:id="@+id/textViewFragment_2"
android:layout_width="match_parent"
android:layout_height="261dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
片段 3
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".fragments.FragmentThird">
<ImageView
android:id="@+id/imageViewFragment_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_banana" />
<TextView
android:id="@+id/textViewFragment_3"
android:layout_width="match_parent"
android:layout_height="261dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
使用的方法
1. Clear/Rebuild 项目
2.Shutdown/Restart电脑
编辑:根据请求,我粘贴我得到的堆栈跟踪
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.company.app, PID: 6790
java.lang.IllegalStateException: this.textViewFragment_3 must not be null
at com.company.app.MainActivity.onNavigationItemSelected(MainActivity.kt:111)
at android.support.design.widget.NavigationView.onMenuItemSelected(NavigationView.java:154)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
at android.support.design.internal.NavigationMenuPresenter.onClick(NavigationMenuPresenter.java:342)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Edit2:致 Rahul 的答案
Main 中的嵌入代码Activity
...
ViewPagerMain.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
private lateinit var fr: Fragment
private lateinit var viewPager: ViewPager
private lateinit var textView1:TextView
private lateinit var textView2:TextView
private lateinit var textView3:TextView
override fun onPageSelected(position: Int) {
when (position) {
0 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.ViewPagerMain + ":" + ViewPagerMain.getCurrentItem())
textView1 = fr.textViewFragment_1
textView1.text= "test1"
}
1 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.ViewPagerMain + ":" + ViewPagerMain.getCurrentItem())
textView2 = fr.textViewFragment_2
textView2.text= "test2"
}
2 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.ViewPagerMain + ":" + ViewPagerMain.getCurrentItem())
textView3.text= "test3"
}
不要在 onCreate 中访问 textView,而是使用 onPageChangeListener 事件
private lateinit var fr: Fragment;
private lateinit var viewPager: ViewPager
private lateinit var textView1:TextView
private lateinit var textView2:TextView
private lateinit var textView3:TextView
override fun onPageSelected(position: Int) {
when (position) {
0 ->{
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.getCurrentItem())
textView1 = fr.textViewFragment_1
}
1-> {
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.getCurrentItem())
textView2 = fr.textViewFragment_2
textView2.text = "rr"
}
2-> {
fr = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager.getCurrentItem())
textView3= fr.textViewFragment_3
textView3.text = "tt"
}
}
}
override fun onPageScrollStateChanged(state: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
setContentView(R.layout.test_layout)
}
在 onPageselected 中使用这些行来获取当前可见片段的实例
Fragment fr = getSupportFragmentManager().findFragmentByTag(“android:switcher:” + R.id.pager + “:” + mViewPager.getCurrentItem());
现在您可以访问 textview 但请检查 fr instancOf Fragment1 textView1=fr.findViewById(textview1Id) 等等 os........