可扩展 ListView 中的 android:divider 属性使我在 Android 6.01 中的应用程序崩溃

标签 android android-fragments

我不明白为什么当可扩展 ListView 在具有分隔线设置的对话框 fragment 中膨胀时我的应用程序崩溃。它仅出现在 Android 6.0 中。 Android 4.2 没问题。

可扩展 ListView .xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/filter_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/scroll_layout"
    android:background="#fff"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ExpandableListView
        android:id="@+id/expandable_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/primaryLight"
        android:dividerHeight="5dp"/>
</LinearLayout>

部分对话 fragment :

@Override
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {

    if(savedInstanceState == null) {

        final Context context = getActivity();

        Bundle bundle = getArguments();

        Map<String, List<FilterItem>> listCollection = (Map<String, List<FilterItem>>) bundle.getSerializable(DATA);

        List<String> groupList = (List<String>) bundle.getSerializable(GROUP);

        ExpandableListView expListView = (ExpandableListView) view.findViewById(R.id.expandable_list);

        final ExpandableListAdapter expListAdapter = new ExpandableListAdapter(context, groupList, listCollection);

        expListView.setAdapter(expListAdapter);

        expListView.expandGroup(0);

    }
}

我认为崩溃是由 xml 中的分隔符设置引起的。部分错误说 setBounds(android.graphics.Rect) 失败,所以我猜它与分隔符有关:

android:divider="@color/primaryLight"
android:dividerHeight="5dp"

如果删除这两行,对话框 fragment 就能够打开。

日志:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.drawable.Drawable.setBounds(android.graphics.Rect)' on a null object reference
at android.widget.ExpandableListView.drawDivider(ExpandableListView.java:534)
at android.widget.ListView.dispatchDraw(ListView.java:3335)
at android.widget.ExpandableListView.dispatchDraw(ExpandableListView.java:351)
at android.view.View.draw(View.java:16187)
at android.widget.AbsListView.draw(AbsListView.java:4166)
at android.view.View.updateDisplayListIfDirty(View.java:15180)
at android.view.View.draw(View.java:15954)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.draw(View.java:16187)
at android.view.View.updateDisplayListIfDirty(View.java:15180)
at android.view.View.draw(View.java:15954)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.updateDisplayListIfDirty(View.java:15175)
at android.view.View.draw(View.java:15954)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.updateDisplayListIfDirty(View.java:15175)
at android.view.View.draw(View.java:15954)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.draw(View.java:16187)
at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2690)
at android.view.View.updateDisplayListIfDirty(View.java:15180)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2623)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2442)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2075)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1115)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6023)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

最佳答案

如您所见ExpandableListView的源代码您的代码崩溃于:

@Override
    void drawDivider(Canvas canvas, Rect bounds, int childIndex) {
        int flatListPosition = childIndex + mFirstPosition;

        // Only proceed as possible child if the divider isn't above all items (if it is above
        // all items, then the item below it has to be a group)
        if (flatListPosition >= 0) {
            final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
            PositionMetadata pos = mConnector.getUnflattenedPos(adjustedPosition);
            // If this item is a child, or it is a non-empty group that is expanded
            if ((pos.position.type == ExpandableListPosition.CHILD) || (pos.isExpanded() &&
                    pos.groupMetadata.lastChildFlPos != pos.groupMetadata.flPos)) {
                // These are the cases where we draw the child divider
                final Drawable divider = mChildDivider;
                divider.setBounds(bounds);
                divider.draw(canvas);
                pos.recycle();
                return;
            }
            pos.recycle();
        }

        // Otherwise draw the default divider
        super.drawDivider(canvas, bounds, flatListPosition);
    }

您的代码已崩溃,因为 divider 为 null,或 mChildDivider 为 null,

mChildDivder 以两种方式接受值:

1- 从 xml 通过 :

a.getDrawable(com.android.internal.R.styleable.ExpandableListView_childDivider);

所以你可以设置:

android:childDivider="..."

2- 通过代码:

public void setChildDivider(Drawable childDivider) {
        mChildDivider = childDivider;
    }

您必须使用其中之一来设置 mChildDivider

关于可扩展 ListView 中的 android:divider 属性使我在 Android 6.01 中的应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37885945/

相关文章:

java - 需要有关我的 fragment 的帮助

android - 无法替换 ViewPager 内的 fragment

android - 保留两个 fragment 之间的定时器状态

android - 关于 fragment 生命周期,何时调用 fragment 的 onActivityResult?

android - 如何在 ImageView 中缩放图像,使其显示为 "fits"

android - 试图让 BarChart 与 Firebase 一起工作

android - 使用 ActionBarSherlock 实现滑动抽屉导航

android - Android中的内存分析器工具?

java - PreferenceFragmentCompat 不显示

android - 如何从我的 jar 或 aar 文件中隐藏类?