Android:如何从 Fragment onCreateView() 访问 Activity 的视图(使用 findViewById)?
Android: how do I access views (using findViewById) of an Activity from a Fragment onCreateView()?
我有一个非常简单的项目,其中 Activity 包含一个片段。您可能唯一不熟悉的是我使用的 VideoEnabledWebView 并不那么复杂,而且我以前用过。这只是一个自定义的 webview。
这是我的代码:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Don't forget the internet permission if you will be using the WebView to load remote content -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true" > <!-- Only works in API level 11+, and allows the HTML5 videos to play in-line -->
<activity
android:name="name.cpr.ExampleActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
ExampleActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import cpr.name.videoenabledwebview.R;
public class ExampleActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.i("rai", "activity onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
}
}
activity_example.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ExampleActivity">
<!-- View that will be hidden when video goes fullscreen -->
<RelativeLayout
android:id="@+id/nonVideoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment android:name="name.cpr.WebViewFragment"
android:id="@+id/webViewFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
WebViewFragment.java
package name.cpr;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import cpr.name.videoenabledwebview.R;
public class WebViewFragment extends Fragment {
private VideoEnabledWebView webView;
private VideoEnabledWebChromeClient webChromeClient;
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.root, container, false);
webView = (VideoEnabledWebView) rootView.findViewById(R.id.webView);
Log.i("rai", "nonVideoLayout = " + R.id.nonVideoLayout);
Log.i("rai", "videoLayout = " + R.id.videoLayout);
View nonVideoLayout = rootView.findViewById(R.id.nonVideoLayout);
if(nonVideoLayout == null){
Log.i("rai", "why is nonVideoLayout null?");
}
ViewGroup videoLayout = (ViewGroup) rootView.findViewById(R.id.videoLayout);
if(videoLayout == null){
Log.i("rai", "why is videoLayout null?");
}
webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout);
webView.setWebChromeClient(webChromeClient);
webView.loadUrl("http://m.youtube.com");
return rootView;
}
}
root.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:text="the fragment"/>
<name.cpr.VideoEnabledWebView
android:id="@+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
我只是无法访问我的 Activity 中的这两个相关布局,我总是得到 null。
我尝试过但不起作用的方法:
rootView.findViewById //rootView是来自inflate
的return
getActivity().findViewById
getView().findViewById
container.findViewById
我也在我的 onCreate 片段中尝试过这个:
context = getActivity().getApplicationContext();
webViewFragmentId = context.getResources().getIdentifier(
"root", "layout", context.getPackageName());
webViewId = context.getResources().getIdentifier("webView", "id",
context.getPackageName());
nonVideoLayoutId = context.getResources().getIdentifier("nonVideoLayout", "id", context.getPackageName());
videoLayoutId = context.getResources().getIdentifier("videoLayout","id", context.getPackageName());
rootView = inflater.inflate(webViewFragmentId, null);
webView = (VideoEnabledWebView) rootView.findViewById(webViewId);
View nonVideoLayout = getActivity().findViewById(nonVideoLayoutId);
ViewGroup videoLayout = (ViewGroup) getActivity().findViewById(videoLayoutId);
webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout);
webView.setWebChromeClient(webChromeClient);
webView.loadUrl("http://m.youtube.com");
return rootView;
您需要覆盖 onViewCreated。视图不是在 onCreate 时创建的,而是在实际创建视图后创建的。这个 post 提供了更多信息 Difference between onCreateView and onViewCreated in Fragment
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
...
}
更新2020-10-27
既然 onActivityCreated
已被弃用,documentation 声明您应该改为注册 LifecycleObserver
以了解 Activity.onCreate()
方法何时完成。
有关示例,请参阅 。
原答案
您应该覆盖 onActivityCreated
并从该方法中的 activity 访问您需要的视图,因为当 onCreateView
在片段中是 运行 时 activity 尚未设置其布局,因此您无法访问其视图。
@Override
public void onActivityCreated (Bundle savedInstanceState) {
View nonVideoLayout = getActivity().findViewById(R.id.nonVideoLayout);
ViewGroup videoLayout = (ViewGroup) getActivity().findViewById(R.id.videoLayout);
...
}
您需要覆盖 onActivityCreated(),因为 activity 在调用此方法之前不会创建视图。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View nonVideoLayout = ((MainActivity)getActivity()).findViewById(R.id.nonVideoLayout);
if(nonVideoLayout == null){
Log.e("rai", "why is nonVideoLayout null?");
}
else{
Log.e("rai", "view not null hurray");
}
View videoLayout = getActivity().findViewById(R.id.videoLayout);
if(videoLayout == null){
Log.e("rai", "why is videoLayout null?");
}else{
Log.e("rai", "view not null hurray");
}
我有一个非常简单的项目,其中 Activity 包含一个片段。您可能唯一不熟悉的是我使用的 VideoEnabledWebView 并不那么复杂,而且我以前用过。这只是一个自定义的 webview。
这是我的代码:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Don't forget the internet permission if you will be using the WebView to load remote content -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true" > <!-- Only works in API level 11+, and allows the HTML5 videos to play in-line -->
<activity
android:name="name.cpr.ExampleActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
ExampleActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import cpr.name.videoenabledwebview.R;
public class ExampleActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.i("rai", "activity onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
}
}
activity_example.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ExampleActivity">
<!-- View that will be hidden when video goes fullscreen -->
<RelativeLayout
android:id="@+id/nonVideoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment android:name="name.cpr.WebViewFragment"
android:id="@+id/webViewFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
WebViewFragment.java
package name.cpr;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import cpr.name.videoenabledwebview.R;
public class WebViewFragment extends Fragment {
private VideoEnabledWebView webView;
private VideoEnabledWebChromeClient webChromeClient;
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.root, container, false);
webView = (VideoEnabledWebView) rootView.findViewById(R.id.webView);
Log.i("rai", "nonVideoLayout = " + R.id.nonVideoLayout);
Log.i("rai", "videoLayout = " + R.id.videoLayout);
View nonVideoLayout = rootView.findViewById(R.id.nonVideoLayout);
if(nonVideoLayout == null){
Log.i("rai", "why is nonVideoLayout null?");
}
ViewGroup videoLayout = (ViewGroup) rootView.findViewById(R.id.videoLayout);
if(videoLayout == null){
Log.i("rai", "why is videoLayout null?");
}
webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout);
webView.setWebChromeClient(webChromeClient);
webView.loadUrl("http://m.youtube.com");
return rootView;
}
}
root.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:text="the fragment"/>
<name.cpr.VideoEnabledWebView
android:id="@+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
我只是无法访问我的 Activity 中的这两个相关布局,我总是得到 null。
我尝试过但不起作用的方法:
rootView.findViewById //rootView是来自inflate
的returngetActivity().findViewById
getView().findViewById
container.findViewById
我也在我的 onCreate 片段中尝试过这个:
context = getActivity().getApplicationContext();
webViewFragmentId = context.getResources().getIdentifier(
"root", "layout", context.getPackageName());
webViewId = context.getResources().getIdentifier("webView", "id",
context.getPackageName());
nonVideoLayoutId = context.getResources().getIdentifier("nonVideoLayout", "id", context.getPackageName());
videoLayoutId = context.getResources().getIdentifier("videoLayout","id", context.getPackageName());
rootView = inflater.inflate(webViewFragmentId, null);
webView = (VideoEnabledWebView) rootView.findViewById(webViewId);
View nonVideoLayout = getActivity().findViewById(nonVideoLayoutId);
ViewGroup videoLayout = (ViewGroup) getActivity().findViewById(videoLayoutId);
webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout);
webView.setWebChromeClient(webChromeClient);
webView.loadUrl("http://m.youtube.com");
return rootView;
您需要覆盖 onViewCreated。视图不是在 onCreate 时创建的,而是在实际创建视图后创建的。这个 post 提供了更多信息 Difference between onCreateView and onViewCreated in Fragment
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
...
}
更新2020-10-27
既然 onActivityCreated
已被弃用,documentation 声明您应该改为注册 LifecycleObserver
以了解 Activity.onCreate()
方法何时完成。
有关示例,请参阅
原答案
您应该覆盖 onActivityCreated
并从该方法中的 activity 访问您需要的视图,因为当 onCreateView
在片段中是 运行 时 activity 尚未设置其布局,因此您无法访问其视图。
@Override
public void onActivityCreated (Bundle savedInstanceState) {
View nonVideoLayout = getActivity().findViewById(R.id.nonVideoLayout);
ViewGroup videoLayout = (ViewGroup) getActivity().findViewById(R.id.videoLayout);
...
}
您需要覆盖 onActivityCreated(),因为 activity 在调用此方法之前不会创建视图。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View nonVideoLayout = ((MainActivity)getActivity()).findViewById(R.id.nonVideoLayout);
if(nonVideoLayout == null){
Log.e("rai", "why is nonVideoLayout null?");
}
else{
Log.e("rai", "view not null hurray");
}
View videoLayout = getActivity().findViewById(R.id.videoLayout);
if(videoLayout == null){
Log.e("rai", "why is videoLayout null?");
}else{
Log.e("rai", "view not null hurray");
}