Android AlertDialog标题及列表项文本居中对齐实现问题求助
Hey there! I get that you want to center the title and list items of an AlertDialog using the built-in views instead of custom layouts—let's break down solutions for each issue you're facing.
Centering the AlertDialog Title
The reason android.R.id.title returns null is that the internal structure of AlertDialog varies across Android versions, and that ID isn't always used for the title TextView. Here are two reliable approaches:
Approach 1: Using Reflection (Most Direct)
We can access the private mTitleView field of AlertDialog directly to set the gravity:
AlertDialog dialog = builder.show(); // Center the title try { Field titleField = AlertDialog.class.getDeclaredField("mTitleView"); titleField.setAccessible(true); TextView titleView = (TextView) titleField.get(dialog); if (titleView != null) { titleView.setGravity(Gravity.CENTER); } } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); // Fallback to traversing the view tree if reflection fails ViewGroup decorView = (ViewGroup) dialog.getWindow().getDecorView(); traverseForTitleAndCenter(decorView, dialog.getTitle().toString()); } // Helper method to find title TextView by text content private void traverseForTitleAndCenter(ViewGroup parent, String titleText) { for (int i = 0; i < parent.getChildCount(); i++) { View child = parent.getChildAt(i); if (child instanceof TextView) { TextView textView = (TextView) child; if (titleText.equals(textView.getText().toString())) { textView.setGravity(Gravity.CENTER); break; } } else if (child instanceof ViewGroup) { traverseForTitleAndCenter((ViewGroup) child, titleText); } } }
Approach 2: Traverse the View Tree
If reflection makes you uneasy, you can recursively search the dialog's decor view for the title TextView (identified by its text content). The helper method above handles this as a fallback.
Centering List Items in AlertDialog
Your initial code didn't work because when you immediately call getListView() after show(), the ListView hasn't finished laying out its items yet. Here are two fixes:
Approach 1: Use post() to Wait for Layout
Wait until the ListView is fully rendered before modifying its items:
builder.setItems(new String[]{"First Item", "Second Item", "Third Item"}, null); AlertDialog dialog = builder.show(); dialog.setOnShowListener(dialogInterface -> { ListView listView = dialog.getListView(); if (listView != null) { listView.post(() -> { for (int i = 0; i < listView.getCount(); i++) { View item = listView.getChildAt(i); if (item instanceof TextView) { ((TextView) item).setGravity(Gravity.CENTER); } else { // Most default list items use android.R.id.text1 for the text view TextView textView = item.findViewById(android.R.id.text1); if (textView != null) { textView.setGravity(Gravity.CENTER); } } } }); } });
Approach 2: Wrap the Original Adapter
A more robust way is to wrap the dialog's default adapter and modify the item views in getView():
AlertDialog dialog = builder.show(); ListView listView = dialog.getListView(); if (listView != null) { Adapter originalAdapter = listView.getAdapter(); listView.setAdapter(new CenteringAdapterWrapper(originalAdapter)); } // Wrapper adapter to center list item text private static class CenteringAdapterWrapper extends BaseAdapter { private final Adapter mOriginalAdapter; public CenteringAdapterWrapper(Adapter originalAdapter) { mOriginalAdapter = originalAdapter; } @Override public int getCount() { return mOriginalAdapter.getCount(); } @Override public Object getItem(int position) { return mOriginalAdapter.getItem(position); } @Override public long getItemId(int position) { return mOriginalAdapter.getItemId(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { View itemView = mOriginalAdapter.getView(position, convertView, parent); // Center the text view if (itemView instanceof TextView) { ((TextView) itemView).setGravity(Gravity.CENTER); } else { TextView textView = itemView.findViewById(android.R.id.text1); if (textView != null) { textView.setGravity(Gravity.CENTER); } } return itemView; } }
This approach ensures that even if new items are added (or recycled in the ListView), their text stays centered.
All these methods work with the built-in AlertDialog views, so you don't need to create custom layouts.
内容的提问来源于stack exchange,提问作者Sujay U N

