首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android EditText 聚焦時 ListView 自動滾動到底部並避免鍵盤遮擋

     編輯:程式設計綜合問答

當 EditText 獲取焦點彈出軟鍵盤時,需要 ListView 自動滾動到最後一項,且確保該項不被鍵盤遮擋。這需要協調 ListView 滾動、窗口軟鍵盤模式與佈局調整。

核心解決方案

1. 設置窗口軟鍵盤模式(關鍵)

在 AndroidManifest.xml 對應 Activity 中聲明:

<activity
    android:name=".ChatActivity"
    android:windowSoftInputMode="adjustResize|stateHidden">
</activity>
  • adjustResize:窗口大小調整以容納鍵盤,ListView 可滾動區域自動縮小
  • stateHidden:啟動時隱藏鍵盤

2. 自訂 ListView 重寫 onSizeChanged

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);
        }
    }
}

3. 佈局 XML 使用自訂 ListView

<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>

4. 代碼中輔助滾動(雙重保險)

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

新專案強烈建議使用 RecyclerView + LinearLayoutManager:

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true); // 等同 stackFromBottom
recyclerView.setLayoutManager(layoutManager);

// 滾動到底部
layoutManager.scrollToPositionWithOffset(adapter.getItemCount() - 1, 0);

配合 adjustResize 效果更佳,且性能優於 ListView。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved