2011-12-11 105 views
1

我有一個自定義列表視圖與兩個textviews。如果我使用仿真器的D-pad,一切正常,行被選中,但如果我點擊模擬器上的項目(或嘗試選擇在手機上)沒有選擇。Android-Can not get listview item selected

addresslist.xml: 
    <?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" 
    android:orientation="horizontal" android:paddingBottom="6dip" 
    android:paddingTop="4dip"> 

    <TextView android:id="@+id/DENUMIRE_CELL" 
     android:layout_width="50dp" android:layout_height="wrap_content" 
     android:layout_weight="1.03" /> 

    <TextView android:id="@+id/ADRESA_CELL" android:layout_width="50dp" 
     android:layout_height="wrap_content" android:layout_weight="0.84" /> 
</LinearLayout> 
clienti.xml: 

    <?xml version="1.0" encoding="utf-8"?> 
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="fill_parent" 
    android:orientation="vertical"> 

    <TableRow android:id="@+id/tableRow1" android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 

     <LinearLayout android:orientation="horizontal" 
      android:focusable="true" android:focusableInTouchMode="true"> 
      <EditText android:id="@+id/editTextCauta" 
       android:layout_width="100dp" android:layout_height="wrap_content" 
       android:layout_weight="0.04" /> 

      <Button android:id="@+id/buttonCauta" android:layout_width="70dp" 
       android:layout_height="wrap_content" android:text="Cauta" /> 
     </LinearLayout> 

    </TableRow> 
    <TableRow android:id="@+id/tableRowHeader" 
     android:layout_width="fill_parent" android:layout_height="wrap_content" 
     android:background="#000000"> 

     <LinearLayout android:orientation="horizontal"> 
      <TextView android:id="@+id/textView1" android:layout_width="159dp" 
       android:layout_height="wrap_content" android:text="Denumire" 
       android:textAppearance="?android:attr/textAppearanceLarge" 
       android:textColor="#BBBBBB" android:textSize="15sp" /> 
      <TextView android:id="@+id/textView2" android:layout_width="159dp" 
       android:layout_height="wrap_content" android:text="Adresa" 
       android:textAppearance="?android:attr/textAppearanceLarge" 
       android:textColor="#BBBBBB" android:textSize="15sp" /> 

     </LinearLayout> 

    </TableRow> 
    <TableRow android:id="@+id/tableRow2" android:layout_width="wrap_content" 
     android:layout_height="wrap_content" android:baselineAligned="false"> 


     <ListView android:id="@+id/adresslist" android:layout_width="wrap_content" 
      android:choiceMode="singleChoice" android:layout_height="wrap_content" 
      android:scrollbars="horizontal|vertical" /> 

    </TableRow> 


</TableLayout> 

代碼:

