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

Android ListView 與 TextView 整體滾動:使用 addHeaderView

     編輯:程式設計綜合問答

需求場景

畫面頂部有標題 TextView,下方是 ListView,希望上下滑動時**整體內容一起滾動**,而非 ListView 內部獨立滾動。

核心解法:ListView.addHeaderView()

將標題 View 作為 ListView 的 Header 加入,使其成為列表一部分,隨列表整體滾動。


ListView listView = findViewById(R.id.list_view);
TextView headerTitle = findViewById(R.id.header_title); // 或動態建立

// 關鍵:加入 Header (需在 setAdapter 之前)
listView.addHeaderView(headerTitle, null, false); 
// 參數:view, data(可為 null), isSelectable(false=不可點選)

// 然後設定 Adapter
listView.setAdapter(adapter);

完整範例


public class MainActivity extends AppCompatActivity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ListView listView = findViewById(R.id.list_view);
        
        // 1. 建立或找到 Header View
        TextView header = new TextView(this);
        header.setText("我的標題");
        header.setTextSize(24);
        header.setGravity(Gravity.CENTER);
        header.setPadding(0, 32, 0, 32);
        header.setBackgroundColor(Color.WHITE);
        
        // 2. 加入 Header (必須在 setAdapter 前)
        listView.addHeaderView(header, null, false);
        
        // 3. 設定 Adapter
        List data = Arrays.asList("項目 1", "項目 2", "項目 3", "項目 4", "項目 5");
        ArrayAdapter adapter = new ArrayAdapter<>(this, 
            android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);
    }
}

XML 佈局 (簡單版)




進階:多個 Header / Footer


// 多個 Header
listView.addHeaderView(header1, null, false);
listView.addHeaderView(header2, null, true); // 可點選

// Footer (底部固定)
View footer = LayoutInflater.from(this).inflate(R.layout.footer_layout, listView, false);
listView.addFooterView(footer, null, false);

關鍵限制與注意事項

限制說明
必須在 setAdapter 前呼叫否則拋出 IllegalStateException
Header 不可回收不參與 View 回收機制,複雜 Header 可能影響記憶體
Header 位置計算Adapter position 0 即為第一個 Header,getItem(0) 回傳 Header data
RecyclerView 替代用 ConcatAdapter 或多 ViewType 實現同樣效果

RecyclerView 等效做法 (現代)


// Adapter 實現多 ViewType
public class MyAdapter extends RecyclerView.Adapter {
    static final int TYPE_HEADER = 0, TYPE_ITEM = 1;
    
    @Override public int getItemViewType(int position) {
        return position == 0 ? TYPE_HEADER : TYPE_ITEM;
    }
    
    @NonNull @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == TYPE_HEADER) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_layout, parent, false);
            return new HeaderViewHolder(v);
        } else {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
            return new ItemViewHolder(v);
        }
    }
    
    @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof HeaderViewHolder) {
            ((HeaderViewHolder) holder).bind(headerData);
        } else {
            ((ItemViewHolder) holder).bind(items.get(position - 1)); // 扣除 header
        }
    }
    
    @Override public int getItemCount() {
        return 1 + items.size(); // 1 header + items
    }
}

總結

  1. ListView:用 addHeaderView() 最簡單、效能好
  2. 注意時機:必須在 setAdapter() **之前**呼叫
  3. RecyclerView:用多 ViewType 實現,更靈活、支援動畫
  4. 避免 ScrollView 嵌套 ListView:滾動衝突、效能差、測量錯誤
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved