Android Fragments 不更新

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

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

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

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

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

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

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) {

        }
    };
}

最佳答案

尝试在 fragment 对用户可见时更新 View ,如下所示:

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

关于Android Fragments 不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23072664/

相关文章:

Android ExoPlayer , VideoPlayer 中间的播放/暂停按钮

java - 无法解析 Fragment 中的 setText(java.lang.String) 方法

android - 在 viewpager fragment 内的 recyclerview 项目与 viewpager fragment 之间共享元素转换

java - Android:ViewPager仅显示第一个 fragment ,其他页面空白

android - FragmentStatePagerAdapter onPageSelected 事件

导致ANR的android服务

android - 如何通过其值获取字符串资源名称

java - Android和ObjectOutputStream到资源文件

android - 恢复具有相同 ID 的两个 View 的 fragment

java - 如何在 Android 的同一 Activity 中将日期从一个 fragment 传递到另一个 fragment ?