【问题标题】:Android ListView child View setEnabled() and setClickable() do nothingAndroid ListView 子视图 setEnabled() 和 setClickable() 什么都不做
【发布时间】:2011-01-08 21:32:47
【问题描述】:

在用户单击我的ListView 中的一个项目后,我正在做一些AsyncTask 的工作。我想禁用该项目,所以它不能被点击两次。我已经将点击监听器简化为只包含这个方法,但它仍然没有为我做任何事情,视图看起来一样,它让自己再次被愉快地点击,这让我很烦恼。

public void onItemClick(AdapterView<?> parent, View clickedView,
  int position, long id) {
  item = (Episode) parent.getItemAtPosition(position);
  clickedView.setClickable(false);
  clickedView.setEnabled(false);
  clickedView.invalidate();
}

我对每一行的视图是一个自定义 LinearLayout 和两个 TextViews。

【问题讨论】:

  • 你们都是对的。现在可以了,谢谢

标签: android listview


【解决方案1】:

因此,您可能也在使用自定义适配器。如果这样做,请覆盖这些方法:

public boolean areAllItemsEnabled() {
    return false;
}

public boolean isEnabled(int position) {
    // return false if position == position you want to disable
}

然后,当您收到点击时,告诉适配器最后点击的项目是什么,并在 isEnabled 上为该位置返回 false。例如,您可以在适配器中使用这样的方法:

private int mLastClicked;
public void setLastClicked(int lastClicked){
    mLastClicked = lastClicked;
}

【讨论】:

  • 嗨,我很难找到最后点击的项目的位置,您能告诉我吗?谢谢
【解决方案2】:

如果您想禁用列表视图中的项目点击,请使用clickedView.setClickable(true);

【讨论】:

  • 这听起来很错误,但不管出于什么原因,它都有效。奇怪,也许有高手能告诉我们为什么 setClickable(true) 实际上会有使视图不可点击的预期效果。
  • 死了!看起来像系统中的一个错误。
  • 我认为这不是错误。这样clickedView 会拦截点击。列表元素不会响应任何点击,因为clickedView 会拦截它们,因此列表元素不会突出显示。
  • 天啊!我刚刚花了几个小时试图实现这一目标!我正在考虑创建自定义选择器或背景颜色以隐藏选择器效果...谢谢大家!
  • 真的很奇怪... setClickable(true) 表示不可点击。希望以后不会解决这个问题...XDD
【解决方案3】:

您的问题并不完全清楚。我将您的问题解释为您期望 onItemClick() 不会根据您的 setEnabled()setClickable() 调用而被调用。

我并不感到惊讶,因为 onItemClick()ListView 所做的,而不是子视图。请尝试在您的 ListAdapter 中覆盖 areAllItemsEnabled()isEnabled()

【讨论】:

    【解决方案4】:

    您的方法行不通的原因有多种。

    1) onItemClick 仅因键盘事件而被调用。特别是KeyKevent.KEYCODE_ENTER。它不是通过任何其他代码路径调用的。因此,仅当您尝试提供键盘/轨迹球支持时,处理这种情况才有用。

    AbsListView相关方法的Android源码:

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_CENTER:
        case KeyEvent.KEYCODE_ENTER:
            if (!isEnabled()) {
                return true;
            }
            if (isClickable() && isPressed() &&
                    mSelectedPosition >= 0 && mAdapter != null &&
                    mSelectedPosition < mAdapter.getCount()) {
    
                final View view = getChildAt(mSelectedPosition - mFirstPosition);
                if (view != null) {
                    performItemClick(view, mSelectedPosition, mSelectedRowId);
                    view.setPressed(false);
                }
                setPressed(false);
                return true;
            }
            break;
        }
        return super.onKeyUp(keyCode, event);
    }
    
    public boolean performItemClick(View view, int position, long id) {
        if (mOnItemClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            mOnItemClickListener.onItemClick(this, view, position, id);
            return true;
        }
    
        return false;
    }
    

    2) 您正在直接在视图上设置可点击信息。通过任何AdapterView 显示的视图都是空灵的。它们是应AdapterView 的请求创建的,并且仅在AdapterView 需要它们时才存在。您不应在它们上设置任何要保留的数据。您可以在它们上调用setEnabledsetClickable 以立即生效,但如果您希望该信息持续存在,您需要将其存储在Adapter 可以访问的某个位置,以便在AdapterView 重新创建@987654331 时重新创建它@那个位置。

    3) 您需要处理onClick 事件,以便实际点击View。你在哪里处理这取决于你。最好的地方可能是您的Adapter,然后可能会或可能不会将其传递给您的Activity,具体取决于您的设计要求。那是您需要处理触摸事件的地方。

    查看此代码以获得简单的 Activity:

    public class PhoneTesting extends Activity {
        private static final String TAG = "PhoneTesting";
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Log.d(TAG, "onCreate()");
    
            List<String> strings = new ArrayList<String>();
            for(int i = 0 ; i < 20 ; i++) {
                strings.add(Integer.toString(i));
            }
    
            ListView list = (ListView) this.findViewById(R.id.list);
    
            list.setAdapter(new SimpleAdapter(this, 0, 0, strings));
            list.setOnItemClickListener(new OnItemClickListener() {
    
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Log.d(TAG, "onItemClick: " + id);
                }
            });
    
        }
    
        class SimpleAdapter extends ArrayAdapter<String> implements OnClickListener {
            SimpleAdapter(Context context, int resource, int textViewResourceId, List<String> objects) {
                super(context, resource, textViewResourceId, objects);
            }
    
            SimpleAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
                super(context, resource, textViewResourceId, objects);
            }
    
            SimpleAdapter(Context context, int resource, int textViewResourceId) {
                super(context, resource, textViewResourceId);
            }
    
            SimpleAdapter(Context context, int textViewResourceId, List<String> objects) {
                super(context, textViewResourceId, objects);
            }
    
            SimpleAdapter(Context context, int textViewResourceId, String[] objects) {
                super(context, textViewResourceId, objects);
            }
    
            SimpleAdapter(Context context, int textViewResourceId) {
                super(context, textViewResourceId);
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                TextView b = position % 2 == 0 ? new Button(this.getContext()) : new TextView(this.getContext());
                b.setText(this.getItem(position));
    
                b.setOnClickListener(this);
    
                return b;
            }
    
            @Override
            public void onClick(View v) {
                TextView t = (TextView) v;
                Log.d(TAG, "onClick: " + t.getText());
            }
    
            @Override
            public boolean isEnabled(int position) {
                return position % 2 == 0 ? false : true;
            }
    
        }
    }
    

    如果您执行此代码并单击ListView 中的任何Views,您将在logcat 输出中注意到只有onClick 被调用。 onItemClick 永远不会被调用。

    还要注意,适配器中的isEnabled 似乎不会影响View 是否可点击。我不知道如何解释。这意味着,如果您想控制 View 的该属性,则需要在创建 View 时设置 Adapter 并以某种方式维护该信息。

    【讨论】:

    • 我还需要在适配器中覆盖 areAllItemsEnabled(),但谢谢
    • 是的,忘了那个。仍然只通过键盘事件调用 onItemClick。
    猜你喜欢
    • 2013-03-14
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 2013-08-14
    • 2012-09-11
    • 2021-12-23
    • 1970-01-01
    • 2020-01-18
    相关资源
    最近更新 更多