gpt4 book ai didi

Android - ListView 中的延迟点击

转载 作者:IT老高 更新时间:2023-10-28 23:11:47 26 4
gpt4 key购买 nike

我的应用中有以下结构:

FragmentActivity 与 ViewPager 持有由 FragmentStatePagerAdapter 管理的多个 fragment ,使用与 Android 2.1 的兼容包

每个 fragment 都包含 ListViewListView 中的每个元素都有一个 LinearLayout,其中包含两个 TextViews 和一个 ButtonLinearLayout 和按钮有 onClickListeners (分开)。单击 LinearLayout 会启动另一个 Activity。我注意到点击行为非常不一致:有时会立即执行操作,但通常会延迟,有时无论我点击多少次都会忽略它。它变得更加奇怪,因为我可以点击并且只有在我开始滚动列表时才会执行该操作。我尝试了 setFocusable(false)setSelectable(true) 的各种组合,但似乎没有任何区别。有任何想法吗?我很乐意提供更多详细信息。

最佳答案

我遇到了类似的问题,我花了 2 天时间来调试并解决它。我有一个 ListAdapter,它在 LinearLayout 中为每个列表项创建几个 TextView。每个 TextView 都有自己的 OnClickListener,因为我需要处理每个项目的点击。

当我更改实现以便重用 View 时,OnClickListener 停止正常工作。在 4.4.2 上,大多数点击都有效,但有时在我滚动列表之前没有任何反应。在 2.3 上,第一次点击无法正常工作,然后所有点击都会突然处理。

在我的特殊情况下,我在 Java 代码中创建了所有 View ,而不是通过膨胀资源。关键点是,即使 View 被重用,我也确实设置了 LinearLayout 的 LayoutParams(这似乎更安全,然后假设重用的 View 具有正确的布局参数)。当我在重用时不设置 LayoutParams 一切正常!这是关键代码:

public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout tapeLine = null;
if (convertView != null && convertView instanceof LinearLayout && ((LinearLayout)convertView).getChildCount() == 4) tapeLine = (LinearLayout) convertView; // Reuse view
else tapeLine = new LinearLayout(activity);
if (convertView == null) { // Don't set LayoutParams when reusing view
ViewGroup.LayoutParams tapeLineLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tapeLine.setLayoutParams(tapeLineLayoutParams);
}
ScrollingTape scrollingTape = calculatorHolder.getCalculator().getScrollingTape();
int tapeWidthPx = parent.getWidth();
TapeLineTextSizeInfo tapeLineTextSizeInfo = calculatorHolder.getTapeLineTextSizeHelper().createTapeLineTextSizeInfo(tapeWidthPx);
ScrollingTapeLine line = scrollingTape.getLine(position);
tapeLine.setOrientation(LinearLayout.HORIZONTAL);
int tapeBackgroundColor = getBackgroundColor(line);
tapeLine.setBackgroundColor(tapeBackgroundColor);
addColumnViews(tapeLine, line, tapeLineTextSizeInfo);
tapeLine.setTag(R.id.scrollingtapeadapter_viewtag_position, position);
tapeLine.setOnLongClickListener(longClickListener);
tapeLine.setOnClickListener(remainClickListener);
return tapeLine;
}

ListView 这种奇怪行为的背景是什么?我在 Android 源代码中做了一些调试和研究。当 android 更新一个 View 时,有两个重要的步骤 onMeasure 和 onLayout。ListAdapter 的 getView 方法不仅被调用来绘制 View ,而且在 onMeasure 期间也更早地被调用。在后一种情况下, View 已创建,但尚未在事件链中注册以处理点击事件。

当一个为onMeasure创建的 View 稍后被重用以准确地绘制到屏幕上时,它必须从Android系统注册来处理点击事件。对于这种特殊情况,Android 开发人员做了一些事情,这可以被认为是一个肮脏的 hack。 LayoutParams 中的一个特殊标志用于决定必须在事件更改中注册 View 。

现在我的问题是:通过在重用 View 时也重置 LayoutParams,这个标志总是被重置。因此Android系统不会注册 View ,事件也不会通过。

总结一下:在 ListAdapter 的 getView 中重用 View 时,不要覆盖 LayoutParams,因为它们保留了 android 系统的内部信息。

关于Android - ListView 中的延迟点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8815066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com