2013-12-10 5 views
0

각 행에 확인란과 텍스트 뷰가 포함되어있는 목록이 있습니다. 또한 목록의 모든 확인란을 선택/선택 취소해야하는 버튼이 있습니다. 화면의 바깥쪽에있는 체크 박스를 사용하여이 작업을 수행 할 수 있습니다. 화면의 바깥에있는 항목이 없기 때문에 잘 이해하면 스크롤하는 동안 새 행을 만들기 위해 재활용되고 화면 밖으로 체크 박스를 확인하거나 액세스하려고 할 때 색인 오류가 발생합니다.ListView에서 모든 확인란을 선택하는 방법

해결책을 찾았지만 지금까지 아무 것도 작동하지 않았습니다.

어떻게 해결할 수 있습니까? 더 많은 코드가 필요

public class AlumnoArrayAdapter<T> extends BaseAdapter{ 

    Context mContext; 
    LayoutInflater mInflater; 
    ArrayList<T> mList; 
    ArrayList<Alumno> alumno; 
    boolean verEstadisticas; 
    SparseBooleanArray mSparseBooleanArray; 

    public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) { 

     //TODO Auto-generated constructor stub 
     this.alumno = alumno; 
     this.verEstadisticas = verEstadisticas; 

     this.mContext = context; 

     mInflater = LayoutInflater.from(mContext); 
     mSparseBooleanArray = new SparseBooleanArray(); 
     mList = new ArrayList<T>(); 
     this.mList = list; 
    } 

    public ArrayList<T> getCheckedItems() { 
     ArrayList<T> mTempArry = new ArrayList<T>(); 

     for(int i=0;i<mList.size();i++) { 
      if(mSparseBooleanArray.get(i)) { 
       mTempArry.add(mList.get(i)); 
      } 
     } 
     return mTempArry; 
    } 

    public int getCount() { 
     return mList.size(); 
    } 

    public Object getItem(int position) { 
     return mList.get(position); 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) {  

     if(convertView == null) { 
      convertView = mInflater.inflate(R.layout.row, null); 
     } 

     TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle); 
     tvTitle.setText(mList.get(position).toString()); 

     CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable); 
     mCheckBox.setTag((Integer) position); 
     mCheckBox.setChecked(mSparseBooleanArray.get(position)); 
     mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener); 

     if(verEstadisticas){ 
      mCheckBox.setVisibility(View.GONE); 
     } 

     mCheckBox.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       CheckBox cb = (CheckBox) v; 
       Integer position = (Integer) cb.getTag(); 
       alumno.get(position).setChecked(cb.isChecked());     
      } 
     });  

     return convertView; 
    } 

    OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() { 

     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {    
      mSparseBooleanArray.put((Integer) buttonView.getTag(), isChecked);   
     } 
    }; 
} 

경우 알려 주시기 바랍니다 : 여기에

는 어댑터입니다.

도움을 주시면 감사하겠습니다.

미리 감사드립니다.

편집 : 솔루션! 수정 된 어댑터를 얻었다 :

당신은 당신의 기본 데이터 구조에서 "확인"정보를 조작해야
public class AlumnoArrayAdapter<T> extends BaseAdapter{ 

    Context mContext; 
    LayoutInflater mInflater; 
    ArrayList<T> mList; 
    ArrayList<Alumno> alumno; 
    boolean verEstadisticas; 
    SparseBooleanArray mSparseBooleanArray; 

    boolean checarTodo = false; 

