关于android:findViewById在Fragment中

findViewById in Fragment

我试图在片段中创建一个ImageView,它将引用我在XML中为片段创建的ImageView元素。但是,只有当我扩展一个活动类时,findViewById方法才有效。还有什么我可以在片段中使用的吗?

1
2
3
4
5
6
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方法有错误,说明该方法未定义。


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

1
2
3
4
@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()的片段方法中使用。


您需要膨胀片段的视图,并在它返回的View上调用findViewById()

1
2
3
4
5
6
7
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;
}


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

1
2
3
4
5
6
7
8
@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);
}

切记在片段的情况下,如果您从onCreateView()方法返回null或super.onCreateView()时,不会自动调用onViewCreated()方法。在ListFragment的情况下,默认调用,因为ListFragment默认返回FrameLayout

注意:在成功执行onCreateView()之后,您可以使用getView()在类中的任何地方获得片段视图。即

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


我意识到这是一个古老的问题,但普遍的答案留下了一些值得期待的东西。

这个问题还不清楚imageView的要求是什么——我们是把它作为视图传递回去,还是仅仅为以后保存一个参考?

不管怎样,如果imageView来自充气布局,正确的方法是:

1
2
3
4
5
6
7
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;
    }
}


首先获取片段视图,然后从此视图获取图像视图。

1
2
3
4
5
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;
}


你也可以用onActivityCreated方法来实现。

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

和这里一样:http://developer.android.com/reference/android/app/fragment.html(在API级别28中已弃用)

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

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

是可能的。


getView()将给出根视图

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

您可以重写onViewCreated(),该函数在所有视图都充气后立即调用。这是填充片段成员View变量的正确位置。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
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);
    }
}

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

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

1
2
3
4
5
6
7
8
9
10
11
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);
}


1
2
EditText name = (EditText) getView().findViewById(R.id.editText1);
EditText add = (EditText) getView().findViewById(R.id.editText2);

1)首先展开片段的布局,然后可以使用findViewByID。

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


同意就此致电findViewById()

1
2
3
4
5
6
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;
}

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


根据API 11级文件

参考,在后堆栈中http://developer.android.com/reference/android/app/fragment.html网站

短代码

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * 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;
}


使用

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

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

它会起作用


注:

在API级别26中,您也不需要特别强制转换findView的结果,因为它对其返回类型使用推理。

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

1
2
3
4
5
6
7
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;
}


1)声明布局文件。

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

2)然后,获取视图的ID

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

试试这个,它对我有用

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
    }
}


还有一个名为OnViewCreated的方法。

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


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

1
2
3
4
5
6
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
}

这样,rootview就可以用于在XML布局中定义的每个控件,这样代码就更干净了。

希望这有帮助:)


试试这个:

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

return v;

使用Gradle骨架插件,它将自动生成视图持有者类,并引用您的布局。

1
2
3
4
5
6
7
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类。


尝试

1
2
3
4
5
6
7
8
9
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;
}


您可以使用您在片段中的public void onAttach(Activity activity)方法中获得的活动对象调用findViewById()

将活动保存到变量中,例如:

在fragment类中:private Activity mainActivity;onAttach()法中:this.mainActivity=activity;

最后,通过可用项执行每个findViewByID:mainActivity.findViewById(R.id.TextView);


OnCreateView方法内部

1)首先,必须对要添加的布局/视图进行充气。例如线性布局

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

2)然后您可以从布局中找到您的ImageView ID。

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

3)返回充气布局

1
return ll;


在片段中,我们需要该窗口的视图,以便对该片段进行onCreateView。

然后获取视图并使用它访问该视图元素的每个视图ID。

1
2
3
4
5
6
7
8
9
10
11
  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;
        }
    }


布局充气器在这里出现。布局充气器是一种使我们能够在Java代码中使用XML视图的类。因此,您可以用以下代码填充变量v中的根XML视图。然后使用v,可以找到根视图v的子视图。

1
2
3
4
5
6
7
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;
    }
}

你得把视野放大

1
2
3
4
5
6
7
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
}}

getView()只有在onCreateView()完成后才起作用,所以从onPostCreate()调用它:

1
2
3
4
5
@Override
public void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    ImageView imageView = (ImageView) getView().findViewById(R.id.foo);
}

使用这种东西最简单的方法是使用巴特刀。这样,您就可以通过@onclick()添加尽可能多的onclickListener,如下所述:

1
2
3
4
5
6
7
8
9
10
11
12
public class TestClass extends Fragment {
    @BindView(R.id.my_image) ImageView imageView;
    @OnClick(R.id.my_image)
    public void my_image_click(){
        yourMethod();
    }
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.testclassfragment, container, false);
        ButterKnife.bind(getActivity,view);
        return view;
    }
}


1
2
3
4
5
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;
}

注意,如果使用getView()方法,可能会导致nullPointerException返回rootview,并且在onCreateView()方法之后会出现一些视图。


.commit()之后的事务计时也可能导致此问题

我也遇到了同样的问题(无法访问片段中的视图)。原因是,在(fragmentTransaction.commit()之后,视图没有在UI中被激活。在.commit()之后,当事务发生时没有保证;它只是排队的。所以我添加了一个(fragmentmanager.executependingTransactions()来强制完成事务。在此之后,引用视图将按预期工作!