【问题标题】:Android Fragments Not UpdatingAndroid 片段未更新
【发布时间】:2014-04-15 00:30:42
【问题描述】:

我正在尝试创建一个非常简单的 Android 应用程序,它使用 FragmentPagerAdapter 在三个片段之间滑动。每个片段都包含一个 EditText,并且具有完全相同的代码。

期望的行为是当用户更新 EditText 时,新值被保存到应用程序实例中。然后,一旦选择了新片段,该新片段应显示保存的值。由于某种原因,这不起作用。

我还希望焦点片段在应用程序恢复(从后台返回)时显示保存的数据。这也行不通。

我真的很困惑,为什么这么简单的事情这么难!

到目前为止,这是我的代码:

StackOverflowDemoApplication.java:

public class StackOverflowDemoApplication extends Application {

    private ApplicationData applicationData;

    // the index of the last fragment that was displayed
    private int lastItem = 0;

    @Override
    public void onCreate() {

        applicationData = new ApplicationData();
    }

    public ApplicationData getApplicationData() {
        return applicationData;
    }

    public int getLastItem() {
        return lastItem;
    }

    public void setLastItem(int lastItem) {
        this.lastItem = lastItem;
    }
}

MainActivity.java

public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
    private static final String TAG = "MainActivity";

    // the application instance
    private StackOverflowDemoApplication application;

    // the pager adapter
    private SectionsPagerAdapter pagerAdapter;

    // the view pager
    private ViewPager viewPager;

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

        // Save the application instance.
        application = (StackOverflowDemoApplication) getApplication();

        // Set up the action bar.
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        pagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        viewPager = (ViewPager) findViewById(R.id.pager);
        viewPager.setAdapter(pagerAdapter);

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < pagerAdapter.getCount(); i++) {

            actionBar.addTab(
                    actionBar.newTab()
                            .setText(pagerAdapter.getPageTitle(i))
                            .setTabListener(this));
        }
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

        viewPager.setCurrentItem(tab.getPosition());
        pagerAdapter.notifyDataSetChanged();
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {
        private int NUM_ITEMS = 3;

        public SectionsPagerAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        @Override
        public Fragment getItem(int position) {

            // get the application data instance
            ApplicationData data = application.getApplicationData();

            switch (position) {
                case 0:
                    return SecondFragment.newInstance(data);
                case 1:
                    return FirstFragment.newInstance(data);
                case 2:
                    return ThirdFragment.newInstance(data);
                default:
                    return null;
            }
        }

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

        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

        @Override
        public CharSequence getPageTitle(int position) {

            switch (position) {
                case 0:
                    return "FIRST FRAGMENT";
                case 1:
                    return "SECOND FRAGMENT";
                case 2:
                    return "THIRD FRAGMENT";
                default:
                    return null;
            }
        }
    }

    @Override
    public void onResume() {

        // load the previous fragment
        viewPager.setCurrentItem(application.getLastItem());

        super.onResume();
    }

    @Override
    public void onPause() {

        // save the last fragment we used
        application.setLastItem(viewPager.getCurrentItem());

        super.onPause();
    }
}

FirstFragment.java

public class FirstFragment extends Fragment {
    private static final String TAG = "FirstFragment";

    // the activity reference
    private Activity activity;

    // the application data
    private ApplicationData data;

    // the edit text
    private EditText editText;

    // are we currently loading data for this fragment?
    private boolean loadingData = false;

    public FirstFragment(ApplicationData data) {
        super();

        this.data = data;
    }

    public static FirstFragment newInstance(ApplicationData data) {
        Log.e(TAG, "New instance called");
        FirstFragment fragment = new FirstFragment(data);
        return fragment;
    }

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

        Log.e(TAG, "Creating FirstFragment view");

        // inflate the view
        View view = inflater.inflate(R.layout.first_fragment_layout, container, false);

        // get the activity instance
        activity = getActivity();

        // the textview
        editText = (EditText) view.findViewById(R.id.textView);
        editText.addTextChangedListener(textWatcher);

        // update the ui from the data
        updateUIFromData();

        return view;
    }

    public void updateUIFromData() {

        // we have started loading the data
        loadingData = true;

        // if there is data
        if (null != data) {

            // set the value
            if (null != data.getStringValue()) {
                editText.setText(data.getStringValue());
            }
        }

        // done loading the data
        loadingData = false;
    }

    private void updateDataFromUi() {

        data.setStringValue(editText.getText().toString());
    }

    private TextWatcher textWatcher = new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            // if we are not loading data
            if (!loadingData) {

                // update the data from the ui
                updateDataFromUi();
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };
}

【问题讨论】:

    标签: android android-fragments android-viewpager global-variables fragment


    【解决方案1】:

    当片段对用户可见时尝试更新视图,如下所示:

    public class MyFragment extends Fragment
        @Override
        public void setMenuVisibility(final boolean visible) {
            super.setMenuVisibility(visible);
            if (visible) {
                **//Get new data and update views here**
            }
        }
    

    【讨论】:

      【解决方案2】:

      查看本教程,它可能会对您有所帮助: http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/

      您不必在 tabSelected 回调中调用 notifyDataSetChanged()。

      【讨论】:

      • 该教程中是否有处理全局数据或在片段之间共享数据的地方?我阅读了它,但没有看到任何与我的问题相关的内容。
      • 您可以使用您的活动在片段之间共享数据
      • 您可以在您的主要活动中添加一个方法来设置和获取数据,例如 setData(Data) …getData() 并通过将 getActivity 转换为您的主要活动来在您的片段中调用它。它看起来像 MainActivity m = (MainActivity)getActivity();然后 m.setData() 和 m.getData() 试试看,让我知道会发生什么。
      【解决方案3】:

      您应该在 onResumer() 中更新您的片段数据,例如 TextViewEditText ...等。参见示例:

      Oncreate....
      TextView mtextview = rootview.findViewById....
      
      @Override
      public void onResume() {
          if(do some thing){
              mtextview.setText("It did something");
          }
          super.onResume();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多