Android中OnCreateView触发IndexOutOfBoundsException问题求助
Hey there! Let's break down why you're running into that IndexOutOfBoundsException when tapping contact list items, and fix it step by step.
问题根源
The crash happens because of a mismatched data source:
- In your Firebase
onDataChangecallback, you create a localarrayListto store fetched usernames and bind it to your ListView adapter. - But your item click listener tries to access the global
alArrayList, which is never populated with any data (it stays empty, size = 0). When you click the first item (position 0), it tries to get an element from an empty list—hence the error.
修复方案
We need to make sure both the adapter and the click listener use the same data set. Here's how to adjust your code:
统一数据源
Keep your globalalArrayList, and use it directly in the Firebase callback instead of creating a new local list. This way, the adapter and click listener share the same data.完善加载状态与空数据处理
Don't forget to dismiss the progress dialog after loading, and handle the case where there are no users to show.避免空指针风险
Add a check to make sure theNamefield from Firebase isn't null before adding it to the list.
修改后的完整代码片段
// 保留全局变量 ListView usersList; TextView noUsersText; ArrayList<String> al = new ArrayList<>(); int totalUsers = 0; ProgressDialog mProgressDialogue; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View rootView = inflater.inflate(R.layout.fragment_contacts, container, false); usersList = rootView.findViewById(R.id.usersList); noUsersText = rootView.findViewById(R.id.noUsersText); mProgressDialogue = new ProgressDialog(getActivity()); mProgressDialogue.setMessage("Loading..."); mProgressDialogue.show(); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference usersRef = rootRef.child("Users"); ValueEventListener eventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { mProgressDialogue.dismiss(); // 关闭加载弹窗 al.clear(); // 清空旧数据,防止重复加载 for(DataSnapshot ds : dataSnapshot.getChildren()) { // 安全获取Name字段,避免空指针 String name = ds.child("Name").getValue(String.class); if(name != null) { al.add(name); } } // 绑定数据到Adapter ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, al); usersList.setAdapter(adapter); // 处理无用户的情况 if(al.isEmpty()) { noUsersText.setVisibility(View.VISIBLE); usersList.setVisibility(View.GONE); } else { noUsersText.setVisibility(View.GONE); usersList.setVisibility(View.VISIBLE); } } @Override public void onCancelled(DatabaseError databaseError) { mProgressDialogue.dismiss(); // 加载失败也关闭弹窗 Toast.makeText(getActivity(),"Please Check Your Internet Connection",Toast.LENGTH_SHORT).show(); } }; usersRef.addListenerForSingleValueEvent(eventListener); usersList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 现在al已经有数据,直接获取对应位置的用户名 UserDetails.chatWith = al.get(position); Intent intent = new Intent(getActivity(), Chat.class); startActivity(intent); } }); return rootView; } // UserDetails类不变 public class UserDetails { static String phonenumber = ""; static String chatWith = ""; }
额外建议
- If you plan to update the user list dynamically later, consider using a
RecyclerViewinstead ofListViewfor better performance and flexibility. - Storing only the username in the list might be limiting later—you might want to store full user objects (with UIDs, phone numbers, etc.) so you can reference more data when navigating to the chat screen.
内容的提问来源于stack exchange,提问作者user9027554

