2010-10-08 105 views
1

我有一個ExpandableListView,我想填充我的NoteView類型的自定義視圖。 NoteView擴展了LinearLayout幷包含兩個按鈕和一個複選框。我幾乎一切正常,NoteView正在填充支持數據,列表正在填充,並且按鈕可點擊並執行所需的任務。如何使用按鈕實現自定義列表視圖行?

問題是ExpandableListView不再響應click/longclick/keypress事件(除了選擇帶軌跡球/ DPAD的列表項)。

我用標準的TextView替換了我的自定義視圖,觸摸事件再次正常流動,所以它幾乎可以肯定是我做錯了我的自定義視圖或我忽略的一些模糊的ListView設置。

這是我的NoteView代碼和XML佈局。我錯過了什麼?

//Custom Note View 
public class NoteView extends LinearLayout{ 

    private CheckBox mCheckBox; 
    private TextView mTitleTextView; 
    private TextView mDetailsTextView; 
    private TextView mDetailsRightTextView; 
    private LinearLayout mButtonLayout; 
    private Button mDeleteButton; 
    private Button mEditButton; 

    //data storage 
    private long mNoteId = -1; 
    private boolean mStretched = false; 
    private CharSequence mDetails = ""; 
    private CharSequence mStretchedDetails = ""; 
    private CharSequence mDetailsRight = ""; 
    private CharSequence mStretchedDetailsRight = "";  


    private NoteView.OnNoteButtonClickedListener mEditNoteListener; 
    private NoteView.OnNoteButtonClickedListener mDeleteNoteListener; 
    private NoteView.OnNoteCheckBoxClickedListener mCheckboxListener; 

    public NoteView(Context context) { 
     super(context); 
     init(context); 
    } 

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


    private void init(Context context) { 

     this.setPadding(0, 0, 5, 0); 
     this.setOrientation(LinearLayout.VERTICAL); 

     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     inflater.inflate(R.layout.noteview_layout, this);//returns the noteview itself, since is parent 

     //get views 
     mCheckBox = (CheckBox) findViewById(R.id.noteViewCB); 
     mTitleTextView = (TextView) findViewById(R.id.noteViewTitle); 
     mDetailsRightTextView = (TextView) findViewById(R.id.noteViewDetailsRight); 
     mDetailsTextView = (TextView) findViewById(R.id.noteViewDetails); 


     mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       if(mCheckboxListener != null) 
       { 
        mCheckboxListener.onNoteCheckBoxClicked(mNoteId, isChecked); 
       } 
      } 
     }); 

     //prepare button layout 
     mButtonLayout = (LinearLayout) findViewById(R.id.noteViewButtonLayout); 
     mEditButton = (Button) findViewById(R.id.noteViewEditButton); 
     mDeleteButton = (Button) findViewById(R.id.noteViewDeleteButton); 


     mEditButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       if(mEditNoteListener != null) 
       { 
        mEditNoteListener.onNoteButtonClicked(mNoteId); 
       } 
      } 
     }); 

     mDeleteButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       if(mDeleteNoteListener != null) 
       { 
        mDeleteNoteListener.onNoteButtonClicked(mNoteId); 
       } 
      } 
     }); 

    } 

    public void setOnEditClickedListener(NoteView.OnNoteButtonClickedListener listener) 
    { 
     mEditNoteListener = listener; 
    } 

    public void setOnDeleteClickedListener(NoteView.OnNoteButtonClickedListener listener) 
    { 
     mDeleteNoteListener = listener; 
    } 


    public void setOnCheckboxClickedListener(NoteView.OnNoteCheckBoxClickedListener listener) 
    { 
     mCheckboxListener = listener; 
    } 

    static abstract class OnNoteButtonClickedListener 
    { 
     public abstract void onNoteButtonClicked(long noteId); 
    } 


    static abstract class OnNoteCheckBoxClickedListener 
    { 
     public abstract void onNoteCheckBoxClicked(long noteId, boolean checked); 
    } 


    public void setNoteId(long noteId) 
    { 
     mNoteId = noteId; 
    } 

    public long getNoteId() 
    { 
     return mNoteId; 
    } 

    public void setTitle(CharSequence title) 
    { 
     mTitleTextView.setText(title); 
    } 

    public void setChecked(boolean checked) 
    { 
     mCheckBox.setChecked(checked); 
    } 

    public boolean isChecked() 
    { 
     return mCheckBox.isChecked(); 
    } 

    public void setDetails(CharSequence details, CharSequence stretchedDetails) 
    { 
     if(details == null || details.length() == 0) 
     { 
      mDetails = ""; 
     }else 
     { 
      mDetails = details; 
     } 

     if(stretchedDetails == null) 
     { 
      mStretchedDetails = ""; 
     } 
     else 
     { 
      mStretchedDetails = stretchedDetails; 
     } 

     refreshStretched(); 
    } 

    public void setDetailsRight(CharSequence detailsRight, CharSequence expandedDetailsRight) 
    { 
     if(detailsRight == null || detailsRight.length() == 0) 
     { 
      mDetailsRight = ""; 
     }else 
     { 
      mDetailsRight = detailsRight; 
     } 

     if(expandedDetailsRight == null) 
     { 
      mStretchedDetailsRight = ""; 
     } 
     else 
     { 
      mStretchedDetailsRight = expandedDetailsRight; 
     } 

     refreshStretched(); 
    } 

    public void setStretched(boolean expanded) 
    { 
     mStretched = expanded; 
     refreshStretched(); 
    } 

    public boolean getStretched() 
    { 
     return mStretched; 
    } 

    public boolean toggleStretched() 
    { 
     setStretched(!getStretched()); 
     return mStretched; 
    } 

    public void showButtons() { 

     if(mButtonLayout.getVisibility() != VISIBLE) 
     { 
      Animation slideIn = AnimationUtils.loadAnimation(this.getContext(), R.anim.slideonfromright); 

      mButtonLayout.setAnimation(slideIn); 
      mButtonLayout.setVisibility(VISIBLE); 
      mButtonLayout.startAnimation(slideIn); 
     }  
    } 

    public void hideButtons() { 
     if(mButtonLayout != null && mButtonLayout.getVisibility() == VISIBLE) 
     { 
      Animation slideOut = AnimationUtils.loadAnimation(this.getContext(), R.anim.slideofftoright); 
      slideOut.setAnimationListener(new AnimationListener() 
      { 
       @Override 
       public void onAnimationEnd(Animation animation) { 
        mButtonLayout.setVisibility(GONE); 
       } 
       @Override 
       public void onAnimationRepeat(Animation animation) {} 
       @Override 
       public void onAnimationStart(Animation animation) { } 
      }); 

      mButtonLayout.startAnimation(slideOut); 
     } 
    } 


    public void hideButtons(boolean noAnimation) { 
     mButtonLayout.setVisibility(GONE); 
    } 

    public void refreshStretched() { 

     if(mStretched) 
     { 
      mDetailsRightTextView.setText(mStretchedDetailsRight); 
      mDetailsTextView.setText(mStretchedDetails); 
     }else 
     { 
      mDetailsRightTextView.setText(mDetailsRight); 
      mDetailsTextView.setText(mDetails); 
     } 

     if(mDetailsRightTextView.length() == 0) 
     { 

      mDetailsRightTextView.setVisibility(GONE); 
     }else 
     { 
      mDetailsRightTextView.setVisibility(VISIBLE); 
     } 

     if(mDetailsTextView.length() == 0) 
     { 
      mDetailsTextView.setVisibility(GONE); 
     }else 
     { 
      mDetailsTextView.setVisibility(VISIBLE); 
     } 
    } 
} 

noteview_layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<merge xmlns:android="http://schemas.android.com/apk/res/android" > 
    <LinearLayout 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:paddingRight="5dip"> 
     <CheckBox android:id="@+id/noteViewCB" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
     <TextView android:id="@+id/noteViewTitle" 
     android:layout_width="wrap_content" 
     android:layout_height="fill_parent" 
     android:layout_weight="1" 
     android:gravity="center_vertical" 
     android:text="Title"/> 
     <LinearLayout 
       android:id="@+id/noteViewButtonLayout" 
       android:orientation="horizontal" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:padding="5dip" 
       android:visibility="gone" 
       android:layout_gravity="center_vertical"> 
      <Button android:id="@+id/noteViewEditButton" 
        android:layout_width="80dp" 
        android:layout_height="fill_parent" 
        android:background="@drawable/drawngreenbutton" 
        android:textStyle="bold" 
        android:text="Edit"/> 
      <Button android:id="@+id/noteViewDeleteButton" 
        android:layout_width="80dp" 
        android:layout_height="fill_parent" 
        android:background="@drawable/drawnredbutton" 
        android:textStyle="bold" 
        android:text="Delete"/> 
     </LinearLayout> 
    </LinearLayout> 
    <LinearLayout android:orientation="horizontal" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 
    <TextView android:id="@+id/noteViewDetails" 
    android:layout_width="0dip" 
    android:layout_height="wrap_content" 
    android:layout_weight="2" 
    android:layout_marginRight="10dip" 
    android:visibility="gone" 
    android:focusable="false" 
    android:bufferType="spannable"/> 
    <TextView 
    android:id="@+id/noteViewDetailsRight" 
    android:layout_width="0dip" 
    android:layout_height="wrap_content" 
    android:layout_weight="1" 
    android:visibility="gone" 
    android:focusable="false" 
    android:bufferType="spannable" 
    android:gravity="right"/></LinearLayout> 
</merge> 

回答

2

我已經當使用複選框在ListView項目佈局happends類似的問題。 請檢查是否添加屬性: 機器人:可調焦=「假」 的複選框定義有助於你喜歡:

<CheckBox android:id="@+id/noteViewCB" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:focusable="false" /> 

這個問題似乎是安卓不允許您選擇具有列表項可聚焦的元素。

最好,

+0

我在開發早期有同樣的問題,並發現focusable =「false」是解決方案。然後,我將佈局更改爲自定義視圖,而不是直接的XML佈局,並忘記在我的所有實驗中再次執行此操作。我曾嘗試通過xml阻止後代的可聚焦性,但我從未進入單獨的按鈕進行焦點控制。謝謝,工作完美。 – CodeFusionMobile 2010-10-08 17:03:58

相關問題