2014-01-25 3 views
3

Я использую этот зритель неправильно? Я получаю NPE на линии 165. Есть ли очевидная причина, по которой мне не хватает? Нужен ли мне аудитор группы и дочерний зритель, если я использую expandablelistview? Я выделил строку 165, чтобы попытаться облегчить глаза.Нужно ли мне несколько viewHolders для ExpandableListView?

Большое спасибо

мой expandablelistview, что это получение NPE:

public class MyExpandableListAdapter extends BaseExpandableListAdapter { 

    private Context mContext; 
    private ArrayList<ContactNameItems> mListDataHeader; 
    private ArrayList<Boolean> phoneNumberCheckStates; 
    private ArrayList<String> selectedNumbers; 

    private HashMap<String, List<ContactPhoneItems>> mListDataChild; 

    private ViewHolder mViewHolder; 

    public MyExpandableListAdapter(Context context, 
      ArrayList<ContactNameItems> listDataHeader, 
      HashMap<String, List<ContactPhoneItems>> listDataChild, 
      ArrayList<String> listOfNumbers) { 

     mContext = context; 
     mListDataHeader = listDataHeader; 
     mListDataChild = listDataChild; 
     selectedNumbers = listOfNumbers; 
    } 

    @Override 
    public int getGroupCount() { 
     return mListDataHeader.size(); 
    } 

    @Override 
    public ContactNameItems getGroup(int groupPosition) { 
     return mListDataHeader.get(groupPosition); 
    } 

    @Override 
    public long getGroupId(int groupPosition) { 
     return groupPosition; 
    } 

    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, 
      View convertView, ViewGroup parent) { 

     String contactName = getGroup(groupPosition).getName(); 
     Bitmap contactImage = getGroup(groupPosition).getImage(); 

     if (convertView == null) { 

      LayoutInflater inflater = (LayoutInflater) mContext 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.contact_name_item, null); 

      mViewHolder = new ViewHolder(); 

      mViewHolder.mContactName = (TextView) convertView 
        .findViewById(R.id.lblListHeader); 

      mViewHolder.mContactImage = (ImageView) convertView 
        .findViewById(R.id.ivContactPhoto); 

      convertView.setTag(mViewHolder); 
     } else { 

      mViewHolder = (ViewHolder) convertView.getTag(); 
     } 

     if (contactImage != null) { 
      mViewHolder.mContactImage.setImageBitmap(contactImage); 

     } else { 
      mViewHolder.mContactImage.setImageResource(R.drawable.default_contact); 
     } 

     mViewHolder.mContactName.setText(contactName); 

     return convertView; 
    } 

    @Override 
    public int getChildrenCount(int groupPosition) { 
     return mListDataChild.get(mListDataHeader.get(groupPosition).getName()) 
       .size(); 
    } 

    @Override 
    public ContactPhoneItems getChild(int groupPosition, int childPosition) { 
     return mListDataChild.get(mListDataHeader.get(groupPosition).getName()) 
       .get(childPosition); 
    } 

    @Override 
    public long getChildId(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    @Override 
    public View getChildView(int groupPosition, final int childPosition, 
      boolean isLastChild, View convertView, ViewGroup parent) { 

     String numberText = getChild(groupPosition, childPosition).getNumber(); 
     String typeText = getChild(groupPosition, childPosition).getPhoneType(); 

     final int mGroupPosition = groupPosition; 

     if (convertView == null) { 

      LayoutInflater inflater = (LayoutInflater) this.mContext 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.contact_detail_item, null); 

      mViewHolder = new ViewHolder(); 

      mViewHolder.mPhoneNumber = (TextView) convertView 
        .findViewById(R.id.tv_phone_number); 

      mViewHolder.mPhoneType = (TextView) convertView 
        .findViewById(R.id.tv_phone_type); 

      mViewHolder.mCheckBox = (CheckBox) convertView 
        .findViewById(R.id.checkBox); 

      convertView.setTag(mViewHolder); 

     } else { 

      mViewHolder = (ViewHolder) convertView.getTag(); 
     } 

     mViewHolder.mPhoneNumber.setText(numberText); 
     mViewHolder.mPhoneType.setText(typeText); 

     phoneNumberCheckStates = new ArrayList<Boolean>(); 

     for (int i = 0; i < mListDataChild.size(); i++) { 

      phoneNumberCheckStates.add(false); 
     } 

     if (phoneNumberCheckStates.get(childPosition)) { 
      mViewHolder.mCheckBox.setChecked(true); 
     } else { 
      mViewHolder.mCheckBox.setChecked(false); 
     } 

     mViewHolder.mCheckBox.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

/*this is line 165*/ if (mViewHolder.mCheckBox.isChecked()) { /*this is line 165*/ 
        phoneNumberCheckStates.set(childPosition, true); 

        selectedNumbers.add(mListDataChild 
          .get(mListDataHeader.get(mGroupPosition).getName()) 
          .get(childPosition).getNumber()); 

       } else { 
        phoneNumberCheckStates.set(childPosition, false); 

        selectedNumbers.remove(mListDataChild 
          .get(mListDataHeader.get(mGroupPosition).getName()) 
          .get(childPosition).getNumber()); 
       } 
      } 
     }); 

     return convertView; 
    } 

    @Override 
    public boolean isChildSelectable(int groupPosition, int childPosition) { 
     return false; 
    } 

    @Override 
    public boolean hasStableIds() { 
     return false; 
    } 

    public ArrayList<Boolean> getCheckedNumbers() { 

     return phoneNumberCheckStates; 
    } 

    public ArrayList<String> getSelectedNumbers() { 

     return selectedNumbers; 
    } 

    private class ViewHolder { 

     TextView mContactName; 
     TextView mPhoneNumber; 
     TextView mPhoneType; 
     ImageView mContactImage; 
     CheckBox mCheckBox; 
    } 
} 

