Android 在 FragmentPagerAdapter 中的 Fragment 中设置 TextView 的文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24559124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:25:04  来源:igfitidea点击:

Android Set Text of TextView in Fragment that is in FragmentPagerAdapter

androidandroid-fragmentsandroid-viewpagerandroid-fragmentactivity

提问by Josh I

This one is driving me nuts. Basically, I want to create a ViewPagerand add a few Fragments to it. Then, all I want to do, it set a value in one of the Fragment's TextViews. I can add the Fragments fine, and they attach, but when I go to findViewById()for one of the TextViews in the first Fragmentit throws a NullPointerException. I, for the life of me, can't figure out why.

这个让我发疯。基本上,我想创建一个ViewPager并添加一些Fragments 到它。然后,我想做的就是在Fragment's之一中设置一个值TextView。我可以Fragment很好地添加s,然后它们会附加,但是当我去findViewById()寻找第一个TextViews 时,Fragment它会抛出一个NullPointerException. 我,对于我的生活,无法弄清楚为什么。

Here's my code so far, let me know if more is needed please.

到目前为止,这是我的代码,如果需要更多,请告诉我。

public class SheetActivity extends FragmentActivity {

    // /////////////////////////////////////////////////////////////////////////
    // Variable Declaration
    // /////////////////////////////////////////////////////////////////////////
    private ViewPager               viewPager;
    private PagerTitleStrip         titleStrip;
    private String                  type;
    private FragmentPagerAdapter    fragmentPager;  //UPDATE

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sheet);

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        titleStrip = (PagerTitleStrip) findViewById(R.id.viewPagerTitleStrip);

        // Determine which type of sheet to create
        Intent intent = getIntent();
        this.type = intent.getStringExtra("type");
        FragmentManager manager = getSupportFragmentManager();
        switch (type) {
            case "1":
                viewPager.setAdapter(new InstallAdapter(manager));
                break;
            case "2":
                viewPager.setAdapter(new InstallAdapter(manager));
                break;
        }
        fragmentPager = (FragmentPagerAdapter) viewPager.getAdapter();  //UPDATE
    }

    @Override
    public void onResume() {
        super.onResume();

        fragmentPager.getItem(0).setText("something"); //UPDATE
    }

    class MyAdapter extends FragmentPagerAdapter {

        private final String[]      TITLES      = { "Title1", "Title2" };
        private final int           PAGE_COUNT  = TITLES.length;
        private ArrayList<Fragment> FRAGMENTS   = null;

        public MyAdapter(FragmentManager fm) {
            super(fm);
            FRAGMENTS = new ArrayList<Fragment>();
            FRAGMENTS.add(new FragmentA());
            FRAGMENTS.add(new FragmentB());
        }

        @Override
        public Fragment getItem(int pos) {
            return FRAGMENTS.get(pos);
        }

        @Override
        public int getCount() {
            return PAGE_COUNT;
        }

        @Override
        public CharSequence getPageTitle(int pos) {
            return TITLES[pos];
        }
    }
}

All of Fragments I created only have the onCreateView()method overridden so I can display the proper XML layout. Other than that they are 'stock'. Why can't I interact with elements in any of the Fragments?

Fragment我创建的所有s 都只onCreateView()覆盖了方法,因此我可以显示正确的 XML 布局。除此之外,它们是“库存”。为什么我不能与任何Fragments 中的元素进行交互?

UPDATE:

更新:

So do something like this?

那么做这样的事情吗?

public class FragmentA extends Fragment {

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

    public void setText(String text) {
        TextView t = (TextView) getView().findViewById(R.id.someTextView);  //UPDATE
        t.setText(text);
    }
}

XML LAYOUT FOR FRAGMENT A

片段 A 的 XML 布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/someTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="22sp" />

</LinearLayout>

采纳答案by C0D3LIC1OU5

Unless you are planning to change the value at runtime, you can pass the value into the fragment as a parameter. It is done my using a Bundle and passing it as args into a Fragment, which then retrieves it from it's args. More info here. If you implement this, your instantiation of new Fragments might look something like this:

除非您计划在运行时更改该值,否则您可以将该值作为参数传递到片段中。我使用 Bundle 并将其作为 args 传递到 Fragment 中,然后从它的 args 中检索它。更多信息在这里。如果您实现了这一点,您的新 Fragments 实例化可能如下所示:

public InstallAdapter(FragmentManager fm) {
            super(fm);
            FRAGMENTS = new ArrayList<Fragment>();
            FRAGMENTS.add(FragmentA.newInstance("<text to set to the TextView>"));
            FRAGMENTS.add(FragmentB.newInstance("<text to set to the TextView>"));
        }

If, however, you are planning to update the value at runtime (it will change as user is running the app), then you want to use an Interface to channell communication between your fragment and your activity. Info here. This is what it might look like:

但是,如果您计划在运行时更新该值(它会随着用户运行应用程序而改变),那么您希望使用接口来引导片段和活动之间的通信。信息在这里。这可能是这样的:

