FragmentActivity 定義接口 OnConnectingToInternet,Fragment 需調用該接口顯示/隱藏 ProgressBar。直接強轉 Activity 導致崩潰或 NPE。
// Fragment 中
private OnConnectingToInternet onConnectingToInternet;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// 錯誤1:Activity 未實現接口 → ClassCastException
// 錯誤2:未賦值 → 後續調用 NPE
onConnectingToInternet = (OnConnectingToInternet) activity;
}
public interface OnNetworkListener {
void showProgress(boolean show);
}
public class TopRecipesFragment extends Fragment {
private OnNetworkListener networkListener;
// 標準回調設置方法
public void setNetworkListener(OnNetworkListener listener) {
this.networkListener = listener;
}
private class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
if (networkListener != null) {
networkListener.showProgress(true);
}
}
// ... doInBackground / onPostExecute 同理
}
}
public class MainScreen extends FragmentActivity implements OnNetworkListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 獲取 Fragment 實例 (從 FragmentManager 或 ViewPager)
TopRecipesFragment fragment = (TopRecipesFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_container);
if (fragment != null) {
fragment.setNetworkListener(this); // 關鍵:註冊回調
}
}
@Override
public void showProgress(boolean show) {
if (show) progressBar.setVisibility(View.VISIBLE);
else progressBar.setVisibility(View.GONE);
}
}
// SharedViewModel.kt
class SharedViewModel : ViewModel() {
val networkState = MutableLiveData<Boolean>()
}
// Activity
val model = ViewModelProvider(this).get(SharedViewModel::class.java)
model.networkState.observe(this) { show ->
progressBar.visibility = if (show) View.VISIBLE else View.GONE
}
// Fragment
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
// 需顯示時
model.networkState.postValue(true)
優點:生命周期感知、無記憶體洩漏、跨 Fragment 通訊、配置變更存活。
若接口邏輯極簡且只在 Fragment 內部用:
public class TopRecipesFragment extends Fragment implements OnNetworkListener {
@Override
public void showProgress(boolean flag) {
// 直接操作 Fragment 視圖或通過 getActivity() 找 Activity 控件
if (getActivity() instanceof MainScreen) {
((MainScreen) getActivity()).updateProgress(flag);
}
}
}
if (listener != null) 防禦性編程