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

用户单击我的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(); } 

我的每行视图是一个具有两个TextView的自定义LinearLayout

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

所以,你也可以使用自定义适配器。 如果你这样做,重写这些方法:

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

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

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

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

你的问题并不完全清楚。 我正在解释你的问题,因为你所期待的onItemClick()不会被基于你的setEnabled()setClickable()调用调用。

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

您的方法无法正常工作的原因有很多。

1) onItemClick仅由于键盘事件而被调用。 特别是KeyKevent.KEYCODE_ENTER 。 它不会通过任何其他代码path调用。 所以,如果您正在尝试提供键盘/轨迹球支持,那么处理这一点甚至是有用的。

Android源码为AbsListView的相关方法:

 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的请求下创build的,只要AdapterView需要它们就存在。 你不应该设置任何你想保留的数据。 你可以在它们上面调用setEnabledsetClickable来立即生效,但是如果你想让这个信息持久存在,你需要将它存储在Adapter有权访问的地方,这样当AdapterView为该位置重新创buildView时,它可以被重新创build。

3)你需要处理被点击的实际ViewonClick事件。 你在哪里处理这取决于你。 最好的地方可能是你的Adapter ,然后根据你的devise要求,它可能会或可能不会传递给你的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中的任何一个View ,你会注意到logcat输出中只有onClick被调用。 onItemClick永远不会被调用。

另外请注意,如果View是可点击的,则适配器中的isEnabled似乎不起作用。 我不知道如何解释。 这意味着如果你想控制View Adapter需要设置的属性,当创buildView ,并以某种方式维护该信息。