    public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) { 

     //TODO Auto-generated constructor stub 
     this.alumno = alumno; 
     this.verEstadisticas = verEstadisticas; 

     this.mContext = context; 

     mInflater = LayoutInflater.from(mContext); 
     mSparseBooleanArray = new SparseBooleanArray(); 
     mList = new ArrayList<T>(); 
     this.mList = list; 
    } 

    public ArrayList<T> getCheckedItems() { 
     ArrayList<T> mTempArry = new ArrayList<T>(); 

     for(int i=0;i<mList.size();i++) { 
      if(mSparseBooleanArray.get(i)) { 
       mTempArry.add(mList.get(i)); 
      } 
     } 
     return mTempArry; 
    } 

    public int getCount() { 
     return mList.size(); 
    } 

    public Object getItem(int position) { 
     return mList.get(position); 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    public void checkAll(){ 
     for(int x = 0; x < alumno.size(); x++){ 
      alumno.get(x).setChecked(!alumno.get(x).isChecked()); 
     } 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) {  

     if(convertView == null) { 
      convertView = mInflater.inflate(R.layout.row, null); 
     } 

     TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle); 
     tvTitle.setText(mList.get(position).toString()); 

     CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable); 
     mCheckBox.setTag((Integer) position); 
     mCheckBox.setChecked(alumno.get(position).isChecked()); 

     if(verEstadisticas){ 
      mCheckBox.setVisibility(View.GONE); 
     } 

     mCheckBox.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       CheckBox cb = (CheckBox) v; 
       //Alumno Alumno = (Alumno) cb.getTag(); 
       Integer position = (Integer) cb.getTag(); 
       alumno.get(position).setChecked(cb.isChecked());     
      } 
     });  

     return convertView; 
    } 


} 

답변

2

당신은 다음과 같은 시도 할 수 있습니다 :

  1. 이 어댑터와 동일하게 설정하는 방법에 하나 개의 부울 속성을 추가합니다.
  2. 모든 확인란을 선택하려는 버튼을 클릭하십시오. 부울 값을 설정하려면 어댑터 메소드를 호출하십시오. notifyDataSetChanged를 호출하면 목록 뷰를 무효화하고 다시 그려야합니다.
  3. 다시 그리기 프로세스 중에 어댑터의 getView 메소드가 호출됩니다. 따라서이 메소드에서 부울 값이 true 또는 false로 설정되었는지 확인하고 그에 따라 선택란을 선택 또는 선택 취소하십시오.

이 단계가 도움이되기를 바랍니다.

+0

:

<?xml version="1.0" encoding="utf-8"?> <com.example.ExampleListItemView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" ndroid:addStatesFromChildren="true" > <CheckBox android:id="@+id/cbExample" /> <TextView android:id="@+id/txtExample" android:layout_toRightOf="@id/cbExample" /> </com.example.ExampleListItemView> 

그런 다음이 같은 끝낼 것 완성도를 들어, 여기에 체크 할 뷰의 예입니다 아주. 정확히 제안한 내용을 약간 수정했습니다. "checkAll"플래그에 부울 속성을 사용하지 않았습니다. 대신 "checkAll"메서드에서 데이터 구조의 확인란에 대한 부울 데이터를 수정하고 notifyDataSetChanged를 호출하여 목록을 다시 그리는 대신 mSparseBooleanArray를 사용하여 확인란의 상태를 설정하는 대신 저장 위치에 ArrayList를 사용했습니다. 내가 필요한 데이터. OP에서 수정 된 어댑터를 볼 수 있으며 함께 수정했습니다. 다시 한 번 감사드립니다! – Moko

1

. 말하듯이 GUI 객체는 기본 데이터에 시각적 양식을 나타내는 용도로만 사용됩니다. 유감 스럽지만 응용 프로그램 상태 정보를 유지하는 유일한 수단으로 GUI 객체를 사용하는 것은 좋지 않습니다.

1

이 코드를 확인하십시오. 어댑터를 채택하십시오. 그것은 동일하지 않습니다. 그러나 약간의 수정은 확실히 작동 할 것입니다.

class CustomAdapter extends ArrayAdapter<ContactPerson>{ 
     private ArrayList<ContactPerson> contactList; 

     public CustomAdapter(Context context, int textViewResourceId, 
       ArrayList<ContactPerson> contactList) { 
      super(context, textViewResourceId, contactList); 
      // TODO Auto-generated constructor stub 
      this.contactList = new ArrayList<ContactPerson>(); 
      this.contactList.addAll(contactList); 
     } 