public void adresalistBind() 
     { 
      listview = (ListView) findViewById(R.id.adresslist); 

      ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); 
      ArrayList<ClientClass> clientlist=new ArrayList<ClientClass>(); 

      ClientClass.setClientContextForDB(this); 

      clientlist=ClientClass.ClientiGet(); 

      listaAll=clientlist; 


      HashMap<String, String> map; 

      for(int i=0;i<clientlist.size();i++) 
      { 
       map = new HashMap<String, String>(); 
       map.put("denumire", clientlist.get(i).getDenumire()); 
       map.put("adresa", clientlist.get(i).getAdresa()); 
       map.put("clientid", String.valueOf(clientlist.get(i).getClientID())); 
       mylist.add(map); 
      } 

      SimpleAdapter mAdapter = new SimpleAdapter(this, mylist, R.layout.addresslist, 
         new String[] {"denumire", "adresa"}, new int[] {R.id.DENUMIRE_CELL, R.id.ADRESA_CELL}); 
      listview.setAdapter(mAdapter); 
      listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
      listview.setSelection(1); 
      listview.setOnItemSelectedListener(new OnItemSelectedListener() 
      { 
       public void onItemSelected(AdapterView<?> adaptview, View clickedview, int position, 
         long id) 
       { 
        //adaptview.setSelected(true); 
        listview.setSelection(position); 
       } 

       public void onNothingSelected(AdapterView<?> arg0) 
       { 
       } 

      }); 

      listview.setOnItemClickListener(new OnItemClickListener() 
      { 
       public void onItemClick(AdapterView<?> adaptview, View arg1, 
         int position, long arg3) 
       { 
        //adaptview.setSelected(true); 
        // View rowview = (View) adaptview.getChildAt(position); 
        // rowview.setSelected(true); 
        listview.setSelection(position); 

        //Toast.makeText(ClientiForm.this, (String) listview.getItemAtPosition(position).toString(), 10000).show(); 
       } 
      }); 

      listview.setOnItemLongClickListener(new OnItemLongClickListener() 
      { 

       public boolean onItemLongClick(AdapterView<?> arg0, View arg1, 
         int position, long arg3) 
       { 
        listview.setSelection(position); 
        openOptionsMenu(); 

        Toast.makeText(ClientiForm.this, (String) listview.getItemAtPosition(position).toString(), 10000).show(); 
        return false; 
       } 
      }); 
     } 

回答

6

爲了使物品「可檢查」,物品的俯視圖應該實現Checkable界面。只有在這種情況下,您纔會在ListView內收到「已檢查」/「未檢查」狀態。

請注意,「可選」和「可檢查」項目具有不同的含義。在你的情況下,你的意思是「可檢查」項目。不「可選」。您需要對物品進行「檢查」,但ListView確保一次最多隻檢查一個物品CHOICE_MODE_SINGLE。 「selected」項目是當前活動的項目(主要用於輔助功能需求)。

您可以通過在列表項目的佈局中簡單地替換LinearLayoutCheckBox視圖來驗證我所說的內容。並且ListView應該開始自動處理「檢查」狀態。


如果你想使用LinearLayout,仍然能夠支持「檢查」 /「未登記」狀態,你需要實現擴展LinearLayout並實現Checkable界面自定義佈局。

這裏是我的這個實現的版本是:

public class CheckableLinearLayout extends LinearLayout implements Checkable { 

    private boolean mChecked; 

    private static final int[] CHECKED_STATE_SET = { 
     android.R.attr.state_checked 
    }; 

    public CheckableLinearLayout(Context context) { 
     this(context, null); 
     init(); 
    } 

    public CheckableLinearLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    private void init() {  
     setClickable(true); 
    } 

    /**********************/ 
    /** Handle clicks **/ 
    /**********************/ 

    @Override 
    public boolean performClick() { 
     toggle(); 
     return super.performClick(); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     return onTouchEvent(ev); 
    } 

    /**************************/ 
    /**  Checkable  **/ 
    /**************************/ 

    public void toggle() { 
     setChecked(!mChecked); 
    } 

    public boolean isChecked() { 
     return mChecked; 
    } 

    public void setChecked(boolean checked) { 
     if (mChecked != checked) { 
      mChecked = checked; 
      refreshDrawableState(); 
      setCheckedRecursive(this, checked); 
     } 
    } 

    private void setCheckedRecursive(ViewGroup parent, boolean checked) { 
     int count = parent.getChildCount(); 
     for(int i = 0; i < count; i++) { 
      View v = parent.getChildAt(i); 
      if(v instanceof Checkable) { 
       ((Checkable) v).setChecked(checked); 
      } 

      if(v instanceof ViewGroup) { 
       setCheckedRecursive((ViewGroup)v, checked); 
      } 
     } 
    } 

