onClick事件不适用于android

时间:2016-08-25 15:46:56

标签: android listview android-dialog

我有两个弹出窗口。在第一个弹出窗口中,我有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()弹出窗口)到第一个弹出窗口时,第一个listview上的onClick处理程序停止工作。还有一些其他的东西:

    列表视图项的
  1. onTouch侦听器仍在工作(调用action=ACTION_DOWNaction=ACTION_UP);
  2. 当我为listview onItemClickListener设置时,它始终会被调用 (第一次打开弹出窗口,当我们返回时);
  3. 当我在列表视图中的项目上多次单击时,有时会onClick 发生这种情况,然后在我点击时多次调用它 之前。
  4. 你有什么想法可能是问题的原因吗?

    更新

    似乎适配器内的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 ()创建视图?或者如果可能的话我应该怎么做?

1 个答案:

答案 0 :(得分:0)

尝试在列出android:descendantFocusability="blocksDescendants"的列表项的父布局声明中插入属性listItemButton

属性android:descendantFocusability

  

在查找要获得焦点的视图时定义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;
}
}