简体   繁体   English

onClick事件不适用于Android中的嵌套列表视图项控件

[英]onClick event doesn't work on nested listview item control in android

I have 2 popups. 我有2个弹出窗口。 On the first popup I have ListView with selectable items. 在第一个弹出窗口中,我具有带有可选项目的ListView When I click item from first list, then second popup appear, which also has ListView with options to select. 当我单击第一个列表中的项目时,然后出现第二个弹出窗口,该弹出窗口也具有带有选择选项的ListView

I've implemented first list view items as custom View and subscribing to clicks inside view constructor, like that: 我已经将第一个列表视图项实现为自定义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");  
       );
    }
}

When I open first dialog for the first time onClick handler fires as expected and second popup appears. 当我第一次打开第一个对话框时, onClick处理程序将按预期触发,并出现第二个弹出窗口。 But when I close second popup and return back (calling Dialog.dismiss() for popup) to the first popup, then onClick handler on first listview stops working. 但是,当我关闭第二个弹出窗口并返回(为弹出窗口调用Dialog.dismiss() )回到第一个弹出窗口时,则第一个列表视图上的onClick处理程序将停止工作。 There are some other inetersting things: 还有其他一些有趣的事情:

  1. onTouch listener for list view item is still working (called for action=ACTION_DOWN and action=ACTION_UP ); 列表视图项目的onTouch侦听器仍在工作(称为action=ACTION_DOWNaction=ACTION_UP );
  2. when I set for listview onItemClickListener it's called always (1st time when popup opened and when we return back to it); 当我为listview设置onItemClickListener它总是被调用(第一次打开弹出窗口并返回到它时);
  3. when I click many times on item in list view sometimes onClick happens and after that it's called as many times as I clicked before. 当我在列表视图中多次单击该项目时,有时会发生onClick ,此后它的调用次数与我之前单击的次数相同。

Do you have any ideas what may be the reason of the problem? 您有什么想法可能是问题的原因吗?

UPDATE 更新

Seems that there is a problem with getView method inside adapter. 适配器内的getView方法似乎有问题。 I've tried to create a custom list item control inside it (or get it from cache): 我试图在其中创建一个自定义列表项控件(或从缓存中获取它):

@Override
public View getView(int position, View view, ViewGroup parent) {
    if (!constructedViewCache.containsKey(position)) {
        constructedViewCache.put(position, new CustomListItem ());
    }

    return constructedViewCache.get(position);
}

When I changed this code to the code below everything works: 当我将此代码更改为下面的代码时,一切正常:

@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;
}

Why it's not possible to create view with a new CustomListItem () ? 为什么无法使用new CustomListItem ()创建视图? Or if it's possible how should I do that? 或者,如果可能的话,我该怎么做?

Try to insert the attribute android:descendantFocusability="blocksDescendants" in the parent layout declaration of your list item where listItemButton is placed. 尝试在放置listItemButton的列表项的父布局声明中插入android:descendantFocusability="blocksDescendants"属性。

Where attribute android:descendantFocusability 凡属性android:descendantFocusability

Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus. 定义在寻找要聚焦的View时ViewGroup及其子孙之间的关系。

And constant blocksDescendants means that: 常量blocksDescendants意味着:

The ViewGroup will block its descendants from receiving focus. ViewGroup将阻止其后代获得焦点。

Second question 第二个问题

It's possible to create view with a new CustomListItem (). 可以使用新的CustomListItem()创建视图。 See example below: 请参见下面的示例:

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    return new CustomListItem(context);
}

EDIT 编辑

I didn't see your full code, it looks that you are something wrong. 我没有看到完整的代码,看来您有问题。 Here is working example take a look at: 这是工作示例,请看一下:

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);
}
}

And second class: 第二类:

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");
    });

}
}

EDIT 2 编辑2

I've updated CustomListItem to display dialog when button is clicked. 我更新了CustomListItem以在单击按钮时显示对话框。 There is code of custom DialogFragment which is using list of items same layout and adapter as activity: 有自定义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;
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM