登錄頁用 Fragment,未登錄顯示登錄表單,登錄成功後更新同一 Fragment 顯示用戶信息,**不想用 FragmentTransaction replace 替換**。
<FrameLayout xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 登錄表單 -->
<LinearLayout
android:id="@+id/llLoginForm"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible">
<EditText android:id="@+id/etPhone" ... />
<EditText android:id="@+id/etPwd" ... />
<Button android:id="@+id/btnLogin" ... />
</LinearLayout>
<!-- 登錄後信息 -->
<LinearLayout
android:id="@+id/llUserInfo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone">
<TextView android:id="@+id/tvWelcome" ... />
<Button android:id="@+id/btnLogout" ... />
</LinearLayout>
</FrameLayout>
public class LoginFragment extends Fragment {
private View llLoginForm, llUserInfo;
private TextView tvWelcome;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_login, container, false);
llLoginForm = root.findViewById(R.id.llLoginForm);
llUserInfo = root.findViewById(R.id.llUserInfo);
tvWelcome = root.findViewById(R.id.tvWelcome);
root.findViewById(R.id.btnLogin).setOnClickListener(v -> attemptLogin());
root.findViewById(R.id.btnLogout).setOnClickListener(v -> showLoginForm());
return root;
}
private void attemptLogin() {
String phone = ((EditText)getView().findViewById(R.id.etPhone)).getText().toString();
String pwd = ((EditText)getView().findViewById(R.id.etPwd)).getText().toString();
// 調用登錄 API...
// 成功回調:
showUserInfo("歡迎, " + phone);
}
private void showUserInfo(String msg) {
llLoginForm.setVisibility(View.GONE);
llUserInfo.setVisibility(View.VISIBLE);
tvWelcome.setText(msg);
}
private void showLoginForm() {
llUserInfo.setVisibility(View.GONE);
llLoginForm.setVisibility(View.VISIBLE);
}
}
| 方案 | 優點 | 缺點 | 適用 |
|---|---|---|---|
| 同 Fragment 切換 View 可見性 | 簡單、高效、狀態保持 | 布局稍顯臃腫 | 登錄/註冊、簡單狀態切換 |
| FragmentTransaction replace | 結構清晰、符合單一職責 | 需管理回棧、生命週期、動畫 | 複雜業務流程、明確分離關注點 |
| ViewPager + FragmentStatePagerAdapter | 滑動切換、預加載 | 過度設計 | 向導/引導頁 |
// ViewBinding (buildFeatures { viewBinding true })
private FragmentLoginBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
binding.btnLogin.setOnClickListener(v -> attemptLogin());
return binding.getRoot();
}
private void showUserInfo(String msg) {
binding.llLoginForm.visibility = View.GONE;
binding.llUserInfo.visibility = View.VISIBLE;
binding.tvWelcome.text = msg;
}
結論:**同一 Fragment 內用 View.GONE/VISIBLE 切換登錄前後態**,最輕量、最符合「不替換 Fragment」的需求。