//Declare your values for activity;
    ISetTextInFragment setText;
    ISetTextInFragment setText2;
...
//Add interface
public interface ISetTextInFragment{
    public abstract void showText(String testToShow);
}
...
//your new InstallAdapter
public InstallAdapter(FragmentManager fm) {
        super(fm);

        FRAGMENTS = new ArrayList<Fragment>();

        Fragment fragA = new FragmentA();
        setText= (ISetTextInFragment)fragA;
        FRAGMENTS.add(fragA);

        Fragment fragB = new FragmentB();
        setText2= (ISetTextInFragment)fragB;
        FRAGMENTS.add(fragB);
}

//then, you can do this from your activity:
...
setText.showText("text to show");
...

and it will update your text view in the fragment.

它将更新片段中的文本视图。

While it can be done "more easily", these methods are recomended because they reduce chances of bugs and make code a lot more readable and maintainable.

虽然它可以“更容易”完成,但推荐使用这些方法,因为它们减少了错误的机会并使代码更具可读性和可维护性。

EDIT: this is what your Fragment should look like (modified your code):

编辑:这就是您的 Fragment 的样子(修改了您的代码):

public class FragmentA extends Fragment implements ISetTextInFragment {

    TextView myTextView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle inState) {
        View v = inflater.inflate(R.layout.fragment_a, container, false);
        myTextView = (TextView)v.findViewbyId(R.id.someTextView)
        return v;
    }

    @Override
    public void showText(String text) {
        myTextView.setText(text);
    }
}

If after that you are still getting a null pointer exception, your TextView is NOT located where it needs to me, namely in the R.layout.fragment_a filem, and it needs to be located there. Unless you are calling the interface method BEFORE the fragment finished loading, of course.

如果在那之后你仍然得到一个空指针异常,你的 TextView 不在它需要的地方,即在 R.layout.fragment_a 文件中,它需要位于那里。当然,除非您在片段加载完成之前调用接口方法。

回答by Aashir

The TextViewis located in the fragments layout, not in the ViewPagersor the PagerAdapter, that is causing the NPE. Now, you have 2 options.

TextView位于片段布局,而不是在ViewPagersPagerAdapter,也就是造成NPE。现在,您有 2 个选择。

  • The first is the easiest, you should simple move your code for changing the text into the corresponding fragment's class, FragmentA in this case.
  • Secondly, you could make the TextViewinto FragmentA static, so it can be accessed by other classes. So your code would look something like this:

     ....
     TextView myText;
    
     @Override
     public View onCreateView(....) {
    
         myLayout = ....;
    
         myText = myLayout.findViewById(yourID);
    
         ....
    }
    
  • 第一个是最简单的,您应该简单地将用于更改文本的代码移动到相应片段的类中,在本例中为 FragmentA。
  • 其次,您可以将TextViewinto FragmentA 设为静态,以便其他类可以访问它。所以你的代码看起来像这样:

     ....
     TextView myText;
    
     @Override
     public View onCreateView(....) {
    
         myLayout = ....;
    
         myText = myLayout.findViewById(yourID);
    
         ....
    }
    

And then you would change the text from somewhere else (if it's really necessary):

然后你会从其他地方更改文本(如果真的有必要):

   FragmentA.myText.setText("new text");

Explaining method 2

说明方法二

Use the following in your Fragment.

在您的片段中使用以下内容。

public static void setText(String text) {
    TextView t = (TextView) getView().findViewById(R.id.someTextView);
    t.setText(text);
}

Then change the text like:

然后将文本更改为:

FragmentA.setText("Lulz");

回答by Carlos J

This line:

这一行:

TextView t = (TextView) findViewById(R.id.someTextViewInFragmentA);

is looking for the view in your ParentActivity. Of course it wont find it and that's when you get your NPE.

正在您的 ParentActivity 中寻找视图。当然,它不会找到它,那是您获得 NPE 的时候。

Try something like this:

尝试这样的事情:

  1. Add a "tag" to your fragments when you add them

  2. Use someFragment = getSupportFragmentManager().findFragmentByTag("your_fragment_tag")

  3. Get the view of the fragment fragmentView = someFragment.getView();

  4. And finally find your TextViewand set the text

    TextView t = (TextView) fragmentView.findViewById(R.id.someTextViewInFragmentA); t.setText("some text");

  1. 添加片段时为片段添加“标签”

  2. someFragment = getSupportFragmentManager().findFragmentByTag("your_fragment_tag")

  3. 获取片段的视图 fragmentView = someFragment.getView();

  4. 最后找到你的TextView并设置文本

    TextView t = (TextView) fragmentView.findViewById(R.id.someTextViewInFragmentA); t.setText("some text");

回答by Artis JIANG

How about to change this line

这条线怎么改

TextView t = (TextView) getView().findViewById(R.id.someTextView);  //UPDATE

to

TextView t = (TextView) getActivity().findViewById(R.id.someTextView);  //UPDATE

then you can try to update "t" with .setText("some_string") inside "SheetActivity".

那么您可以尝试在“SheetActivity”中使用 .setText("some_string") 更新“t”。