ChatGPT解决这个技术问题 Extra ChatGPT

我正在尝试在 Fragment 中创建一个 ImageView,它将引用我在 XML 中为 Fragment 创建的 ImageView 元素。但是,findViewById 方法仅在我扩展 Activity 类时才有效。无论如何,我也可以在 Fragment 中使用它吗?

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ImageView imageView = (ImageView)findViewById(R.id.my_image);
        return inflater.inflate(R.layout.testclassfragment, container, false);
    }
}

findViewById 方法上有一个错误,指出该方法未定义。

使用 Android 的 ButterKnife 视图绑定库。还演示它是如何工作的,如何在您的 android 应用程序开发中集成和使用以使您的开发更快。
'一些'时间过去了,但您仍然没有接受答案。您能否选择对您最有帮助的答案,以便将其标记为已回答?
鼓励使用 Data Binding orang View Binding 而不是手动 findViewById

O
OneCricketeer

使用 getView() 或实现 onViewCreated 方法的 View 参数。它返回片段 (由 onCreateView() 方法返回的那个) 的根视图。有了这个,您可以调用 findViewById()

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    ImageView imageView = (ImageView) getView().findViewById(R.id.foo);
    // or  (ImageView) view.findViewById(R.id.foo); 

由于 getView() 仅在 onCreateView() 之后有效,您不能在片段的 onCreate()onCreateView() 方法中使用它。


注意:它仅在 onCreateView() 之后有效。所以,你不能在 onCreate() 中使用它
那么如果 onCreate 不是正确的地方,我可以覆盖什么功能来实现它?
如果 ImageView 来自膨胀的布局,这将无济于事 - 有关详细信息,请参阅我的答案。否则, onCreateView 是执行此操作的正确位置@N-AccessDev
执行此操作的最佳位置是 onViewCreated 方法
该文档指出,onActivityCreated() 是查找和存储对您的视图的引用的推荐位置。您必须通过在 onDestroyView() 中将它们设置回 null 来清理这些存储的引用,否则您将泄漏 Activity
J
JJD

您需要扩展 Fragment 的视图并在它返回的 View 上调用 findViewById()

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
     return view;
}

当您执行 V.findViewById(R.id.someid) 时,肯定只适用于膨胀视图中的所有小部件。如果他试图膨胀的 imageView 在膨胀的视图之外怎么办?
然后,“拥有”并夸大 imageView 的类需要提供对它的公共访问。这是非常糟糕的做法。片段应该只能访问其布局中存在的 UI 元素。
看起来你的代码有问题(从后台线程更新 UI),而不是我的。
谢谢,很有用。作为不相关的评论:尝试在代码中坚持 Java 命名约定。 “V”看起来不像 Java 中的变量名。
这应该是正确的答案。被接受的留给您 NullPointerException
A
Ankur Chaudhary

Fragment 类中,您将获得 onViewCreated() 覆盖方法,您应该始终初始化您的视图,因为在此方法中您将获得视图对象,您可以使用该对象找到您的视图,例如:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.findViewById(R.id.yourId).setOnClickListener(this);

    // or
    getActivity().findViewById(R.id.yourId).setOnClickListener(this);
}

永远记住,在 Fragment 的情况下,如果您从 onCreateView() 方法返回 null 或 super.onCreateView(),则不会自动调用 onViewCreated() 方法。在 ListFragment 的情况下默认调用它,因为 ListFragment 默认返回 FrameLayout

注意:一旦 onCreateView() 成功执行,您可以使用 getView() 在类中的任何位置获取片段视图。 IE

getView().findViewById("your view id");

我很惊讶没有很多人支持这个响应——这是在片段上设置侦听器的正确方法......也许这是 API 的新发展。
使用 view 传递给 onViewCreated 仍然会导致 NullPointerException 但使用 getActivity() 很好。任何想法为什么?
@dVaffect 可能是您没有在片段的 onCreateView() 生命周期方法中返回非空视图。现在,在 getActivity 的情况下,您从活动中获取视图而不是片段主视图取决于您传递的 id。请检查您是否从 onCreateView 返回非空视图?然后告诉我。
@AnkurChaudhary 我从 onCreateView 方法返回视图。我刚刚调试过,结果发现有一个布局(在我的例子中是 FrameLayout)。话虽如此,当我尝试查找它返回 null 的元素时。为什么会这样?
@dVaffection 能否请您分享您的片段类别和相应的布局。
M
MattJenko

我意识到这是一个老问题,但普遍的答案还有待改进。

问题不清楚 imageView 需要什么 - 我们是将其作为视图传递回来,还是只是保存参考以供以后使用?

