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

Jos*_*h I 8 android android-fragments android-viewpager android-fragmentactivity

这个让我疯了.基本上,我想创建一个ViewPager并添加几个Fragments.然后,所有我想做的事,它在一个设定值FragmentTextView秒.我可以添加Fragments,它们附加,但当我去第findViewById()一个TextViews中的一个时,Fragment它会抛出一个NullPointerException.我,在我的生活中,无法弄清楚为什么.

到目前为止,这是我的代码,请告诉我是否需要更多代码.

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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Fragment我创建的所有s只onCreateView()覆盖了方法,因此我可以显示正确的XML布局.除此之外,他们是'股票'.为什么我不能与任何Fragments中的元素交互?

更新:

那么做这样的事情?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

分段的XML布局A.

<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>
Run Code Online (Sandbox Code Playgroud)

Aas*_*hir 5

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

  • 第一个是最简单的,你应该简单地移动代码,将文本更改为相应的片段类,在这种情况下为FragmentA.
  • 其次,您可以将TextViewFragmentA设置为静态,因此可以被其他类访问.所以你的代码看起来像这样:

     ....
     TextView myText;
    
     @Override
     public View onCreateView(....) {
    
         myLayout = ....;
    
         myText = myLayout.findViewById(yourID);
    
         ....
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

   FragmentA.myText.setText("new text");
Run Code Online (Sandbox Code Playgroud)

解释方法2

在片段中使用以下内容.

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

然后更改文本,如:

FragmentA.setText("Lulz");
Run Code Online (Sandbox Code Playgroud)


C0D*_*OU5 4

除非您计划在运行时更改该值,否则可以将该值作为参数传递到片段中。这是通过使用 Bundle 并将其作为参数传递到 Fragment 中来完成的,然后 Fragment 从它的参数中检索它。更多信息请点击这里。如果你实现这个,你的新片段的实例化可能看起来像这样:

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>"));
        }
Run Code Online (Sandbox Code Playgroud)

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

//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");
...
Run Code Online (Sandbox Code Playgroud)

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

虽然可以“更轻松”地完成,但建议使用这些方法,因为它们减少了出现错误的机会并使代码更具可读性和可维护性。

编辑:这就是您的片段应该是什么样子(修改了您的代码):

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果之后您仍然遇到空指针异常,则您的 TextView 未位于我需要的位置,即在 R.layout.fragment_a 文件中,并且它需要位于那里。当然,除非您在片段加载完成之前调用接口方法。