我创建了一个Fragment,其中包含一个包含从SQLite数据库加载的信息的项目列表。我使用CursurAdapter加载数据。这是Fragment和扩展CursorAdapter的内部AlarmAdapter类。
public class AlarmListFragment extends Fragment {
private DBHelper dbHelper;
private Context context;
private Cursor mCursor;
private AlarmListAdapter alarmItemAdapter;
private final String QUERY = String.format("SELECT * FROM %s", DBHelper.TABLE_ALARM_LIST);
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getActivity().getApplicationContext();
dbHelper = new DBHelper(context);
SQLiteDatabase db = dbHelper.getReadableDatabase();
mCursor = db.rawQuery(QUERY, null);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
/*
* Instead of doing inflater.inflate(R.layout.fragment_alarm_list, null);
* inflater.inflate(R.layout.fragment_alarm_list, container, false) will occur with the given container, but won't attach it to the parent.
*/
View view = inflater.inflate(R.layout.fragment_alarm_list, container, false);
final ListView lvAlarmsList = (ListView) view.findViewById(R.id.lvAlarmsList);
alarmItemAdapter = new AlarmListAdapter(context, mCursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
lvAlarmsList.setAdapter(alarmItemAdapter);
loadAlarms();
Button btnAddNewAlarm = (Button) view.findViewById(R.id.btnAddNewAlarm);
btnAddNewAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlarmPreferencesFragment fragment = new AlarmPreferencesFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
transaction.replace(R.id.main_frame, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
return view;
}
private void loadAlarms() {
int alarmsCount = dbHelper.getAllAlarms().size();
if(alarmsCount != 0) {
for (int i = 1; i <= alarmsCount; i++) {
Alarm alarm = dbHelper.getAlarm(i);
alarmItemAdapter.addItem(alarm);
}
}
alarmItemAdapter.notifyDataSetChanged();
}
class AlarmListAdapter extends CursorAdapter {
private ArrayList<Alarm> itemsList = new ArrayList<>();
AlarmListAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
}
@Override
public int getCount() {
return itemsList.size();
}
@Override
public Object getItem(int i) {
return itemsList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.listitem_alarm, parent, false);
}
@Override
protected void onContentChanged() {
super.onContentChanged();
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final long id = cursor.getLong(0);
final int position = cursor.getPosition();
final Alarm alarm = dbHelper.getAlarm(id);
CardView cvAlarmItem = (CardView) view.findViewById(R.id.cvAlarmItem);
cvAlarmItem.setBackgroundColor(ContextCompat.getColor(context, R.color.super_light_grey));
cvAlarmItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// If you click the CardView item, it will lead to the alarm preference fragment with the corresponding alarm's info.
Bundle bundle = new Bundle();
bundle.putSerializable("alarm", alarm);
Toast.makeText(getContext(), ""+id, Toast.LENGTH_SHORT).show();
AlarmPreferencesFragment fragment = new AlarmPreferencesFragment();
fragment.setArguments(bundle);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_frame, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
TextView tvSetAlarmType = (TextView) view.findViewById(R.id.tvSetAlarmType);
int alarmType = alarm.getRingTypeOptionNum();
String strAlarmType = "";
switch(alarmType) {
case SoundVibrate.SOUND:
strAlarmType = getString(R.string.sound);
break;
case SoundVibrate.SOUND_AND_VIBRATE:
strAlarmType = getString(R.string.sound_and_vibrate);
break;
case SoundVibrate.VIBRATE:
strAlarmType = getString(R.string.vibrate);
break;
}
tvSetAlarmType.setTextColor(ContextCompat.getColor(context, R.color.dark_grey));
tvSetAlarmType.setText(strAlarmType);
TextView tvSetAlarmRepeat = (TextView) view.findViewById(R.id.tvSetAlarmRepeat);
tvSetAlarmRepeat.setTextColor(ContextCompat.getColor(context, R.color.dark_grey));
Alarm.Day[] repeatDays = alarm.getRepeatDays();
String guide = "";
int size = repeatDays.length;
if(size > 1) {
int i = 0;
while(i<size-1) {
guide += repeatDays[i].toString() + ", ";
++i;
}
guide += "and " + repeatDays[size-1];
} else if(size == 1){
guide = repeatDays[0].toString();
} else {
guide = getString(R.string.never);
}
tvSetAlarmRepeat.setText(guide);
TextView tvSetAlarmTime = (TextView) view.findViewById(R.id.tvSetAlarmTime);
String strAlarmTime = alarm.getAlarmTimeString();
tvSetAlarmTime.setTextColor(ContextCompat.getColor(context, R.color.dark_grey));
tvSetAlarmTime.setText(strAlarmTime);
Switch switchAlarmOnOff = (Switch) view.findViewById(R.id.switchAlarmOnOff);
boolean active = alarm.isAlarmActive();
switchAlarmOnOff.setChecked(active);
switchAlarmOnOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});
ImageView ivDelete = (ImageView) view.findViewById(R.id.ivDelete);
ivDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Cursor c = alarmItemAdapter.getCursor();
c.moveToPosition(position);
dbHelper.deleteAlarm(alarm);
loadAlarms();
}
});
}
void addItem(Alarm item) {
itemsList.add(item);
}
}
}
这是截图。
如果我点击“X&#39;在该项目上,该项目将从数据库和列表中删除。但现在,如果点击“X&#39;”,应用程序将退出并显示此错误消息。
01-20 12:50:13.969 20112-20112/com.marshall.alarm E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.marshall.alarm, PID: 20112
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
at com.marshall.alarm.ui.AlarmListFragment$AlarmListAdapter.bindView(AlarmListFragment.java:200)
at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:273)
at android.widget.AbsListView.obtainView(AbsListView.java:2402)
at android.widget.ListView.makeAndAddView(ListView.java:1891)
at android.widget.ListView.fillSpecific(ListView.java:1364)
at android.widget.ListView.layoutChildren(ListView.java:1676)
at android.widget.AbsListView.onLayout(AbsListView.java:2206)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1795)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:16075)
at android.view.ViewGroup.layout(ViewGroup.java:5300)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16075)
我认为这个问题与Cursor
有关,但我不知道如何开始。
答案 0 :(得分:0)
检查以上行的条件:
if(alarm!=null && alarm.isAlarmActive()!=null && alarm.isAlarmActive()){
boolean active = alarm.isAlarmActive();
switchAlarmOnOff.setChecked(active);
}
我希望此代码对您有所帮助。