无论哪种方式,如果 ImageView 来自膨胀的布局,正确的做法是:

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
        return v;
    }
}

那么你将如何从 ListFragment 更新 imageView?这需要 FragmentManager 吗?换句话说,如何从单独的类的 onListItemClick 更新详细片段中的 imageView?
您可以在方便的地方保存对 imageView 的引用,或者在需要时保存 fragment.getView().findViewById(R.id.my_image) 。在 ListFragment 中,假设图像在列表项中,您通常会在适配器的 getView 方法中使用列表视图项的 setTag/getTag 方法创建一个引用持有者 - 有很多示例说明如何执行此操作。
@MattJenko,您能否分享更多详细信息或示例在使用膨胀布局时如何获得可行的解决方案?例如,我有一个带有 tablayout(4 个选项卡)的 viewpager2,并且我正在扩展片段中的 edittext 视图,我需要从主要活动中访问每个 viewpager2 视图的 editext。具体怎么做?
x
xevincent

首先获取片段视图,然后从该视图获取您的 ImageView。

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
    return view;
}

那么,onCreate 方法在 Fragment 中有用吗?
onCreateView 创建并返回与片段关联的视图层次结构。调用 onCreate 来执行片段的初始创建。实际上,这取决于您在这些方法中编写的内容。
好的,但是我如何在 onCreate 中声明变量?因为 View 在 onCreateView 方法里面。
@Tsunaze 你有没有从 onCreate 方法中发现如何做到这一点?
我同意。此答案应标记为解决方案。
A
Apurv

Fragment 类中,我们获得了 onViewCreated() 覆盖方法,我们应该始终初始化我们的视图,因为在此方法中我们获得了 view 对象。使用这个对象,我们可以找到如下视图:

class MyFragment extends Fragment {
    private ImageView imageView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_fragment_layout, container, false);
    }

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

        //initialize your view here for use view.findViewById("your view id")
        imageView = (ImageView) view.findViewById(R.id.my_image);
    }
}

r
rafvasq

您也可以在 onActivityCreated 方法中执行此操作。

public void onActivityCreated(Bundle savedInstanceState) { 
      super.onActivityCreated(savedInstanceState);
}

就像他们在这里做的那样:http://developer.android.com/reference/android/app/Fragment.html (在 API 级别 28 中已弃用)

getView().findViewById(R.id.foo);

getActivity().findViewById(R.id.foo);

是可能的。


请注意,API 28 引入了 requiereActivity()、requireView()、requireViewById()。
c
conca

getView() 将给出根视图

View v = getView().findViewByID(R.id.x); 

C
Community

您可以覆盖 onViewCreated() ,它在所有视图都被膨胀后立即调用。这是填写 Fragment 的成员 View 变量的正确位置。这是一个例子:

class GalleryFragment extends Fragment {
    private Gallery gallery;

    (...)

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        gallery = (Gallery) view.findViewById(R.id.gallery);
        gallery.setAdapter(adapter);
        super.onViewCreated(view, savedInstanceState);
    }
}

Z
Ziem

getView() 方法不适用于 OnCreate 和类似方法之外的片段。

您有两种方法,将视图传递给 oncreate 上的函数(这意味着您只能在创建视图时运行函数)或将视图设置为变量:

private View rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.fragment_contatos, container, false);
}

public void doSomething () {
    ImageView thumbnail = (ImageView) rootView.findViewById(R.id.someId);
}

p
priti

1)首先膨胀片段的布局,然后你可以使用 findviewbyId 。

View view = inflater.inflate(R.layout.testclassfragment, container, false);
             ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
             return view;

Z
Ziem

同意在视图上调用 findViewById()

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View V = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) V.findViewById(R.id.my_image);

    return V;
}

Z
Ziem
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);  

K
Kartik Shandilya

笔记 :

从 API 级别 26 开始,您也不需要专门转换 findViewById 的结果,因为它对其返回类型使用推理。

所以现在你可以简单地做,

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView =  view.findViewById(R.id.my_image); //without casting the return type
     return view;
}

没有解释的事情对我有帮助。
我建议将此答案与 API 28 中提到弃用 getView() 的内容结合起来。
M
Manoj ahirwar

利用

imagebutton = (ImageButton) getActivity().findViewById(R.id.imagebutton1);

imageview = (ImageView) getActivity().findViewById(R.id.imageview1);

它会起作用的


D
Dexter

根据 API 级别 11 的文档

参考,在 Back Stack http://developer.android.com/reference/android/app/Fragment.html

短代码

