2010-10-08 3 views
1

У меня есть ExpandableListView, который я хочу заполнить специальными видами типа NoteView. NoteView расширяет LinearLayout и содержит две кнопки и флажок. У меня почти все работает: NoteView заполняется данными резервного копирования, списки заполняются, кнопки можно щелкнуть и выполнить требуемые задачи.Как реализовать пользовательскую строку списка с кнопками?

Проблема: ExpandableListView больше не отвечает на события click/longclick/keypress вообще (кроме выбора элементов списка с трекболом/DPAD).

Я заменил свой пользовательский вид стандартным TextView, и события прикосновения текли нормально, поэтому почти наверняка что-то не так с моим пользовательским представлением или каким-то неясным параметром ListView, который я просматриваю.

Вот мой код NoteView и XML Layout. Что мне не хватает?

//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

У меня была аналогичная проблема, что happends при использовании флажок в макете ListView элементов. Пожалуйста, проверьте, добавив атрибут: андроида: фокусируемый = «ложь» к определению CheckBox помогает вам нравится:

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

Проблема, кажется, что Android не позволяет выбрать элементы списка, которые имеют элементы на них, которые являются ориентируемыми.

Best,

+0

У меня была такая же проблема намного раньше в разработке, и выяснилось, что focusable = "false" было решением. Затем я изменил макет на свой пользовательский вид вместо прямого XML-макета и забыл сделать это снова во всех своих экспериментах. Я попытался блокировать поточность потомства через xml, но я никогда не ходил на отдельные кнопки для управления фокусом. Спасибо, отлично работал. – CodeFusionMobile

Смежные вопросы