, если это поможет, вот Log:

01-25 04:34:31.695: E/AndroidRuntime(7074): FATAL EXCEPTION: main 
01-25 04:34:31.695: E/AndroidRuntime(7074): java.lang.NullPointerException 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at com.psesto.journeysend.contactpicker.MyExpandableListAdapter$1.onClick(MyExpandableListAdapter.java:165) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.view.View.performClick(View.java:4204) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.widget.CompoundButton.performClick(CompoundButton.java:100) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.view.View$PerformClick.run(View.java:17355) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.os.Handler.handleCallback(Handler.java:725) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.os.Handler.dispatchMessage(Handler.java:92) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.os.Looper.loop(Looper.java:137) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at android.app.ActivityThread.main(ActivityThread.java:5041) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at java.lang.reflect.Method.invoke(Method.java:511) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
01-25 04:34:31.695: E/AndroidRuntime(7074):  at dalvik.system.NativeStart.main(Native Method) 

ответ

2

У вас есть один ViewHolder ссылки в вашем Adapter для всех ваших Views. Это не имеет смысла, потому что каждый вид в списке имеет свой собственный экземпляр ViewHolder, который вы получаете по View.getTag().

Вы можете установить int[] с позиции, вам нужно, как тег CheckBox

int[] positions = new int[2]; 
    positions[0] = childPosition; 
    positions[1] = groupPosition; 
    mViewHolder.mCheckBox.setTag(positions); 

и в onClick()

CheckBox box = (CheckBox) v; 
    int[] posTag = (int[]) v.getTag(); 

Тогда у вас есть CheckBox для государства и позиции для отдыха

-1

Это происходит, если Child «посмотреть повторное использование a Group, а также ViewHolder. Очевидно, что он не может найти mCheckBox в строке 165, потому что он не был установлен.
Просто добавьте флаг в ViewHolder, чтобы проверить, есть ли ViewHolder может решить вашу проблему. Не нужно иметь два вида ViewHolder здесь.
Надежда помогает

+0

Извините, но я не знаю, что вы подразумеваете, добавив флаг. Извините, самоучка здесь. Учусь как я иду – Psest328

6

Я принял ответ Towlie288, потому что он указал мне в правильном направлении. Вот изменение кода, которое заставило все работать:

public class MyExpandableListAdapter extends BaseExpandableListAdapter { 

    private Context mContext; 
    private ArrayList<ContactNameItems> mListDataHeader; 
    private ArrayList<String> selectedNumbers; 

    private HashMap<String, List<ContactPhoneItems>> mListDataChild; 

    private ChildViewHolder childViewHolder; 
    private GroupViewHolder groupViewHolder; 

    public MyExpandableListAdapter(Context context, 
      ArrayList<ContactNameItems> listDataHeader, 
      HashMap<String, List<ContactPhoneItems>> listDataChild, 
      ArrayList<String> listOfNumbers) { 

     mContext = context; 
     mListDataHeader = listDataHeader; 
     mListDataChild = listDataChild; 
     selectedNumbers = listOfNumbers; 

    } 

    @Override 
    public int getGroupCount() { 
     return mListDataHeader.size(); 
    } 

    @Override 
    public ContactNameItems getGroup(int groupPosition) { 
     return mListDataHeader.get(groupPosition); 
    } 

