首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

ScrollView 嵌套 ListView 僅顯示一項的兩種完美解決方案

     編輯:Java 相關知識

問題根因

ScrollView 與 ListView 都擁有垂直滾動機制,觸摸事件分發衝突導致 ListView 無法正確測量高度,默認僅顯示一項。

方案一:動態測量設置高度(適用於靜態數據)

遍歷適配器所有項目,累加測量高度,設置給 ListView:

public void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter adapter = listView.getAdapter();
    if (adapter == null) return;

    int totalHeight = 0;
    for (int i = 0; i < adapter.getCount(); i++) {
        View item = adapter.getView(i, null, listView);
        item.measure(0, 0); // 測量寬高
        totalHeight += item.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
    params.height += 5; // 微調邊距
    listView.setLayoutParams(params);
    listView.requestLayout();
}

調用時機: adapter.notifyDataSetChanged() 後或數據加載完成後。缺點: 數據變動需重新調用,項目過多時測量耗時。

方案二:自定義 ListView 重寫 onMeasure(推薦,完美支持動態數據)

核心思路:將測量模式改為 AT_MOST 並給足夠大的尺寸限制,讓 ListView 完全展開。

public class ScrollViewListView extends ListView {
    public ScrollViewListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Integer.MAX_VALUE >> 2 即 536870911,足夠大
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

使用: 在布局 XML 中直接替換 <ListView> 為 <com.yourpkg.ScrollViewListView>,無需額外 Java 代碼。

對比總結

維度動態測量法自定義 View 法
代碼侵入性需在邏輯層調用僅替換 XML 標籤
動態數據支持需手動刷新自動適應
性能大數據量測量慢系統優化測量流程
推薦場景簡單靜態列表通用、生產環境首選

最佳實踐建議

  • 優先使用 方案二,一次封裝處處復用。
  • 若列表項目極多(>100),考慮改用 RecyclerView + NestedScrollView 並設置 setNestedScrollingEnabled(false)。
  • 避免在 ScrollView 中嵌套多個滾動視圖,嚴重影響流暢度。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved