【问题标题】:Android: how do I access views (using findViewById) of an Activity from a Fragment onCreateView()?Android:如何从 Fragment onCreateView() 访问 Activity 的视图(使用 findViewById)?
【发布时间】:2016-01-27 16:43:11
【问题描述】:

我有一个非常简单的项目,其中包含一个片段的 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 中的这两个相对布局,我一直为空。

我尝试过但不起作用的方法:

rootView.findViewById //rootView是inflate的返回

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;

【问题讨论】:

  • 您是否尝试过像((ExampleActivity) getActivity()).findViewById 一样转换getActivity 或在片段的onAttach 方法中使用该代码?

标签: android fragment findviewbyid


【解决方案1】:

2020 年 10 月 27 日更新

现在 onActivityCreated 已被弃用,documentation 状态您应该注册一个 LifecycleObserver 以了解 Activity.onCreate() 方法何时完成。

有关示例,请参阅 this answer


原答案

您应该覆盖onActivityCreated 并在该方法中从活动中访问您需要的视图,因为当onCreateView 在片段中运行时,活动尚未设置其布局,因此您无法访问其视图。

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    View nonVideoLayout = getActivity().findViewById(R.id.nonVideoLayout);
    ViewGroup videoLayout = (ViewGroup) getActivity().findViewById(R.id.videoLayout);
    ...
}

【讨论】:

  • 啊好吧,你知道吗?当我弄乱嵌套片段时,我尝试过的事情实际上是有效的。因此,如果片段是子片段,我可以从活动中访问视图。我猜一个活动在创建子片段时有它的布局?但是父母不会工作。我以为我疯了哈哈。
  • @Rai 子片段是什么意思?如果您使用通常在主机活动的onCreate 或更高版本中完成的FragmentManager 添加片段,那么在这种情况下,可以在片段的onCreateView 中访问视图。
  • 那时一定是这样。我使用子片段管理器创建了子片段。因此,如果我在 Activity 的 onCreate 中使用片段管理器并以这种方式创建片段,它应该可以工作。哇,android 太棘手了:P 如果可行,我将关闭问题并将您的答案标记为已接受。
  • 现在 onActivityCreated() 方法已经被弃用了,在最新的 SDK 上怎么做呢?无法使用片段 onViewCreated 方法,因为此时活动视图不可用。谢谢
【解决方案2】:

您需要重写 onActivityCreated(),因为在调用此方法之前不会创建活动视图。

@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");
    }

【讨论】:

    【解决方案3】:

    您需要覆盖 onViewCreated。视图不是在 onCreate 中创建的,而是在实际创建视图后创建的。这篇文章提供了更多信息Difference between onCreateView and onViewCreated in Fragment

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多