Android ListView子视图setEnabled()和setClickable()什么都不做

时间:2011-01-08 21:32:48

标签: android listview

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

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,其中包含两个TextView

4 个答案:

答案 0 :(得分:20)

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

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

答案 1 :(得分:18)

如果要在列表视图中单击禁用项目,请使用clickedView.setClickable(true);

答案 2 :(得分:5)

你的问题并不完全清楚。我正在解释您的问题,因为您希望onItemClick()根据您的setEnabled()setClickable()来电不会被调用。

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

答案 3 :(得分: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时可以重新创建该信息。 {1}}为该位置重新创建View

3)您需要处理被点击的实际onClick的{​​{1}}事件。你在哪里处理这取决于你。最好的位置可能是您的View,根据您的设计要求,可能会或可能不会将其传递给Adapter。这是您需要处理触摸事件的地方。

请参阅此代码以获取简单的活动:

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; } } } 中的任何View,您将在logcat输出中注意到仅调用ListView。永远不会调用onClick

另请注意,如果onItemClick可点击,则适配器中的isEnabled似乎无效。我不知道如何解释。这意味着,如果你想控制View View需要设置的属性,那就是创建Adapter时以及以某种方式维护该信息。