當 EditText 獲取焦點彈出軟鍵盤時,需要 ListView 自動滾動到最後一項,且確保該項不被鍵盤遮擋。這需要協調 ListView 滾動、窗口軟鍵盤模式與佈局調整。
在 AndroidManifest.xml 對應 Activity 中聲明:
<activity
android:name=".ChatActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
</activity>
adjustResize:窗口大小調整以容納鍵盤,ListView 可滾動區域自動縮小stateHidden:啟動時隱藏鍵盤public class ChatListView extends ListView {
public ChatListView(Context context) {
super(context);
}
public ChatListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChatListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 高度變化時(如鍵盤彈出縮小)自動滾動到底部
if (h < oldh && getAdapter() != null) {
setSelection(getAdapter().getCount() - 1);
}
}
}
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.ChatListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/input_layout"
android:transcriptMode="alwaysScroll"
android:stackFromBottom="true" />
<LinearLayout
android:id="@+id/input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<EditText
android:id="@+id/message_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發送" />
</LinearLayout>
</RelativeLayout>
EditText input = findViewById(R.id.message_input);
input.setOnFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
// 延遲執行確保佈局已調整
listView.post(() -> {
listView.setSelection(listView.getAdapter().getCount() - 1);
});
}
});
// 或使用 OnClickListener
input.setOnClickListener(v -> {
listView.post(() -> listView.setSelection(listView.getCount() - 1));
});
transcriptMode="alwaysScroll":新項添加時自動滾動到底部stackFromBottom="true":項目從底部向上堆疊(聊天列表常用)adjustResize:讓佈局在鍵盤彈出時重新計算高度,觸發 onSizeChanged新專案強烈建議使用 RecyclerView + LinearLayoutManager:
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true); // 等同 stackFromBottom
recyclerView.setLayoutManager(layoutManager);
// 滾動到底部
layoutManager.scrollToPositionWithOffset(adapter.getItemCount() - 1, 0);
配合 adjustResize 效果更佳,且性能優於 ListView。