如何使用getChildAt

时间:2016-12-27 07:28:58

标签: android listview nullpointerexception android-checkbox

我有listview的自定义视图(有复选框)。我还在活动布局中添加了checkbox来选择所有checkboxes。我在选中活动复选框时收到了所有listview项,但我无法检查checkboxes中的所有listview。当我尝试在for循环中使用getChildAt()时,我得到了一个空指针。

// 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();


        }

    }
}

3 个答案:

答案 0 :(得分:1)

最好你可以定义一个

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

并在您的适配器中将您的持有人添加到列表中

          holders.add(holder);

每当您按下复选框时,只需获取持有人并获取复选框并设置复选框状态,如下所示

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

它会变得简单易行......

希望它有所帮助!!!

答案 1 :(得分: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值不为空

答案 2 :(得分:0)

我认为您应该更改模型中的"box"属性并使用notifyDataSetChanged()

ListView将被刷新,CheckBoxes将由您的boolean字段进行更新。