我有一个带有3个标签的应用程序,其中一个具有待办事项功能。当我想添加新笔记时,一切正常。现在我想为笔记实现一个删除功能,因为我无法访问.xml文件中的按钮,我尝试使用public class Tab2 extends Fragment implements View.OnClickListener
和public void onClick(View v)
,但现在我的应用程序在启动时完全崩溃了。我做错了什么?
片段:
public class Tab2 extends Fragment implements View.OnClickListener {
ImageButton btn_ok;
EditText edit_task;
private TaskDbHelper mHelper;
public ListView mTaskListView;
private ArrayAdapter<String> mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab2, container, false);
setHasOptionsMenu(true);
mHelper = new TaskDbHelper(getActivity());
mTaskListView = view.findViewById(R.id.list_todo);
updateUI();
Button b = view.findViewById(R.id.btn_delete);
b.setOnClickListener(this);
return view;
}
public void updateUI() {
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(TaskContract.TaskEntry.TABLE, new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TITLE},
null, null, null, null, null, null);
while (cursor.moveToNext()) {
int idx = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(cursor.getString(idx));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<String>(getActivity(), R.layout.item_todo, R.id.task_title, taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
cursor.close();
db.close();
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_task:
final AlertDialog.Builder mBuilder = new AlertDialog.Builder(getActivity());
View mView = getLayoutInflater().inflate(R.layout.dialog_add_task, null);
btn_ok = mView.findViewById(R.id.btn_ok5);
edit_task = mView.findViewById(R.id.edit_task);
mBuilder.setView(mView);
final AlertDialog dialog = mBuilder.create();
dialog.show();
btn_ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String task = String.valueOf(edit_task.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(TaskContract.TaskEntry.COL_TASK_TITLE, task);
db.insertWithOnConflict(TaskContract.TaskEntry.TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
updateUI();
dialog.cancel();
}
});
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_delete:
View parent = (View) v.getParent();
TextView taskTextView = parent.findViewById(R.id.task_title);
String task = String.valueOf(taskTextView.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
db.delete(TaskContract.TaskEntry.TABLE, TaskContract.TaskEntry.COL_TASK_TITLE + " = ?", new String[]{task});
db.close();
updateUI();
break;
}
} }
logcat的:
12-06 19:35:58.710 20306-20306/com.example.rike1.final_logbuch E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rike1.final_logbuch, PID: 20306
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.rike1.final_logbuch.Tab2.onCreateView(Tab2.java:49)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2199)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:651)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1236)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
at android.view.View.measure(View.java:19917)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6139)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:714)
at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:91)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1361)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:784)
at android.view.View.measure(View.java:19917)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6139)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:19917)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6139)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1485)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:775)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:657)
at android.view.View.measure(View.java:19917)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6139)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19917)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6139)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1485)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:775)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:657)
at android.view.View.measure(View.java:19917)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6139)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:729)
at android.view.View.measure(View.java:19917)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2436)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1482)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1741)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1366)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6768)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:926)
at android.view.Choreographer.doCallbacks(Choreographer.java:735)
12-06 19:35:58.710 20306-20306/com.example.rike1.final_logbuch E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:667)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:912)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
我要访问Button的XML item_todo:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<TextView
android:id="@+id/task_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="Hello"
android:textSize="20sp" />
<Button
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="Done"
android:backgroundTint="@color/colorAccent"/>
</RelativeLayout>
tab2 XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<ListView
android:id="@+id/list_todo"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
答案 0 :(得分:1)
你正在像这样膨胀tab2.xml
View view = inflater.inflate(R.layout.tab2, container, false);
但你无法从中获取按钮
Button b = view.findViewById(R.id.btn_delete);
因为您虚张声势的观点并不包含 btn_delete 。这就是为什么你从上面的行获得Null异常的原因。
答案 1 :(得分:0)
您需要在ListView中添加项目单击侦听器并使用它。你不能只找到ListViews项目,因为它们会有多个。
mTaskListView.setOnItemClickListener(this); // And remember to implement the interface
https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html
然后,您可以将代码从方法onClick
移至onItemClick
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView taskTextView = view.findViewById(R.id.task_title);
String task = String.valueOf(taskTextView.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
// and so on...
}
并且当然你需要删除导致空指针异常的行:
Button b = view.findViewById(R.id.btn_delete);
b.setOnClickListener(this);