Android 尝试在 Fragment 中的 ImageButton 上设置点击侦听器时应用程序崩溃
Android app crashes when trying to set a click listener on ImageButton in Fragment
尝试在片段中的 ImageButton 上设置 onClickListener (SessionsFragment.java),但我不断收到空指针异常。尝试了所有不同的解决方案,但仍然出现相同的错误。该按钮位于 ExpandableListView 中的一个项目中,因此我添加了 list_item.xml。看到一些评论说它是空的,因为它不在主要 activity 或类似的地方。无论如何,我该如何克服这个问题?
SessionsFragment.java
public class SessionsFragment extends Fragment {
ExpandableListAdapter expandableListAdapter;
ExpandableListView expandableListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
ImageButton addButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sessions, container, false);
// Get the ListView
expandableListView = view.findViewById(R.id.sessionsExpandableListView);
// Prepare the list data
prepareListData();
expandableListAdapter = new ExpandableListAdapter(getContext(), listDataHeader, listDataChild);
// Set the list adapter and expand lists by default
expandableListView.setAdapter(expandableListAdapter);
expandableListView.expandGroup(0);
// Get button values
addButton = view.findViewById(R.id.addButton);
addButton.setOnClickListener(new ImageButton.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Session added", Toast.LENGTH_SHORT).show();
}
});
return view;
}
list_item.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="55dp">
<TextView
android:id="@+id/listItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
<!--android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"/>-->
<ImageButton
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_add_black_24dp"
android:layout_alignParentRight="true" />
Logcat
04-25 15:12:04.053 11894-11901/? E/zygote64: Failed sending reply to
debugger: Broken pipe
04-25 15:12:04.578 11894-11894/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.engineeringweek, PID: 11894
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.android.engineeringweek/com.example.android.engineeringweek.SessionsActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)'
on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)'
on a null object reference
at com.example.android.engineeringweek.SessionsFragment.onCreateView(SessionsFragment.java:47)
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.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:560)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1412)
at android.app.Activity.performStart(Activity.java:7015)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2909)
编辑
ExpandableListAdapter.java
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader;
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listDataChild) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listDataChild;
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if(convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group, null);
}
TextView listHeader = convertView.findViewById(R.id.listHeader);
listHeader.setTypeface(null, Typeface.BOLD);
listHeader.setText(headerTitle);
return convertView;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition)).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if(convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item, null);
}
TextView textListChild = convertView.findViewById(R.id.listItem);
textListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
}
@Override
public boolean isChildSelectable(int i, int i1) {
return true;
}
@Override
public boolean hasStableIds() {
return false;
}
}
您的findViewById 似乎找不到id addButton。
在查看你的代码后,我发现你正在膨胀 R.layout.fragment_sessions 作为你的观点,但搜索包含在你的列表项中的 id。
如果您想将 clicklistener 添加到列表项,您需要在 class viewholder creating/binding 时在适配器中执行此操作。
尝试在片段中的 ImageButton 上设置 onClickListener (SessionsFragment.java),但我不断收到空指针异常。尝试了所有不同的解决方案,但仍然出现相同的错误。该按钮位于 ExpandableListView 中的一个项目中,因此我添加了 list_item.xml。看到一些评论说它是空的,因为它不在主要 activity 或类似的地方。无论如何,我该如何克服这个问题?
SessionsFragment.java
public class SessionsFragment extends Fragment {
ExpandableListAdapter expandableListAdapter;
ExpandableListView expandableListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
ImageButton addButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sessions, container, false);
// Get the ListView
expandableListView = view.findViewById(R.id.sessionsExpandableListView);
// Prepare the list data
prepareListData();
expandableListAdapter = new ExpandableListAdapter(getContext(), listDataHeader, listDataChild);
// Set the list adapter and expand lists by default
expandableListView.setAdapter(expandableListAdapter);
expandableListView.expandGroup(0);
// Get button values
addButton = view.findViewById(R.id.addButton);
addButton.setOnClickListener(new ImageButton.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Session added", Toast.LENGTH_SHORT).show();
}
});
return view;
}
list_item.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="55dp">
<TextView
android:id="@+id/listItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
<!--android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"/>-->
<ImageButton
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_add_black_24dp"
android:layout_alignParentRight="true" />
Logcat
04-25 15:12:04.053 11894-11901/? E/zygote64: Failed sending reply to debugger: Broken pipe 04-25 15:12:04.578 11894-11894/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.engineeringweek, PID: 11894 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.engineeringweek/com.example.android.engineeringweek.SessionsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6809) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at com.example.android.engineeringweek.SessionsFragment.onCreateView(SessionsFragment.java:47) 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.execPendingActions(FragmentManager.java:2229) at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221) at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171) at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192) at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:560) at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1412) at android.app.Activity.performStart(Activity.java:7015) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2909)
编辑
ExpandableListAdapter.java
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader;
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listDataChild) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listDataChild;
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if(convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_group, null);
}
TextView listHeader = convertView.findViewById(R.id.listHeader);
listHeader.setTypeface(null, Typeface.BOLD);
listHeader.setText(headerTitle);
return convertView;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition)).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if(convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item, null);
}
TextView textListChild = convertView.findViewById(R.id.listItem);
textListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
}
@Override
public boolean isChildSelectable(int i, int i1) {
return true;
}
@Override
public boolean hasStableIds() {
return false;
}
}
您的findViewById 似乎找不到id addButton。 在查看你的代码后,我发现你正在膨胀 R.layout.fragment_sessions 作为你的观点,但搜索包含在你的列表项中的 id。
如果您想将 clicklistener 添加到列表项,您需要在 class viewholder creating/binding 时在适配器中执行此操作。