首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android Fragment 中訪問父 Activity UI 元素的正確方式:onAttach 獲取 Activity 引用

     編輯:程式設計綜合問答

錯誤代碼


// Fragment onCreateView 中
ProgressBar progressBar = view.findViewById(R.id.ctrlActivityIndicator); // 找不到,ID 在 Activity 佈局中
progressBar.setVisibility(View.INVISIBLE); // NPE

Fragment 的 view 只包含 Fragment 自身佈局(R.layout.fragment_scan),父 Activity 的 ProgressBar (id: ctrlActivityIndicator) 不在其中。

正確方式:onAttach 獲取 Activity 實例


public class ScanFragment extends Fragment {
    private MainActivity mainActivity; // 或基類 Activity

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof MainActivity) {
            mainActivity = (MainActivity) context;
        } else {
            throw new IllegalStateException("Fragment 必須附掛在 MainActivity 中");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_scan, container, false);
        // 通過 Activity 實例查找父佈局中的 View
        ProgressBar progressBar = mainActivity.findViewById(R.id.ctrlActivityIndicator);
        if (progressBar != null) {
            progressBar.setVisibility(View.INVISIBLE);
        }
        return view;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mainActivity = null; // 防洩漏
    }
}

進階:定義接口回調(解耦 Fragment 與具體 Activity)


// 接口
public interface OnProgressListener {
    void hideProgress();
    void showProgress();
}

// Fragment
public class ScanFragment extends Fragment {
    private OnProgressListener progressListener;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnProgressListener) {
            progressListener = (OnProgressListener) context;
        } else {
            throw new IllegalStateException("Activity 必須實現 OnProgressListener");
        }
    }

    // 使用
    progressListener.hideProgress();
}

// Activity 實現
public class MainActivity extends AppCompatActivity implements OnProgressListener {
    @Override
    public void hideProgress() {
        findViewById(R.id.ctrlActivityIndicator).setVisibility(View.INVISIBLE);
    }
    @Override
    public void showProgress() {
        findViewById(R.id.ctrlActivityIndicator).setVisibility(View.VISIBLE);
    }
}

關鍵原則

  • Fragment 不能直接 findViewById 父 Activity 佈局中的 View。
  • 在 onAttach 獲取 Activity 引用(或接口),onDetach 清空。
  • 優先定義接口,降低耦合,便於 Fragment 復用、測試。
  • 避免在 onCreateView 以外生命周期持有 View 引用,防洩漏。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved