2011-01-08 10 views
8

私がListViewの項目をクリックすると、AsyncTaskの作業をしています。アイテムを無効にして2回クリックすることはできません。私はこのメソッドだけを含むようにクリックリスナーを単純化しましたが、それでも私のために何もしません。ビューは同じように見え、喜んでもう一度クリックすることができます。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(); 
} 

各行のための私のビューは2つのTextView sのカスタムLinearLayoutです。

+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

こんにちは、最後にクリックしたアイテムの位置を取得するのに苦労しました – NoobMe

5

問題は完全にはっきりしていません。あなたのsetEnabled()setClickable()の呼び出しに基づいてonItemClick()が呼び出されないと予想しているという質問を翻訳しています。

onItemClick()は何かであるので、私はうまくいきません。子供の表示ではなく、ListViewです。代わりにListAdapterareAllItemsEnabled()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)実際にViewがクリックされた場合は、onClickイベントを処理する必要があります。あなたがこれを扱うところはあなた次第です。最良の場所はおそらくAdapterで、設計要件に応じてActivityに渡すかどうかは同じです。それがあなたのタッチイベントを処理する必要がある場所です。あなたは、このコードを実行し、あなただけonClickが呼び出されているlogcat出力に気づくでしょうListViewView Sのいずれかをクリックすると

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

    } 
} 

は、単純な活動のためにこのコードを参照してください。 onItemClickは決して呼び出されません。

また、ViewをクリックするとアダプターのisEnabledが有効に見えないことにも注意してください。私はそれをどのように解釈するか分からない。しかし、Viewのプロパティを制御したい場合は、Viewが作成されたときに、その情報を保持する必要があることをAdapterが設定する必要があることを意味します。

+0

アダプタで 'areAllItemsEnabled()'をオーバーライドする必要がありますが、ありがとう – Axarydax

+0

はい、そのことを忘れてしまった。それでもonItemClickはキーボードイベントでのみ呼び出されます。 – Qberticus

18

あなたはリストビューを使用clickedView.setClickable(true);

+8

これは非常に間違っていますが、何らかの理由で動作します。奇妙なことに、おそらくプロが、setClickable(true)が実際にビューをクリックできないようにする効果がある理由を教えてくれるかもしれません。 – Bachi

+0

同じことが発見されました。それは奇妙ですが、それは動作します。 – Drejc

+1

indead!システムのバグのように見えます。 – user717572

関連する問題