2016-12-27 53 views
-2

我有一個自定義視圖(其中有複選框)listview。我還在活動版面中添加了checkbox以選擇全部checkboxes。當我選中活動複選框時,我收到所有listview項目,但我無法將listview中的所有checkboxes選中。當我嘗試在for循環中使用getChildAt()時,我得到一個空指針。如何使用getChildAt獲取listview行的元素

// row layout 

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:id="@+id/rootlay"> 

    <CheckBox 
     android:id="@+id/cbBox" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" > 
    </CheckBox> 

    <LinearLayout 
     android:id="@+id/linearLayout1" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="5dp" 
     android:orientation="vertical" 
     android:layout_weight="1" > 

     <TextView 
      android:id="@+id/tvDescr" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_margin="5dp" 
      android:text="" 
      android:textSize="20sp" > 
     </TextView> 

     <TextView 
      android:id="@+id/tvPrice" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="5dp" 
      android:text="" > 
     </TextView> 
    </LinearLayout> 


</LinearLayout> 
public class ContactsPickerActivity extends AppCompatActivity{ 

    ArrayList<Model> arrayList = new ArrayList<>(); 
    ListView list; 
    CustomAdapter adapter; 
    CheckBox selectall; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_contact); 

     list = (ListView)findViewById(R.id.list); 
     Button loadbtn = (Button)findViewById(R.id.loadbtn); 
     loadbtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ 
        askForPermission(Manifest.permission.READ_CONTACTS,1100); 
       }else{ 
        new LoadContactsAyscn().execute(); 
       } 

      } 
     }); 

     Button getbtn = (Button)findViewById(R.id.getbtn); 
     getbtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       String result = "Selected Product are :"; 
       for (Model p : adapter.getBox()) { 
        if (p.box){ 
         result += "\n" + p.price; 
        } 
       } 
       Toast.makeText(ContactsPickerActivity.this, result, Toast.LENGTH_LONG).show(); 
      } 
     }); 

     adapter = new CustomAdapter(ContactsPickerActivity.this, arrayList); 
     list.setAdapter(adapter); 

     selectall = (CheckBox)findViewById(R.id.selectall); 
     selectall.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
       if(b){ 
        int count = list.getAdapter().getCount(); 
        System.out.println("sammy_total_count "+count); 
        for(int i=0; i<count; i++){ 
         adapter.getProduct(i).box=true; 
         LinearLayout itemlay = (LinearLayout)list.getChildAt(i); 
         CheckBox checkBox = (CheckBox)itemlay.findViewById(R.id.cbBox); 
         checkBox.setTag(i); 
         checkBox.setChecked(adapter.getProduct(i).box); 
        } 
       }else{ 
        int count = list.getAdapter().getCount(); 
        System.out.println("sammy_total_count "+count); 
        for(int i=0; i<count; i++){ 
         adapter.getProduct(i).box=false; 
         LinearLayout itemlay = (LinearLayout)list.getChildAt(i); 
         CheckBox checkBox = (CheckBox)itemlay.findViewById(R.id.cbBox); 
         checkBox.setTag(i); 
         checkBox.setChecked(adapter.getProduct(i).box); 
        } 
       } 

      } 
     }); 
    } 

    private void askForPermission(String permission, Integer requestCode) { 
     System.out.println("sammy_reached_askForPermission"); 
     if (ContextCompat.checkSelfPermission(ContactsPickerActivity.this, permission) != PackageManager.PERMISSION_GRANTED) { 

      if(ActivityCompat.shouldShowRequestPermissionRationale(ContactsPickerActivity.this, permission)) { 
       // if (shouldShowRequestPermissionRationale(permission)) { // for fragment 

       ActivityCompat.requestPermissions(ContactsPickerActivity.this, new String[]{permission}, requestCode); 
       // requestPermissions(new String[]{permission}, requestCode); // for fragment 

      } else { 

       ActivityCompat.requestPermissions(ContactsPickerActivity.this, new String[]{permission}, requestCode); 
       // requestPermissions(new String[]{permission}, requestCode); // for fragment 
      } 
     } else { 
      new LoadContactsAyscn().execute(); 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     System.out.println("sammy_reached_onRequestPermissionsResult"); 
     if(ActivityCompat.checkSelfPermission(ContactsPickerActivity.this, permissions[0]) == PackageManager.PERMISSION_GRANTED){ 
      if(requestCode==1100){ 
       new LoadContactsAyscn().execute(); 
      } 
      Toast.makeText(ContactsPickerActivity.this, "Permission granted", Toast.LENGTH_SHORT).show(); 
     }else{ 
      Toast.makeText(ContactsPickerActivity.this, "Permission denied", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    class LoadContactsAyscn extends AsyncTask<Void, Void, ArrayList<Model>> { 
     ProgressDialog pd; 

     @Override 
     protected void onPreExecute() { 
      // TODO Auto-generated method stub 
      super.onPreExecute(); 

      pd = ProgressDialog.show(ContactsPickerActivity.this, "Loading Contacts", 
        "Please Wait"); 
     } 

     @Override 
     protected ArrayList<Model> doInBackground(Void... params) { 


      Cursor c = getContentResolver().query(
        ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
        null, null, null); 
      while (c.moveToNext()) { 

       String contactName = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
       String phNumber = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 


       arrayList.add(new Model(contactName,phNumber, false)); 

      } 
      c.close(); 

      return arrayList; 
     } 

     @Override 
     protected void onPostExecute(ArrayList<Model> contacts) { 
      // TODO Auto-generated method stub 
      super.onPostExecute(contacts); 

      pd.cancel(); 
      adapter.notifyDataSetChanged(); 


     } 

    } 
} 
+0

你在哪裏初始化適配器? –

+0

什麼是列表和您初始化它的位置?活動中的 –

+0

。 @RandykaYudhistira –

回答

0

更改這個樣子,

for(int i=0; i<count; i++){ 
        adapter.getProduct(i).box=true; 
        View rowView = list.getChildAt(i); 
        LinearLayout itemlay = (LinearLayout)rowView.findViewById(R.id.id); 
        CheckBox checkBox = (CheckBox)rowView.findViewById(R.id.cbBox); 
        checkBox.setTag(i); 
        checkBox.setChecked(adapter.getProduct(i).box); 
       } 

這裏是可見的項目,總項目的問題。 NPE正在獲得,因爲並非所有項目都在視野之內。 所以,你需要改變這樣的,

for(int i=0; i<count; i++){ 
        adapter.getProduct(i).box=true; 
        notifyDataSetChanged(); 
       } 

而內部列表適配器getView()方法

checkBox.setChecked(adapter.getProduct(i).box); 

確保getProduct(I).box的值不爲空

+0

我使用了上面的代碼,但仍然給它NPE @ Exigente05 –

+0

您使用什麼標識獲取LinearLayout? – Exigente05

+0

R.id.rootlay @ Exigente05 –

1

更好的是你可以定義一個

 ArrayList<ViewHolder> holders = new ArrayList<>(); 

,並在適配器中只需添加你的人進入名單像

  holders.add(holder); 

,每當您按複選框只得到持有人,並獲得該複選框,並設置複選框狀態就像下面

(holders.get(POSITION)).checkbox.setChecked(boolean); 

這將是一件簡單而容易的事情......

希望它有幫助!

0

我認爲您應該在您的模型中更改"box"屬性並使用notifyDataSetChanged()

ListView將被刷新,並且CheckBoxes將被您的boolean字段更新。