【问题标题】:Selector is applying change to all views instead of clicked view选择器将更改应用于所有视图而不是单击视图
【发布时间】:2012-12-11 17:34:28
【问题描述】:

我正在为 Android 拖放网格中的视图添加 onClick 突出显示。该项目位于GitHub(开发分支包含使用选择器的代码)。

当我将 onClick 选择器设置为视图的背景时,我遇到的问题是在适配器中,当我单击视图时,选择器不会仅更改该视图的背景,而是更改所有视图的背景。

我很确定这是 ViewGroup 中的 onTouch 处理点击的结果(如下)。我不确定是否应该以不同的方式返回 true/false 或以不同的方式触发 onClick 侦听器以防止突出显示所有视图。

感谢任何想法/帮助。

@Override
public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        touchDown(event);
        break;
    case MotionEvent.ACTION_MOVE:
        touchMove(event);
        break;
    case MotionEvent.ACTION_UP:
        touchUp(event);
        break;
    }
    if (aViewIsDragged())
        return true;
    return false;
}

private void touchUp(MotionEvent event) {
    if(dragged == -1) {
        if(onClickListener != null) {
            View clickedView = getChildAt(getTargetAtCoor((int) event.getX(), (int) event.getY()));
            if(clickedView != null)
                onClickListener.onClick(clickedView);
        }
    } else {
        manageChildrenReordering();
        hideDeleteView();
        cancelEdgeTimer();

        movingView = false;
        dragged = -1;
        lastTarget = -1;
        container.enableScroll();
        cancelAnimations();
    }
}

编辑:查看 ViewGroup 文档后android:addStatesFromChildren 听起来像是我正在寻找的东西,但似乎没有任何效果。

android:addStatesFromChildren

设置此 ViewGroup 的可绘制状态是否还包括其 儿童的可绘制状态。例如,这用于创建一个组 当其子 EditText 或按钮获得焦点时,似乎已获得焦点。

必须是布尔值,“真”或“假”。

这也可能是对资源的引用(形式为 “@[package:]type:name”)或主题属性(形式为 "?[package:][type:]name") 包含此类型的值。

这个对应全局属性资源符号 addStatesFromChildren。

更新

我找到了解决这个问题的方法。拉取请求是here

【问题讨论】:

  • 有机会看到您的 onClickListener 方法吗?也许 performClick 可能会有所帮助?
  • onClickListener 只是对点击侦听器(本例中的活动)的引用,它只是创建一个 toast。我用 clickedView.performClick() 交换了 onClickListener.onClick(clickedView) 但同样的事情发生了,最重要的是点击监听器没有被调用

标签: android android-custom-view viewgroup


【解决方案1】:

编辑

layout.setClickable(true); 添加到视图函数(第133 行和第156 行之间的某个位置)以使每个项目都可点击。这是他们拥有自己的可选择状态所必需的。没有它,网格将接收触摸,并且该状态将传递给每个孩子。这会破坏您的 onTouch 功能,但这将是一个单独的问题。

如果您不想更改 onTouch 的功能,您可以在不同的触摸功能中手动更改所选项目的背景,而不是使用选择器


没抓住重点的原文:

也许我遗漏了一些东西,但我认为您可以从 onTouch 传递视图“v”并将其用作 clickedView,而不是试图根据位置确定它是哪个视图。

【讨论】:

  • 按位置查找视图是因为它在该位置找到子视图,来自 onTouch 的 v 并不总是子视图,并且会在用户刚刚触摸空白时触发点击。在 onTouch 中使用 v 也与我在问题中遇到的问题无关
  • 抱歉,我没听懂你在问什么。选择器在您的代码中的哪个位置?我快速浏览了一下,但什么也没看到
  • 在dev分支中,选择器设置为视图背景here,选择器本身为here
  • 太棒了,完美地修复了选择器。关于如何处理 onTouch 现在有什么想法吗?
  • @Luke 您需要为调用网格侦听器的每个项目添加一个 onTouchListener(不知道您将如何做到这一点),或者删除 setClickable 行和选择器,然后制作触摸功能更改视图的背景。第二个选项对我来说听起来更容易,但我没有时间测试,我不确定它对作为一个库的可用性有什么影响
猜你喜欢
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 2020-08-07
相关资源
最近更新 更多