/**
 * The Fragment's UI is just a simple text view showing its
 * instance number.
 */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.hello_world, container, false);
    View tv = v.findViewById(R.id.text);
    ((TextView)tv).setText("Fragment #" + mNum);
    tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
    return v;
}

C
Chris

使用 getView() 返回片段的视图,然后您可以调用 findViewById() 访问片段视图中的任何视图元素。


视图不是活动
O
OneCricketeer

试试这个它对我有用

public class TestClass extends Fragment {
    private ImageView imageView;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.testclassfragment, container, false);
        findViews(view);
        return view;
    }

    private void findViews(View view) {
        imageView = (ImageView) view.findViewById(R.id.my_image);
    }
}

是的,这里的代码没问题。您对另一个的编辑不是。
@cricket_007 好的,你能看到我哪一个?
对不起,我不太明白你的英语,但现在一切都解决了。我没有什么可以给你看的。
M
Michele La Ferla

实现这一点的最佳方法如下:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

rootView = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView) rootView.findViewById(R.id.my_image);
        return rootView
}

这样,xml布局中定义的每一个控件都可以使用rootView,这样代码就干净多了。

希望这可以帮助 :)


我认为这可能是可行的,但是,它没有用
Z
Ziem

1)声明你的布局文件。

public View onCreateView(LayoutInflater inflater,ViewGroup container, 
                                 Bundle savedInstanceState) {
    return inflate(R.layout.myfragment, container, false);
}

2)然后,获取您的视图的ID

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    TextView nameView = (TextView) view.findViewById(R.id.textview1);
}

I
Ilya Gazman

使用 gradle skeleton plugin,它会根据您的布局自动生成视图持有者类。

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        MyLayout myLayout = new MyLayout(inflater, container, false);
        myLayout.myImage.setImageResource(R.drawable.myImage);
        return myLayout.view;
    }
}

现在假设您在 my_layout.xml 文件中声明了一个 ImageView,它会自动为您生成 myLayout 类。


Z
Ziem

尝试这个:

View v = inflater.inflate(R.layout.testclassfragment, container, false);
ImageView img = (ImageView) v.findViewById(R.id.my_image);

return v;

R
Ramkumar.M

尝试

private View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
myFragmentView = inflater.inflate(R.layout.myLayoutId, container, false);
myView = myFragmentView.findViewById(R.id.myIdTag)
return myFragmentView;
}

场上没有理由。您以后随时可以致电 getView()
m
mrSurprise

您可以使用您在 Fragment 中的 public void onAttach(Activity activity) 方法中获得的 Activity Object 调用 findViewById()

将 Activity 保存到变量中,例如:

Fragment 类 中:private Activity mainActivity;onAttach() 方法中:this.mainActivity=activity;

最后通过变量执行每个 findViewById:mainActivity.findViewById(R.id.TextView);


Z
Ziem

还有一种称为 onViewCreated 的方法。

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ImageView imageView = (ImageView) view.findViewById(R.id.imageview1);
}

V
Vasia Zaretskyi

我喜欢一切都井井有条。你可以这样做。

首先初始化视图

private ImageView imageView;

然后覆盖 OnViewCreated

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

然后添加一个void方法来查找视图

private void findViews(View v) {
    imageView = v.findViewById(R.id.img);
}

M
Mazhar Iqbal
//here you can do it by
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState)
  {
    // Inflate the layout for this fragment
    final View view =  inflater.inflate(R.layout.fragment_apple, container, 
 false);
    ist = view.findViewById(R.id.linearLink);
    second = view.findViewById(R.id.linearPhone);
    return view;

J
Jorgesys

onCreateView 方法内部

1)首先你必须膨胀你想要添加的布局/视图,例如。线性布局

LinearLayout ll = inflater.inflate(R.layout.testclassfragment, container, false);

2)然后你可以从布局中找到你的imageView id

ImageView imageView = (ImageView)ll.findViewById(R.id.my_image);

3)返回膨胀的布局

return ll;

这与 LeffelMania 的回答相同。
S
Surajit Mondal

你必须给视图充气

public class TestClass extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
    return v
}}

O
OneCricketeer

在片段中,我们需要该窗口的视图,以便我们创建此片段的 onCreateView。

然后获取视图并使用它来访问该视图元素的每个视图 id..

  class Demo extends Fragment
    {
        @Override
        public View onCreateView(final LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState)
        {
            View view =inflater.inflate(R.layout.demo_fragment, container,false);
            ImageView imageview=(ImageView)view.findViewById(R.id.imageview1);

            return view;
        }
    }

1)这对其他答案有什么影响? 2)你似乎已经回答了两次

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