填充 ListView 很慢,Fragment 加载不顺畅
Posted
技术标签:
【中文标题】填充 ListView 很慢,Fragment 加载不顺畅【英文标题】:Populating ListView is slow, Fragment not loading smoothly 【发布时间】:2020-04-17 01:10:43 【问题描述】:所以我正在使用 androidStudio 并在 Kotlin 中编写我的代码。 我有一个带有 TabLayout 和 ViewPager 的片段,它有 5 个标签。每个选项卡都包含另一个带有 ListView 和 ToggleButton 的 Fragment。 ListViews 都包含 10 个项目。 Here is a screenshot, I'm not allowed to use embed images yet
问题是Fragment打开不顺畅,尤其是先打开的时候。
我认为问题在于 5 个选项卡中 ListViews 的 ListViewAdapter 的实现,尤其是 getView 函数。 这是他们的代码:
inner class TimetableListAdapter(
private val _context : Context,
private var fulldata : TimetableUtility.TimetableDay,
var bWeek : Boolean,
private var dayData : ArrayList<TimetableUtility.TimetableSubject> = fulldata[0],
private val _resource : Int = R.layout.timetable_subject_element
) : ArrayAdapter<TimetableUtility.TimetableSubject>(_context, _resource, dayData)
init
dayData = if(bWeek)
fulldata[1]
else
fulldata[0]
Log.d("Timetable" , "Adapter init ")
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View
Log.d("Timetable" , "getView: $bWeek")
val s : TimetableUtility.TimetableSubject = if(bWeek)
dayData = fulldata[1]
fulldata[1][position]
else
dayData = fulldata[0]
fulldata[0][position]
val v =
convertView
?: LayoutInflater.from(_context).inflate(
_resource,
parent,
false
)
v.editIcon.setOnClickListener
openEditDialog(this@TimetableDayFragment.context!!,s)
v.timetable_hour_number.text = (position + 1).toString()
v.timetable_subject_title.text = s.name
v.timetable_subject_room.text = s.room
return v
我知道 ViewHolder 模式的实现会减少视图搜索调用的次数,但我认为这不会影响初始生成。
我在 AndroidStudio 中使用 Profiler 玩了一下,发现在我的电脑上的虚拟机上运行应用程序时,适配器的 getView 方法大约需要 20-30 毫秒。在我的三星设备(Galaxy A6,不是那么旧)上运行应用程序时,它会更多,因为延迟更大。我还没有使用分析器。
我的假设是,getView 方法导致的延迟是否正确,如果是,您对如何改进有任何建议或想法?
如果有帮助,这里是 ViewPager 适配器的代码:
inner class TimetableFragmentAdapter(
context : Context,
fm : FragmentManager,
private val totalTabs : Int
) : FragmentPagerAdapter(fm,totalTabs)
private val dayTitles = arrayOfNulls<String>(5)
private var sdf =
SimpleDateFormat("EEE", Locale.getDefault())
private var calendar = Calendar.getInstance()!!
init
for (i in 0..4)
calendar.set(Calendar.DAY_OF_WEEK, i + 2)
dayTitles[i] = sdf.format(calendar.time)
override fun getCount(): Int
return totalTabs
override fun getPageTitle(position: Int): CharSequence?
return dayTitles[position]
@RequiresApi(Build.VERSION_CODES.O)
override fun getItem(position: Int): Fragment
when(position)
0 -> return TimetableDayFragment(DayOfWeek.MONDAY, this@TimetableFragment)
1 -> return TimetableDayFragment(DayOfWeek.TUESDAY, this@TimetableFragment)
2 -> return TimetableDayFragment(DayOfWeek.WEDNESDAY, this@TimetableFragment)
3 -> return TimetableDayFragment(DayOfWeek.THURSDAY, this@TimetableFragment)
4 -> return TimetableDayFragment(DayOfWeek.FRIDAY, this@TimetableFragment)
return TimetableDayFragment(DayOfWeek.MONDAY, this@TimetableFragment)
以及用于每个选项卡的内部片段的创建代码
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View?
val root = inflater.inflate(R.layout.timetable_inner_fragment,container,false)
adapter = TimetableListAdapter(context!!, TimetableUtility.timetable.get(day), root.weekSwitch.isChecked)
root.timetable_list.adapter = adapter
root.weekSwitch.setOnCheckedChangeListener
it, selected ->
(root.timetable_list.adapter as TimetableListAdapter).bWeek = selected
(root.timetable_list.adapter as TimetableListAdapter).notifyDataSetChanged()
return root
非常感谢您提前提供的帮助和想法。 如果您需要更多代码或信息,请告诉我。
【问题讨论】:
【参考方案1】:在你的TimetableFragmentAdapter
覆盖destroyItem()
@Override
public void destroyItem(ViewGroup container, int position, Object object)
// destroy your fragment view here
关注这个问题How to remove fragment from fragmentPagerAdapter
【讨论】:
感谢您的回答。我应该如何销毁片段?你能解释一下这如何有助于解决问题吗?我还没收到呢。以上是关于填充 ListView 很慢,Fragment 加载不顺畅的主要内容,如果未能解决你的问题,请参考以下文章
从 Activity 完成异步后在 Fragment 上填充 ListView
从 Parent 为 Fragment 的 ListView 设置适配器
安卓开发 viewpage加fragment加listview. 我想实现一个类似微信的界面。
求教android studio大神:用fragment写一个导航栏,在每个fragment里面加listview,能实现点击事件
安卓ScrollView中放ViewPager+ViewPager,ViewPager中放的是2个Fragment,Fragment中放Listview.