java - 当某些组为空时 ExpandableListView 崩溃

标签 java android expandablelistview

我正在开发一个 Android 应用程序,它实现了一个带有 ExpandableListView 菜单的抽屉导航,在此 View 中,某些元素应该有子元素,而其他元素则必须在单击时执行操作,而没有子元素。 我的问题是,我遇到了一些随机崩溃,我不明白是什么原因造成的。这是错误代码:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.toptainer.www, PID: 9722 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at 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;
    }
}

Activity 的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);

    }

任何帮助将不胜感激。

最佳答案

在您的 getChildView()

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

txtListChildnull不知何故。这就是为什么你会得到 NullPointerException .

Why ?

原因是您针对不同情况夸大了不同的布局 - R.layout.menu_item对于有 child 的团体和 R.layout.empty_item查看没有 child 的组

但是只有在以下情况下您才会夸大 View

if (convertView == null) 

在这种情况下,假设最后一个 View 膨胀为 R.layout.empty_item如果下一个项目是没有子项的组,则 if (convertView == null)将返回 false,因此您的 R.layout.menu_item不会充气并且会重复使用R.layout.empty_item 。在这种情况下,您将不会拥有 textView (这将为空)。这会给你 NullPointerException。

Solution

您必须通过使两个布局的父布局不同来更改它们。 假设 R.layout.empty_item 的父布局是 RelativeLayoutR.layout.menu_itemLinearLayout 。 改变你的 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;

希望这会有所帮助!

关于java - 当某些组为空时 ExpandableListView 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36091768/

相关文章:

android - ExpandableListview android 中每个组标题的不同子布局

java - 如何在 JSP 中显示从 Hibernate 查询获得的列表

java - Cordova Android 的自定义插件

android - 以编程方式显示 NavigationView MenuItems 全息指示器

用于检测 Google map 方向何时完成的 Android 应用程序

java - 如何锁定threadS写入线程读取的两个变量(Android)

Android的ExpandableListView : Keep groups expanded/unexpanded when removing an item

android - 将子项添加到 ExpandableListView 的特定 header

java - 单例类对象存在多久

java - @Autowired 在 Spring 中的类上