通过单击选项卡(而不是滑动)在滑动选项卡之间切换时应用程序崩溃
App crashes when switching between Sliding Tabs by clicking the tabs (not swiping)
所以我正在使用 PagerSlidingTabStrip。我按照教程中的建议实现了它,并遵循了 sample/demo-app 代码。
我有 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.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
public class 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;
}
}
}
什么可能导致此错误?仅当我尝试通过单击选项卡(而不是滑动)AND 从计算器片段切换到历史片段时,当用户已经将某些内容保存到数据库时(recordsList.size() != 0
).如果 recordsList
为空,则没有错误。
此外,HistoryFragment.java:68 是下面这行
ListView listView = (ListView) rootView.findViewById(R.id.records_list);
我能够自己解决这个问题 :) 所以发生的事情是 setUserVisibleHint
方法正在调用 loadScreen
因为屏幕对用户可见。问题是历史片段的 onCreateView 一开始就没有被调用过!所以我所要做的就是在我的 loadScreen
方法中检查 rootView!=null
。呸!这解决了所有问题。
这是我之前的
if (recordsList.size() != 0) {
以及我现在拥有的
if (recordsList.size() != 0 && rootView!=null) {
在你崩溃的片段中设置:
if (activity != null && isAdded) {
// perform your task
}
所以我正在使用 PagerSlidingTabStrip。我按照教程中的建议实现了它,并遵循了 sample/demo-app 代码。
我有 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.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
public class 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;
}
}
}
什么可能导致此错误?仅当我尝试通过单击选项卡(而不是滑动)AND 从计算器片段切换到历史片段时,当用户已经将某些内容保存到数据库时(recordsList.size() != 0
).如果 recordsList
为空,则没有错误。
此外,HistoryFragment.java:68 是下面这行
ListView listView = (ListView) rootView.findViewById(R.id.records_list);
我能够自己解决这个问题 :) 所以发生的事情是 setUserVisibleHint
方法正在调用 loadScreen
因为屏幕对用户可见。问题是历史片段的 onCreateView 一开始就没有被调用过!所以我所要做的就是在我的 loadScreen
方法中检查 rootView!=null
。呸!这解决了所有问题。
这是我之前的
if (recordsList.size() != 0) {
以及我现在拥有的
if (recordsList.size() != 0 && rootView!=null) {
在你崩溃的片段中设置:
if (activity != null && isAdded) {
// perform your task
}