onClick 事件不适用于 android 中的嵌套列表视图项控件
Posted
技术标签:
【中文标题】onClick 事件不适用于 android 中的嵌套列表视图项控件【英文标题】:onClick event doesn't work on nested listview item control in android 【发布时间】:2017-01-02 03:23:08 【问题描述】:我有 2 个弹出窗口。在第一个弹出窗口中,我有 ListView
和可选项目。当我从第一个列表中单击项目时,会出现第二个弹出窗口,其中还有 ListView
以及可供选择的选项。
我已经将第一个列表视图项实现为自定义 View
并订阅视图构造函数内的点击,如下所示:
class CustomListItem extends RelativeLayout
public CustomListItem()
...
//inflating stuff there
((Button)findViewById(R.id.listItemButton)).setOnClickListener(
//This code not working as expected, but then could fire a lot of times
v -> System.out.println("item clicked");
);
当我第一次打开第一个对话框时,onClick
处理程序按预期触发并出现第二个弹出窗口。但是当我关闭第二个弹出窗口并返回(调用Dialog.dismiss()
弹出窗口)到第一个弹出窗口时,第一个列表视图上的onClick
处理程序停止工作。还有一些其他有趣的东西:
onTouch
列表视图项的侦听器仍在工作(要求 action=ACTION_DOWN
和action=ACTION_UP
);
当我设置 listview onItemClickListener
它总是被调用
(第一次弹出窗口打开并返回时);
当我多次单击列表视图中的项目时,有时onClick
发生,之后它被调用的次数与我点击的次数一样多
之前。
您有什么想法可能是问题的原因吗?
更新
似乎适配器内部的getView
方法有问题。我尝试在其中创建一个自定义列表项控件(或从缓存中获取):
@Override
public View getView(int position, View view, ViewGroup parent)
if (!constructedViewCache.containsKey(position))
constructedViewCache.put(position, new CustomListItem ());
return constructedViewCache.get(position);
当我将此代码更改为以下代码时,一切正常:
@Override
public View getView(int position, View view, ViewGroup parent)
if (view == null)
view = LayoutInflater.from(context).inflate(R.layout.list_view_item, null);
view.setOnClickListener(v ->
v -> System.out.println("item clicked");
);
return view;
为什么不能使用new CustomListItem ()
创建视图?或者如果可能的话我应该怎么做?
【问题讨论】:
我理解正确吗,onclick 不能正常工作,但是如果你点击很多次,比如说 20-30 它可能会触发,之后 onclick 的代码将被执行 20-30 次?跨度> 你能分享更多代码吗? @vovaxo 完整的代码非常复杂。哪部分代码可能对你有用? @silent_coder 是的,你是对的 @Natasha 这取决于您单击的位置还是您尝试单击一次然后等待? 【参考方案1】:尝试在放置listItemButton
的列表项的父布局声明中插入属性android:descendantFocusability="blocksDescendants"
。
where属性android:descendantFocusability
在寻找要获得焦点的 View 时定义 ViewGroup 与其后代之间的关系。
而常量blocksDescendants
表示:
ViewGroup 将阻止其后代接收焦点。
第二个问题
可以使用新的 CustomListItem () 创建视图。请参见下面的示例:
@Override
public View getView(int i, View view, ViewGroup viewGroup)
return new CustomListItem(context);
编辑
我没有看到你的完整代码,看起来你有问题。这是工作示例,请看:
public class CustomAdapter extends BaseAdapter
private Context context;
private HashMap<Integer, CustomListItem> constructedViewCache = new HashMap<>();
public CustomAdapter(Context context)
this.context = context;
@Override
public int getCount()
return 20;
@Override
public Object getItem(int i)
return null;
@Override
public long getItemId(int i)
return 0;
@Override
public View getView(int position, View view, ViewGroup viewGroup)
if (!constructedViewCache.containsKey(position))
constructedViewCache.put(position, new CustomListItem(context, position));
return constructedViewCache.get(position);
二等:
public class CustomListItem extends RelativeLayout
private static final String TAG = "CustomListItem";
public CustomListItem(Context context, int position)
super(context);
View view = LayoutInflater.from(context).inflate(R.layout.item_view, this);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(view1 ->
Log.e(TAG, "CustomListItem: " + position );
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
new CustomDialog().show(fragmentManager, "tag");
);
编辑 2
我已更新CustomListItem
以在单击按钮时显示对话框。有自定义 DialogFragment 的代码,它使用与活动相同的布局和适配器的项目列表:
public class CustomDialog extends DialogFragment
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView listView = (ListView) view.findViewById(R.id.list);
listView.setAdapter(new CustomAdapter(getActivity()));
return view;
【讨论】:
android:descendantFocusability
不会影响结果,但您创建new CustomListItem()
的第二个建议可以正常工作并且不会“中断”点击。还是不明白问题的原因:为什么缓存item会导致点击问题?
我检查了你的代码。我做的完全一样。你试过用对话框吗?我有第一个带有列表和按钮的对话框,它打开另一个对话框,当我们从第二个对话框返回到第一次点击时停止工作。最初它们工作得很好(两个对话框全屏 - 不确定它是否重要)
这很奇怪。你能分享创建对话框(第一级和第二级)的代码吗?
让我们continue this discussion in chat。
@Natasha 是的,你是对的。最好使用 ViewHolder 模式来提高性能。您可以使用 ViewHolder 内置的RecyclerView
。以上是关于onClick 事件不适用于 android 中的嵌套列表视图项控件的主要内容,如果未能解决你的问题,请参考以下文章
QuerySelectorAll 不适用于 onclick 事件
onClick() 事件适用于一个 div,但不适用于另一个。为啥?