    @Override 
    public long getGroupId(int groupPosition) { 
     return groupPosition; 
    } 

    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, 
      View convertView, ViewGroup parent) { 

     String contactName = getGroup(groupPosition).getName(); 
     Bitmap contactImage = getGroup(groupPosition).getImage(); 

     if (convertView == null) { 

      LayoutInflater inflater = (LayoutInflater) mContext 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.contact_name_item, null); 

      groupViewHolder = new GroupViewHolder(); 

      groupViewHolder.mContactName = (TextView) convertView 
        .findViewById(R.id.lblListHeader); 

      groupViewHolder.mContactImage = (ImageView) convertView 
        .findViewById(R.id.ivContactPhoto); 

      convertView.setTag(groupViewHolder); 
     } else { 

      groupViewHolder = (GroupViewHolder) convertView.getTag(); 
     } 

     if (contactImage != null) { 
      groupViewHolder.mContactImage.setImageBitmap(contactImage); 

     } else { 
      groupViewHolder.mContactImage 
        .setImageResource(R.drawable.default_contact); 
     } 

     groupViewHolder.mContactName.setText(contactName); 

     return convertView; 
    } 

    @Override 
    public int getChildrenCount(int groupPosition) { 
     return mListDataChild.get(mListDataHeader.get(groupPosition).getName()) 
       .size(); 
    } 

    @Override 
    public ContactPhoneItems getChild(int groupPosition, int childPosition) { 
     return mListDataChild.get(mListDataHeader.get(groupPosition).getName()) 
       .get(childPosition); 
    } 

    @Override 
    public long getChildId(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    @Override 
    public View getChildView(int groupPosition, final int childPosition, 
      boolean isLastChild, View convertView, ViewGroup parent) { 

     String numberText = getChild(groupPosition, childPosition).getNumber(); 
     String typeText = getChild(groupPosition, childPosition).getPhoneType(); 

     final int mGroupPosition = groupPosition; 

     if (convertView == null) { 

      LayoutInflater inflater = (LayoutInflater) this.mContext 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.contact_detail_item, null); 

      childViewHolder = new ChildViewHolder(); 

      childViewHolder.mPhoneNumber = (TextView) convertView 
        .findViewById(R.id.tv_phone_number); 

      childViewHolder.mPhoneType = (TextView) convertView 
        .findViewById(R.id.tv_phone_type); 

      childViewHolder.mCheckBox = (CheckBox) convertView 
        .findViewById(R.id.checkBox); 

      childViewHolder.mCheckBox.setOnCheckedChangeListener(checkListener); 

      convertView.setTag(childViewHolder); 

     } else { 

      childViewHolder = (ChildViewHolder) convertView.getTag(); 
     } 

     childViewHolder.mPhoneNumber.setText(numberText); 
     childViewHolder.mPhoneType.setText(typeText); 

     ContactPhoneItems cpi = getChild(mGroupPosition, childPosition); 

     childViewHolder.mCheckBox.setTag(cpi); 
     childViewHolder.mCheckBox.setChecked(cpi.getSelected()); 

     // for managing the state of the boolean 
     // array according to the state of the 
     // CheckBox 

     childViewHolder.mCheckBox 
       .setOnClickListener(new View.OnClickListener() { 

        String contactNumber = mListDataChild 
          .get(mListDataHeader.get(mGroupPosition).getName()) 
          .get(childPosition).getNumber(); 

        public void onClick(View v) { 

         boolean isChecked = ((CheckBox) v).isChecked(); 

         if (isChecked) { 

          selectedNumbers.add(contactNumber); 

         } else { 

          selectedNumbers.remove(contactNumber); 
         } 

         getChild(mGroupPosition, childPosition).setSelected(isChecked); 
         notifyDataSetChanged(); 
        } 
       }); 

     return convertView; 
    } 

    @Override 
    public boolean isChildSelectable(int groupPosition, int childPosition) { 
     return false; 
    } 

    @Override 
    public boolean hasStableIds() { 
     return false; 
    } 

    public ArrayList<String> getSelectedNumbers() { 

     return selectedNumbers; 
    } 

    public final class GroupViewHolder { 

     TextView mContactName; 
     ImageView mContactImage; 
    } 

    public final class ChildViewHolder { 

     TextView mPhoneNumber; 
     TextView mPhoneType; 
     CheckBox mCheckBox; 
    } 

    OnCheckedChangeListener checkListener = new OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 

      ContactPhoneItems c = (ContactPhoneItems) buttonView.getTag(); 
      c.setSelected(isChecked); 
     } 
    }; 
} 
+1

Звучит хорошо со мной. Просто примечание: я заметил, что вы использовали надувание (R.layout.contact_detail_item, null); вместо раздувания (R.layout.contact_detail_item, parent, false); Позже кажется, что это лучший вариант, если я правильно проинформирован. –

+0

Кстати, ваш окончательный int mGroupPosition никогда не используется? Или мне что-то не хватает? –

+0

Используется, просто выполните поиск. Но с recyclerview, я считаю, что это немного устарело. – Psest328

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