模仿今日頭條頂部可滑動新聞導航欄,使用 HorizontalScrollView 容器動態添加多個 Button,需在代碼中遍歷獲取每個 Button 的 ID 以綁定點擊事件或標識當前選中項。
getChildAt() + getId()HorizontalScrollView hsv = findViewById(R.id.hsv_nav);
LinearLayout container = (LinearLayout) hsv.getChildAt(0); // HSV 僅允許一個直接子佈局
for (int i = 0; i < container.getChildCount(); i++) {
View child = container.getChildAt(i);
if (child instanceof Button) {
int btnId = child.getId(); // 獲取 ID
// 業務邏輯:綁定點擊、標記選中等
child.setOnClickListener(v -> {
// 使用 v.getId() 區分按鈕
});
}
}
LinearLayout(horizontal),真正的按鈕在該 LinearLayout 內。View.NO_ID (-1),需手動分配:btn.setId(View.generateViewId())(API 17+)或自定義正整數 ID。findViewById() 遍歷,因動態 ID 不在編譯期 R 類中,只能通過容器遍歷獲取。HorizontalScrollView hsv = new HorizontalScrollView(this);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
String[] titles = {"推薦", "熱點", "北京", "視頻", "娛樂", "科技"};
for (int i = 0; i < titles.length; i++) {
Button btn = new Button(this);
btn.setId(View.generateViewId()); // 分配唯一 ID
btn.setText(titles[i]);
btn.setTag(i); // 攜帶索引,比 ID 更語義化
btn.setOnClickListener(this::onNavClick);
ll.addView(btn);
}
hsv.addView(ll);
setContentView(hsv);
// 點擊處理
public void onNavClick(View v) {
int index = (int) v.getTag();
// 更新選中狀態、加載對應 Fragment 等
}
TabLayout + ViewPager2 替代手寫 HSV,官方組件已內置滑動、指示器、無限循環等功能。PagerSnapHelper 實現吸附效果。掌握「容器遍歷 + 動態 ID 分配 + Tag 攜帶數據」三板斧,輕鬆駕馭動態導航欄開發。