在 Android 開發中,有時需要遍歷佈局容器(如 LinearLayout、RelativeLayout 等)以獲取所有的 Button 實例,並對其進行統一操作(例如根據按鈕高度重新設置背景)。但佈局中可能混雜著 TextView、ImageView 等其他類型的視圖,如何只篩選出 Button 呢?
最直接的方法是遞歸遍歷 ViewGroup 的子視圖,並使用 instanceof 判斷類型:
public void collectButtons(ViewGroup parent, List<Button> buttons) {
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
if (child instanceof Button) {
buttons.add((Button) child);
} else if (child instanceof ViewGroup) {
collectButtons((ViewGroup) child, buttons); // 遞歸處理嵌套佈局
}
}
}
調用示例:
List<Button> allButtons = new ArrayList<>();
collectButtons(rootLayout, allButtons);
for (Button btn : allButtons) {
btn.setHeight(targetHeight);
}
若需在設置背景時統一邏輯,可創建自定義 Button 並重寫 setBackgroundDrawable 方法,如下所示:
public class CustomButton extends Button {
@Override
public void setBackgroundDrawable(Drawable background) {
// 組合多層 Drawable 實現複雜背景效果
Drawable[] layers = new Drawable[5];
Resources res = getResources();
layers[0] = res.getDrawable(R.drawable.outer_rectangle);
layers[1] = res.getDrawable(R.drawable.inner_rectangle);
layers[2] = res.getDrawable(R.drawable.upper_oval);
layers[3] = res.getDrawable(R.drawable.gradient_fill);
layers[4] = res.getDrawable(R.drawable.lower_oval);
LayerDrawable layerDrawable = new LayerDrawable(layers);
layerDrawable.setLayerInset(0, 0, 0, 0, 0);
layerDrawable.setLayerInset(1, 3, 3, 3, 0);
layerDrawable.setLayerInset(2, 3, 15, 3, 25);
layerDrawable.setLayerInset(3, 3, 23, 3, 0);
layerDrawable.setLayerInset(4, 4, 60, 4, -5);
super.setBackgroundDrawable(layerDrawable);
}
}
在 XML 佈局中使用 <com.example.CustomButton ... /> 即可自動應用該背景邏輯。
通過遞歸遍歷並配合 instanceof 篩選,可靈活獲取嵌套佈局中的所有 Button。若需統一行為,繼承 Button 並重寫相關方法是更優雅的做法。