    /**************************/ 
    /** Drawable States **/ 
    /**************************/ 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
     if (isChecked()) { 
      mergeDrawableStates(drawableState, CHECKED_STATE_SET); 
     } 
     return drawableState; 
    } 

    @Override 
    protected void drawableStateChanged() { 
     super.drawableStateChanged(); 

     Drawable drawable = getBackground(); 
     if (drawable != null) { 
      int[] myDrawableState = getDrawableState(); 
      drawable.setState(myDrawableState); 
      invalidate(); 
     } 
    } 

    /**************************/ 
    /** State persistency **/ 
    /**************************/ 

    static class SavedState extends BaseSavedState { 
     boolean checked; 

     SavedState(Parcelable superState) { 
      super(superState); 
     } 

     private SavedState(Parcel in) { 
      super(in); 
      checked = (Boolean)in.readValue(null); 
     } 

     @Override 
     public void writeToParcel(Parcel out, int flags) { 
      super.writeToParcel(out, flags); 
      out.writeValue(checked); 
     } 

     @Override 
     public String toString() { 
      return "CheckableLinearLayout.SavedState{" 
        + Integer.toHexString(System.identityHashCode(this)) 
        + " checked=" + checked + "}"; 
     } 

     public static final Parcelable.Creator<SavedState> CREATOR 
       = new Parcelable.Creator<SavedState>() { 
      public SavedState createFromParcel(Parcel in) { 
       return new SavedState(in); 
      } 

      public SavedState[] newArray(int size) { 
       return new SavedState[size]; 
      } 
     }; 
    } 

    @Override 
    public Parcelable onSaveInstanceState() { 
     // Force our ancestor class to save its state 
     Parcelable superState = super.onSaveInstanceState(); 
     SavedState ss = new SavedState(superState); 

     ss.checked = isChecked(); 
     return ss; 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     SavedState ss = (SavedState) state; 

     super.onRestoreInstanceState(ss.getSuperState()); 
     setChecked(ss.checked); 
     requestLayout(); 
    } 
} 

你的項目佈局應該是這個樣子:

<com.your.pkg.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/linearLayout1" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/checkable_item"> 

     <TextView 
      android:id="@+id/name" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Large Text" 
      android:textAppearance="?android:attr/textAppearanceLarge" /> 
</com.your.pkg.CheckableLinearLayout> 

並注意 「繪製/ checakble_item」。它應該處理不同的狀態。在我的例子,它看起來像:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item android:state_pressed="true" android:drawable="@drawable/item_pressed" /> 
    <item android:state_checked="true" android:drawable="@drawable/item_checked"/> 
    <item android:drawable="@drawable/item_unchecked" /> 

</selector> 

drawable/item_presseddrawable/item_checkeddrawable/item_unchecked是我的自定義繪製資源。

最後的那張字條:你AdaptergetView()你必須打電話view.setClickable(false);爲可檢查的狀態要由ListView,而不是由CheckableLinearLayout處理。

+0

你的代碼正在工作,但它檢查多個項目,我想一次只檢查一個項目。我試圖以檢索當前檢查項目,但它不工作是這樣的:如果(listaAll.size()> 0) \t \t \t { \t \t \t \t如果(listview.getCheckedItemPosition()> = 0) \t \t \t \t { \t \t \t \t \t客戶端ID = listaAll.get(listview.getCheckedItemPosition())。getClientID(); \t \t \t \t \t startActivity(new Intent(ClientiForm.this,ClientiDetaliiForm.class)); \t \t \t \t} \t \t \t \t其他 \t \t \t \t { \t \t \t \t \t Toast.makeText(ClientiForm.this, 「Alegeti聯合國客戶!」,10000).show(); \t \t \t \t} \t \t \t \t \t \t \t} –

+0

確保您添加'view.setClickable(假)'在適配器中的'getView()'。或從'CheckableLinearLayout'中刪除'setClickable(true)'。 – inazaruk

+0

,我增加機器人:可點擊=「false」表示CheckableLinearLayout在addresslist.xml,但它會檢查多個項目 –

0

你會發現在this link您的解決方案。您必須以編程方式更改佈局的外觀。