通过单击选项卡(不刷卡)在滑动选项卡之间切换时应用程序崩溃

时间:2015-01-14 15:58:00

标签: android android-fragments nullpointerexception pagerslidingtabstrip

所以我正在使用PagerSlidingTabStrip。我实现它就像在教程中建议的那样,并遵循示例/演示应用程序代码。

我有3个标签:计算器|百分比|历史

所有3扩展Fragment。我可以在这些标签之间滑动没问题。但是当我在计算器选项卡上试图点击历史记录选项卡时,我得到一个NullPointerException。这是我得到的错误:

java.lang.NullPointerException
        at sleeping_vityaz.onerm.tabsswipe.HistoryFragment.loadScreen(HistoryFragment.java:69)
        at sleeping_vityaz.onerm.tabsswipe.HistoryFragment.setUserVisibleHint(HistoryFragment.java:57)
        at android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:130)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1071)
        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:555)
        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
        at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
        at com.astuetz.PagerSlidingTabStrip$2.onClick(PagerSlidingTabStrip.java:299)
        at android.view.View.performClick(View.java:4438)
        at android.view.View$PerformClick.run(View.java:18422)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)

这是我的HistoryFragment代码:

public class HistoryFragment extends Fragment {

    public RecordArrayAdapter adapter;
    ArraySwipeAdapterSample mAdapter;
    View rootView;
    DBTools dbTools = null;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.history_layout, container, false);
        loadScreen();

        return rootView;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser) {
            loadScreen();
        } else {
            Log.d("MyFragment", "Fragment is not visible.");
        }
    }

    private void loadScreen() {
        dbTools = DBTools.getInstance(this.getActivity());
        final List<RecordObject> recordsList = dbTools.getAllRecords();

        if (recordsList.size() != 0) {
            ListView listView = (ListView) rootView.findViewById(R.id.records_list);
            mAdapter = new ArraySwipeAdapterSample<String>(getActivity(), R.layout.record_entry, R.id.key_id, recordsList);

            listView.setAdapter(mAdapter);

            mAdapter.setMode(SwipeItemMangerImpl.Mode.Single);
            SwipeLayout swipeLayout = (SwipeLayout) getActivity().findViewById(R.id.swipe);

            /*adapter = new RecordArrayAdapter(this.getActivity(), recordsList);
            listView.setAdapter(adapter);*/
        }
    }
}

history_layout.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/records_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"></ListView>

record_entry.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp">

    <com.daimajia.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swipe"
        android:layout_width="match_parent"
        android:layout_height="80dp">
        <!-- Bottom View Start-->
        <LinearLayout
            android:id="@+id/bottom_wrapper"
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:background="#66ddff00"
            android:weightSum="1">

            <ImageView
                android:id="@+id/img_trash"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/accent"
                android:paddingLeft="25dp"
                android:paddingRight="25dp"
                android:src="@drawable/ic_action_delete" />

            <!--What you want to show-->
        </LinearLayout>
        <!-- Bottom View End-->

        <!-- Surface View Start -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#ffffff"
            android:padding="10dp">
            <!--What you want to show in SurfaceView-->

            <TextView
                android:id="@+id/key_id"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone" />



            <TextView
                android:id="@+id/onerm"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="2.2"
                android:gravity="center_vertical"
                android:text="WEIGHT"
                android:textColor="#444444"
                android:textSize="16sp"
                android:layout_marginLeft="4dp" />

            <TableLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="3">

                <TextView
                    android:id="@+id/weight"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="WEIGHT"
                    android:textColor="#444444"
                    android:textSize="12sp" />

                <TextView
                    android:id="@+id/reps"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="REPS"
                    android:textColor="#444444"
                    android:textSize="12sp" />

            </TableLayout>

            <TextView
                android:id="@+id/date"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|right"
                android:layout_weight="2"
                android:text="DATE"
                android:textColor="#444444"
                android:textSize="12sp"
                android:gravity="center_vertical|right" />




        </LinearLayout>
        <!-- Surface View End -->
    </com.daimajia.swipe.SwipeLayout>
</LinearLayout>

TabsAdapter.java

公共类TabsAdapter扩展了FragmentPagerAdapter {

final private int NUM_TABS = 3;

public TabsAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0: return new CalculatorFragment();
        case 1: return new PercentageFragment();
        case 2: return new HistoryFragment();
    }
    return null;
}

@Override
public int getCount() {
    return NUM_TABS;
}

@Override
public CharSequence getPageTitle (int position) {

    switch (position) {
        case 0: return "Calculator";
        case 1: return "Percentage";
        case 2: return "History";
        default:return null;
    }
}

}

可能导致此错误的原因是什么?只有当用户已经将某些内容保存到数据库(recordsList.size() != 0)时,通过单击选项卡(而不是滑动) AND ,尝试从Calculator片段切换到History片段时,才会发生这种情况。如果recordsList为空,则没有错误。

此外,HistoryFragment.java:68是以下行

ListView listView = (ListView) rootView.findViewById(R.id.records_list);

2 个答案:

答案 0 :(得分:3)

我能够自己解决这个问题:)所以发生了什么setUserVisibleHint方法正在调用loadScreen因为屏幕对用户可见。问题在于,历史片段的onCreateView从未被调用过!所以,我所要做的就是在rootView!=null方法中检查loadScreen。咄!这解决了一切。

这就是我之前的事情

if (recordsList.size() != 0) {

以及我现在拥有的东西

if (recordsList.size() != 0 && rootView!=null) {

答案 1 :(得分:1)

设置要崩溃的片段:

if (activity != null && isAdded) {
      // perform your task
}