     private class ViewHolder{ 
      TextView ContactName; 
      CheckBox contactCheck; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      // TODO Auto-generated method stub 

      ViewHolder holder = null; 
      Log.v("Convert View", String.valueOf(position)); 

      if(convertView==null){ 
       LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

       convertView = inflater.inflate(R.layout.checkbox_item, null); 

       holder = new ViewHolder(); 
       holder.ContactName = (TextView) convertView.findViewById(R.id.contact_name); 
       holder.contactCheck = (CheckBox) convertView.findViewById(R.id.contact_check); 

       convertView.setTag(holder); 

       holder.contactCheck.setOnClickListener(new View.OnClickListener() { 

        @Override 
        public void onClick(View v) { 
         // TODO Auto-generated method stub 
         CheckBox cb = (CheckBox) v; 
         ContactPerson contact = (ContactPerson) cb.getTag(); 
//      Log.i("clicked users", contact.getName()); 

         contact.setSelected(cb.isChecked()); 
        } 
       }); 
      } 
      else{ 
       holder = (ViewHolder) convertView.getTag(); 
      } 

      ContactPerson contacts = contactList.get(position); 
      holder.ContactName.setText("("+contacts.getName()+")"); 
      holder.contactCheck.setChecked(contacts.isSelected()); 
      holder.contactCheck.setTag(contacts); 
      holder.ContactName.setText(contacts.getName()); 
      return convertView; 
     } 
    } 



    private void checkButtonClick(){ 
     Button nextButton = (Button) findViewById(R.id.selected_done); 
     nextButton.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       StringBuffer display = new StringBuffer(); 
       display.append("the selected contacts are"); 

       ArrayList<ContactPerson> finalContactList = contactAdapter.contactList; 
       for(int i=0;i<finalContactList.size();i++){ 
        ContactPerson selected = finalContactList.get(i); 
        if(selected.isSelected()){ 
         display.append("\n"+selected.getName()+"\t"+selected.getPhoneNumber()); 
        } 
       } 
       Toast.makeText(getApplicationContext(), display, Toast.LENGTH_LONG).show(); 
      } 
     }); 
    } 
1

내가 선택한 항목 표시에 대한 기본 목록보기 기능을 사용합니다 : setItemChecked, 행에 대한 사용자 정의 체크 할 뷰와 결합합니다. 확인 가능한보기를 만드는 데 유용한 연습 (확인란 자식을 다루는 섹션 포함)은 Here을 참조하십시오.

public class ExampleListItemView extends RelativeLayout implements Checkable { 

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

    public ExampleListItemView(Context context) { 
      super(context); 
    } 

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

    public ExampleListItemView(Context context, AttributeSet attrs, 
        int defStyle) { 
      super(context, attrs, defStyle); 
    } 

    TextView txtExample; 
    CheckBox cbExample; 

    private boolean isChecked = false; 

    @Override 
    protected void onFinishInflate() { 
      super.onFinishInflate();   
      txtExample = (TextView) findViewById(R.id.txtExample); 
      cbExample = (CheckBox) findViewById(R.id.cbExample); 
      isChecked = false; 
    } 

    public void setText(String text){ 
      txtExample.setText(text); 
    } 

    @Override 
    public boolean isChecked() { 
      return isChecked; 
    } 

    @Override 
    public void setChecked(boolean checked) {     

      if (isChecked != checked) { 
        cbExample.setChecked(checked); 
        isChecked = checked; 
        refreshDrawableState(); 
      } 
    } 

    @Override 
    public void toggle() { 
      setChecked(!isChecked); 
    } 

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

및 관련 XML 레이아웃 :이 일을

for(int i = 0; i < adapter.getCount(); i++){ 
    listView.setItemChecked(i, true); 
} 

SparseBooleanArray checked = listView.getCheckedItemPositions(); 
관련 문제