2011-01-08 144 views
8

我在做一些AsyncTask工作後,用戶點擊我的ListView中的一個項目。我想禁用該項目,因此無法點擊兩次。我簡化了點擊監聽器來僅包含這種方法,但對我來說它仍然沒有做任何事情,視圖看起來是一樣的,它讓自己再次愉快地被點擊,這讓我很煩惱。Android ListView子視圖setEnabled()和setClickable()什麼都不做

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秒。

+0

你們都是正確的。現在的工作,感謝有一個很難獲得的最後一個項目的位置 – Axarydax

回答

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

喜IM點擊就可以賜教彌補了這個感謝 – NoobMe

5

你的問題並不完全清楚。我正在解釋您的問題,因爲您預計不會根據您的setEnabled()setClickable()調用呼叫onItemClick()

我不驚訝,不起作用,因爲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爲該位置重新創建View時可以重新創建該信息。

3)您需要處理onClick事件,以點擊實際的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 S的ListView您將在logcat的輸出,只有onClick被稱爲通知。從未調用過onItemClick

另請注意,如果View可點擊或不可用,則適配器中的isEnabled似乎不起作用。我不知道如何解釋。這意味着如果你想要控制View的這個屬性,Adapter需要設置當創建View並以某種方式維護該信息時。

+0

我還需要重寫''areAllItemsEnabled在適配器(),但由於 – Axarydax

+0

是啊,忘了那個。仍然onItemClick只能通過鍵盤事件調用。 – Qberticus

18

如果要在列表視圖中禁用項目單擊使用clickedView.setClickable(true);

+8

這聽起來很不對,但無論出於何種原因,它都有效。奇怪的是,也許專業人士可以啓發我們爲什麼setClickable(true)實際上會使視圖不可點擊的效果。 – Bachi

+0

發現了同樣的事情。這很奇怪,但它有效。 – Drejc

+1

indead!看起來像系統中的一個錯誤。 – user717572