FragmentStatePagerAdapter和ViewPager:Fragments实例化乱序

时间:2015-05-23 14:16:30

标签: android android-fragments

我正在尝试将FragmentStatePagerAdapter与ViewPager一起使用来实现顺序幻灯片滚动视图(类似于大多数pdf阅读器)。但是,在运行代码时,会发生以下情况:

  1. 当活动变得可见时,第一页将使用不同的(第二)页面值进行实例化。但是,当滚动到其他页面然后返回到第1页时,页面将显示布局文件中的默认文本。
  2. 只有第二页和第二页到最后一页使用传递的值进行实例化(也可以使用其他页面中的值,而不是自己的值)。其余页面显示布局文件中的默认文本。
  3. 在调试时,我注意到当ViewPager.populate()调用ViewPager.addNewItem()时,index / currentItemNumber会发生变化。更奇怪的是,在TextView(片段布局的一部分)上调用了setText(),但文本不会从默认文本中更改。

    我错过了什么吗?

    以下是代码:

    MainActivity.java

    public class MainActivity extends ActionBarActivity implements View.OnClickListener {
    
    private ViewPager mPager;
    private Button mButtonFirst;
    private Button mButtonPrev;
    private Button mButtonGoTo;
    private Button mButtonNext;
    private Button mButtonLast;
    private TextView mPageCount;
    private EditText mPageNumber;
    private TextView mError;
    private int mNumScreens;
    private int mCurrScreen;
    private MyPagerAdapter mMyPagerAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setUpViews();
        setUpListeners();
        setUpPager();
    }
    
    private void setUpViews() {
        mPager = (ViewPager) findViewById(R.id.my_pager);
    
        // Get other view handles...
    
        mError = (TextView) findViewById(R.id.error_details);
    }
    
    
    private void setUpListeners() {
        // Set this class as click handler for all buttons
    }
    
    private void setUpPager() {
    
        String[] strings = new String[] {
                "1",
                "2",
                "3",
                "4",
                "5",
                "6"
            };
    
        // Success!
        // Set adapter and update views
        mMyPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), strings);
        mPager.setAdapter(mMyPagerAdapter);
        mNumScreens = strings.length;
        mPageCount.setText("/" + Integer.toString(mNumScreens));
        mCurrScreen = -1;
        GoToScreen(1);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
    
        // Handle options
    
        return super.onOptionsItemSelected(item);
    }
    
    @Override
    public void onClick(View v) {
        switch(v.getId()) {
            case R.id.button_first:
                GoToScreen(1);
                break;
            case R.id.button_prev:
                GoToScreen(mCurrScreen - 1);
                break;
            case R.id.button_goto:
            {
                int screen;
                boolean reset = false;
                try {
                    screen = Integer.parseInt(mPageNumber.getText().toString());
                    reset = !SetToScreen(screen);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                    reset = true;
                }
                if(reset) {
                    mPageNumber.setText(Integer.toString(mCurrScreen));
                }
            }
            break;
            case R.id.button_next:
                GoToScreen(mCurrScreen + 1);
                break;
            case R.id.button_last:
                GoToScreen(mNumScreens);
                break;
        }
    }
    
    private void GoToScreen(int screen) {
        if(SetToScreen(screen)) {
            mPageNumber.setText(Integer.toString(mCurrScreen));
        }
    }
    
    private boolean SetToScreen(int screen) {
    
        // Switch to a valid screen
        if(screen >= 1 && screen <= mNumScreens && mCurrScreen != screen) {
            mPager.setCurrentItem(screen - 1, false);
    
    
            // Handle button visibility
    
            // Update current screen
            mCurrScreen = screen;
    
            return true;
        }
    
        return false;
    }
    

    MyPagerAdapter.java

    public class MyPagerAdapter extends FragmentStatePagerAdapter {
    
    private final String[] mStrings;
    
    public MyPagerAdapter(FragmentManager fm, String[] strings) {
        super(fm);
        mStrings = strings;
    }
    
    @Override
    public int getCount() {
        return mStrings.length;
    }
    
    @Override
    public Fragment getItem(int position) {
        return ScreenFragment.newInstance(mStrings[position]);
    }
    }
    

    ScreenFragment.java

    public class ScreenFragment extends Fragment {
    private static final String ARG_SCREEN_STRING= "screen_string";
    
    private String mScreenInfo;
    private TextView mStatementLabel;
    
    
    public static ScreenFragment newInstance(String screenString) {
        ScreenFragment fragment = new ScreenFragment();
        Bundle args = new Bundle();
        args.putString(ARG_SCREEN_STRING, screenString);
        fragment.setArguments(args);
        return fragment;
    }
    
    public ScreenFragment() {
        // Required empty public constructor
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mScreenInfo = getArguments().getString(ARG_SCREEN_STRING);
        }
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_screen, container, false);
    }
    
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setUpViews();
        setUpFields();
    }
    
    private void setUpFields() {
        mStatementLabel.setText(mScreenInfo);
    }
    
    private void setUpViews() {
        mStatementLabel = (TextView) getActivity().findViewById(R.id.qnr_screen_statement);
    }
    
    }
    

1 个答案:

答案 0 :(得分:0)

当我从onActivityCreated()调用setUpViews()和setUpFields()到onCreateView()时,问题解决了,几乎没有任何修改。这就是新的onCreateView()的样子(我在这里移动了上述函数的内容)

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_screen, container, false);
    mStatementLabel = (TextView) v.findViewById(R.id.qnr_screen_statement);
    mStatementLabel.setText(mScreenInfo);
    return v;
}

我还没弄清楚为什么会导致这个问题。如果我找到任何东西,将会更新。