【问题标题】:Access fragment variable outside of Fragment in view pager在视图寻呼机中访问片段之外的片段变量
【发布时间】:2017-02-21 15:42:45
【问题描述】:

enter image description here

在阅读问题之前,请参考图片。

我正在使用 viewpager 来显示片段。

问题

在片段中,我使用了两个edittext,比如说editText1、editText2 现在的问题是我将如何获取editText 数据。当用户单击下一个按钮但下一个按钮位于片段之外时,我只能获取 editText 值。如何访问片段外的editText。

在否决问题之前,请告诉我原因,以便我改进我的问题。

片段java类

// newInstance constructor for creating fragment with arguments
        public static BpDetails newInstance(int page) {
            BpDetails fragmentFirst = new BpDetails();
            Bundle args = new Bundle();
            args.putInt("someInt", page);
            fragmentFirst.setArguments(args);
            return fragmentFirst;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            page = getArguments().getInt("someInt", 0);
        }


        // Inflate the view for the fragment based on layout XML
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            final View view = inflater.inflate(R.layout.bp_details, container, false);

            Log.i("View ",view.toString());

            Log.i("DOB is ",Long.toString(Constants.dob));


            systolic =(EditText) view.findViewById(R.id.systolic);
            diastolic =(EditText) view.findViewById(R.id.diastolic);


            return view;
        }

ViewPager 活动

vpPager = (ViewPager) findViewById(R.id.view_pager);

        adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
        vpPager.setAdapter(adapterViewPager);

        Fragment fragment=adapterViewPager.getItem(prevPage);

        if (fragment.getClass().equals(BpDetails.class)){
            Log.i("Call ","Yes");
        }

        findViewById(R.id.btn_prev).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // checking for last page
                // if last page home screen will be launched
                int current = getItem(-1);
                if (current!=0)
                    prevPage=current-1;
                if (current < 4) {
                    // move to next screen
                    vpPager.setCurrentItem(current);
                } else {
                    //final reached.
                }

            }
        });

        findViewById(R.id.btn_next).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // checking for last page
                // if last page home screen will be launched
                int current = getItem(+1);



                if (current!=0)
                    prevPage=current-1;

                System.out.println("Prev page "+prevPage);

                if (current < 4) {
                    // move to next screen

                    Fragment prevFragment=adapterViewPager.getItem(prevPage);


                } else {

                    //final reached.
                }
            }
        });


    }

    private int getItem(int i) {
        return vpPager.getCurrentItem() + i;
    }


    public static class MyPagerAdapter extends FragmentPagerAdapter {
        private static int NUM_ITEMS = 4;
        private static int mSelectedPosition;

        public MyPagerAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
            //mSelectedPosition=selectedPosition;
        }

        // Returns total number of pages
        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0: // Fragment # 0 - This will show FirstFragment
                    return BasicDetails.newInstance(0);
                case 1:
                    return BpDetails.newInstance(1);
                case 2:
                    return BslDetails.newInstance(2);
                case 3:
                    return Summary.newInstance(3);

                default:
                    return null;
            }
        }


    }

【问题讨论】:

  • ^.你是如何实现ViewPager
  • @an_droid_dev 分享了代码。
  • @JoshLaird 我已经分享了代码。

标签: android android-fragments android-viewpager


【解决方案1】:

像这样在片段中创建两个 getter。

public String getSystolic(){

    return this.systolic.getText().toString();

    }

public String getDiastolic(){

    return this.diastolic.getText().toString();
    }



     BpDetails fr = (BpDetails)myAdapter.getItem(myViewPager.getCurrentItem());
     String systolicString = fr.getSystolic();

【讨论】:

  • java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'android.text.Editable android.widget.EditText.getText()' 这是我遇到的错误。我正在调用 BpDetails fr = (BpDetails)myAdapter.getItem(myViewPager.getCurrentItem());字符串 systolicString = fr.getSystolic();这个,点击下一步按钮。
  • @AnkurKhandelwal 在 onCreateView 方法或日志中设置断点并查看您的 EditText 是否为空
  • 我已经放了登录片段,edittext不为空。
  • @AnkurKhandelwal 当您单击“下一步”按钮时,此片段在 viewpager 中可见?
  • 是的。 @安卓。片段可见。我点击下一步按钮,然后应用程序崩溃。
【解决方案2】:

我遇到了类似的问题。 .getItem() 实例化了一个新的Fragment,因此在调用myAdapter.getItem(...) 时,Fragment 中的所有元素都将为 null,但Fragment 中的元素不会为 null。

当我解决这个问题时,我要做的是在 MyPagerAdapter 内部创建另一个名为 getInstantiatedFragment 的方法:

public Fragment getInstantiatedFragment(int position)
    {
        return fragments.get(position);
    }

fragments 是该类的新字段:

private ArrayList<Fragment> fragments = new ArrayList<>();

我会覆盖getItem()(正如您已经完成的那样)并将其更改为:

@Override
    public Fragment getItem(int position)
    {
        switch (position) {
            case 0:
                BasicDetails basicDetails = BasicDetails.newInstance(0);
                fragments.add(basicDetails);
                return basicDetails;
            ...
    }

您在返回之前将片段添加到fragments 的位置,然后您会调用:

BpDetails fr = (BpDetails)myAdapter.getInstantiatedItem(myViewPager.getCurrentItem());

获取创建片段的实例,然后调用

String systolicString = fr.getSystolic();

如果您使用的是上一个答案的方法。

这样您就可以跟踪fragments 中的实例化片段。我相信还有更好的方法。

【讨论】:

  • 你不应该这样做,因为你会保持对 Fragment 实例的强引用。此外,FragmentPagerAdapter 已经为您缓存了Fragmentsget(int position) 仅在缓存中未找到片段的情况下被调用。
  • 我同意,但是getItem(...) 永远不会为我获得实例化的Fragments,它总是会创建一个新的。它似乎是FragmentPagerAdapter 中的一个抽象方法,所以这可以解释为什么它每次都实例化一个新的Fragment,不是吗?
  • 好吧,如果你看一下FragmentPagerAdapter 的实现,你会看到getItem(...) 在项目的实例化过程中被调用。然而,在它被调用之前,FPA 会尝试使用findFragmentByTag 在其“缓存”中找到这样的片段,并且只有当结果为null 时,您才有责任提供此类片段的新实例。因此 getItem 在您旋转设备时不会被调用,例如
  • 我调用了这个函数 BpDetails fr = (BpDetails)myAdapter.getInstantiatedItem(myViewPager.getCurrentItem());当用户单击下一个按钮但 getInstantiatedItem() 无法识别时。 @JoshLaird
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
相关资源
最近更新 更多