当某些组为空时,ExpandableListView崩溃

时间:2016-03-18 18:28:01

标签: java android expandablelistview

我正在开发一个Android应用程序,它实现了一个带有ExpandableListView菜单的导航抽屉,在这个视图中,一些元素应该有子节点,而其他元素在点击时必须执行操作,没有子节点。 我的问题是我有一些随机崩溃,我无法理解可能导致它的原因。这是错误代码:

  

E / AndroidRuntime:致命异常:主要                                                                    过程:com.toptainer.www,PID:9722                                                                    java.lang.NullPointerException:尝试调用虚方法' void android.widget.TextView.setText(java.lang.CharSequence)'在null对象引用上                                                                        在com.example.nignog.toptainer.ExpandableListAdapter.getChildView(Success.java:377)

点击一个空组,然后点击一个包含子项的组,应用程序通常会崩溃,但它不会让应用程序崩溃。

无论如何,这是我的代码:

首先,我的适配器:

class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context _context;
    private List<String> _listDataHeader;
    private HashMap<String, List<String>> _listDataChild;

    public ExpandableListAdapter(Context context, List<String> listDataHeader,
                                 HashMap<String, List<String>> listChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;
    }

    @Override
    public Object getChild(int groupPosition, int childPosititon) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .get(childPosititon);
    }

    @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) {

        if(getChildrenCount(groupPosition)>1){

        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.menu_item, null);
        }

        TextView txtListChild = (TextView) convertView
                .findViewById(R.id.textoOpcion);

        txtListChild.setText(childText);
        }
        else{
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.empty_item, null);
        }
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        if(this._listDataChild.get(this._listDataHeader.get(groupPosition))
                 != null){
            return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                    .size();
        }
        return 1;

    }

    @Override
    public Object getGroup(int groupPosition) {
        return this._listDataHeader.get(groupPosition);
    }

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

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

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


        String headerTitle = (String) getGroup(groupPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.menu_item, null);
        }

        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.textoOpcion);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);
        ImageView icon = (ImageView) convertView.findViewById(R.id.Icono);

        int[] iconos = {R.drawable.ic_user, R.drawable.ic_camion, R.drawable.ic_box, R.drawable.ic_file, R.drawable.ic_report, android.R.drawable.ic_delete};
        icon.setImageResource(iconos[groupPosition]);

        if(groupPosition == 0) {
            convertView.setBackgroundColor(Color.BLACK);
            lblListHeader.setTextColor(Color.WHITE);
        }
        else {
            convertView.setBackgroundColor(Color.WHITE);
        }


        return convertView;
    }

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

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        if(getChildrenCount(groupPosition)!=1)return true;
        return false;
    }
}

活动onCreate方法:

android.support.v7.app.ActionBar ab = getSupportActionBar();
        ab.setHomeAsUpIndicator(R.drawable.hamburger_button);
        ab.setDisplayHomeAsUpEnabled(true);

        expandableList= (ExpandableListView) findViewById(R.id.left_drawer);


        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mActivityTitle = getTitle().toString();
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        String[] accionesMenu = {getSharedPreferences("Data",Context.MODE_PRIVATE).getString("Usuario", "NOUSER"), "Orden de viaje Emitidas", "Órdenes de viaje en Descarga","Órdenes de viaje en Tránsito","Órdenes de viaje Entregadas","Órdenes de viaje en Carga", "Órdenes de transporte","Guías pendientes", "Reporte", "Desconectar"};
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        expandableList = (ExpandableListView) findViewById(R.id.left_drawer);
        prepareListData();

        mMenuAdapter = new ExpandableListAdapter(this, listDataHeader,   listDataChild);

        // setting list adapter
        expandableList.setAdapter(mMenuAdapter);

        expandableList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v,
                                        int groupPosition, long id) {

                boolean booleano = expandableList.isGroupExpanded(groupPosition);
                for(int i =0;  i<5; i++){
                if(expandableList.isGroupExpanded(i)) expandableList.collapseGroup(i);}

                if(!booleano) expandableList.expandGroup(groupPosition);

                if (groupPosition == 3) startGuiasActivity();

                if (groupPosition == 5) {
                    startLoginActivity();
                }
                return true;
            }
        });

        expandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                if (groupPosition == 1) {
                    if (childPosition == 0) startOrdenesDeViajeActivity();
                    if (childPosition == 1) startOrdenesDeViajeDescargaActivity();
                    if (childPosition == 2) startOrdenesDeViajeTransitoActivity();
                    if (childPosition == 3) startOrdenesDeViajeEntregadasActivity();
                    if (childPosition == 4) startOrdenesDeViajeCargaActivity();
                }
                return false;
            }
        });

这是我的prepareData方法:

private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        // Adding data header
        listDataHeader.add(getSharedPreferences("Data", Context.MODE_PRIVATE).getString("Usuario", "NOUSER"));
        listDataHeader.add("Órdenes de Viaje");
        listDataHeader.add("Órdenes de Transporte");
        listDataHeader.add("Guías Pendientes");
        listDataHeader.add("Reporte");
        listDataHeader.add("Desconectar");

        // Adding child data
        List<String> heading1= new ArrayList<String>();
        heading1.add("Emitidas");
        heading1.add("En proceso de Descarga");
        heading1.add("En tránsito");
        heading1.add("Entregadas");
        heading1.add("En proceso de Carga");


        listDataChild.put(listDataHeader.get(1), heading1);

    }

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

getChildView()

 TextView txtListChild = (TextView) convertView.findViewById(R.id.textoOpcion);

txtListChild以某种方式null。这就是你获得NullPointerException的原因。

  

为什么?

原因是你为不同的情况夸大了不同的布局 - R.layout.menu_item适用于有孩子和有孩子的团体 R.layout.empty_item查看没有孩子的群组

但是只有在

时才会给视图充气
if (convertView == null) 

并且在这种情况下假设最后一个视图膨胀是R.layout.empty_item,如果下一个项目是没有孩子的组, if (convertView == null)将返回false,因此R.layout.menu_item不会被夸大,它将重用R.layout.empty_item。在这种情况下,您将不会拥有textView(将为空)。这将为您提供NullPointerException。

  

解决方案

您必须通过使其父布局不同来更改2个布局。 假设R.layout.empty_item的父级布局为RelativeLayoutR.layout.menu_item的父布局为LinearLayout。 更改你的getView() -

     if(getChildrenCount(groupPosition)>1){
                if(converterView == null || converterView.getClass() == RelativeLayout.class){
                    converterView = inflater.inflate(R.layout.menu_item, null);

TextView txtListChild = (TextView) convertView
                .findViewById(R.id.textoOpcion);

        txtListChild.setText(childText);
                }
            }
            else{
                if(converterView == null || converterView.getClass() == LinearLayout.class){
                    converterView = inflater.inflate(R.layout.empty_item, null);
                }
            }

return converterView;

希望这会有所帮助!