Bos*_*one 18 android onclick android-listview android-fragments android-viewpager
我的应用程序中有以下结构:
FragmentActivity ViewPager通过FragmentStatePagerAdapter使用与Android 2.1的compativility pack 管理多个片段
每个片段包含ListView.每个元素ListView都有一个LinearLayout带有两个TextViews和一个Button.的LinearLayout和按钮具有onClickListeners(分离).点击LinearLayout开始另一个Activity.我注意到点击行为是非常不一致的:有时候动作会立即执行但很多时候它会被延迟,有时它会被忽略,无论我点击多少次.它甚至更奇怪,因为我可以点击,只有当我开始滚动列表时才会执行操作.我试过的各种组合setFocusable(false)和setSelectable(true),但它似乎没有任何区别.有任何想法吗?我很乐意提供更多细节.
小智 9
我有类似的问题,我花了2天的时间来调试和解决它.我有一个ListAdapter,它为每个列表项在LinearLayout中创建几个TextView.每个TextView都有自己的OnClickListener,因为我需要处理每个项目的点击.
当我更改实现以便重用View时,OnClickListener停止正常工作.在4.4.2上,大多数点击都有效,但有时直到我在列表中滚动才会有反应.在2.3上,第一次点击不起作用,然后是爆发中处理的所有点击.
在我的特殊情况下,我创建了所有View in Java代码,而不是通过膨胀资源.关键的一点是,我确实设置了LinearLayout的LayoutParams,即使重用了视图(这似乎更安全,然后假设重用的视图具有正确的布局参数).当我没有设置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;
}
Run Code Online (Sandbox Code Playgroud)
列表视图的这种奇怪行为的背景是什么?我在Android源代码中进行了一些调试和研究.当android更新视图时,有两个重要的步骤onMeasure和onLayout.ListAdapter的getView方法不仅被调用来绘制视图,而且在onMeasure期间也被提前.在后一种情况下,视图已创建,但尚未在事件链中注册以处理单击事件.
当为onMeasure创建的视图稍后被重复使用以被实际绘制到屏幕时,必须从Android系统注册以处理点击事件.对于这个特殊情况,Android开发者已经做了一些事情,这可能被认为是一个肮脏的黑客.LayoutParams中的特殊标志用于确定必须在事件更改中注册视图.
现在我的问题是:通过在重用视图时重置LayoutParams,此标志始终被重置.因此,Android系统不会注册视图,事件也不会通过.
总结一下:当在ListAdapter的getView中重用视图时,不要覆盖LayoutParams,因为它们保留了android系统的内部信息.
如果有人想知道我是如何解决这个问题的。基本上我必须简化我的布局。似乎当您有复杂的嵌套结构时,事件可能需要很长时间才能冒泡,并且如果您同时开始滚动列表,事件可能会触发错误的操作。我通过尽可能切换到RelativeLayout来修剪布局,这似乎有很大帮助
| 归档时间: |
|
| 查看次数: |
3808 次 |
| 最近记录: |