場景:測驗應用 14 道題,點擊「下一題」切換頁面。若每題創建一個 Activity 會導致棧溢出、切換延遲、狀態管理困難。本文提供三種單 Activity 解決方案。
// 佈局:一個 TextView + 一個 Button
TextView questionTv = findViewById(R.id.question);
Button nextBtn = findViewById(R.id.next);
String[] questions = { "Q1...", "Q2...", ... };
int index = 0;
nextBtn.setOnClickListener(v -> {
index = (index + 1) % questions.length;
questionTv.setText(questions[index]);
});
ViewGroup container = findViewById(R.id.container);
View currentView;
nextBtn.setOnClickListener(v -> {
container.removeAllViews();
// 方案 A:inflate 新佈局
currentView = LayoutInflater.from(this).inflate(R.layout.question2, container, false);
container.addView(currentView);
// 初始化新 View 的子控件...
// 方案 B:預加載所有 View,切換可見性
// views[index].setVisibility(View.VISIBLE);
// views[preIndex].setVisibility(View.GONE);
});
nextBtn.setOnClickListener(v -> {
index = (index + 1) % layouts.length;
setContentView(layouts[index]); // 完全重建視圖
// 必須重新 findViewById、綁定監聽器
bindViews();
});
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| TextView 替換 | 零開銷、狀態保持簡單 | 佈局固定、無法支持複雜 UI 差異 | 純文本/選項題 |
| View 切換 | 佈局靈活、可預加載 | 需手動管理子 View 生命周期 | 每題 UI 差異大 |
| setContentView | 代碼隔離、佈局文件獨立 | 銷毀重建開銷大、易丟失狀態 | 原型驗證、極簡項目 |
| Fragment (推薦) | 生命周期托管、回棧支持、動畫豐富、架構標準 | 學習成本稍高 | 所有生產項目 |
// Activity
viewPager = findViewById(R.id.viewPager);
viewPager.setAdapter(new FragmentStateAdapter(this) {
@NonNull @Override public Fragment createFragment(int pos) {
return QuestionFragment.newInstance(questions[pos]);
}
@Override public int getItemCount() { return questions.length; }
});
// Fragment
public class QuestionFragment extends Fragment {
static QuestionFragment newInstance(String q) { ... }
@Nullable @Override View onCreateView(...) {
// inflate 佈局、綁定數據
}
}
棄用多 Activity 方案,擁抱單 Activity + Fragment/Flow 架構,構建流暢可維護的應用。