我不能保存片段的实例,以便在屏幕旋转后不重启

时间:2015-07-20 10:56:30

标签: android android-fragments rotation screen-orientation savestate

我的片段代码如下:

public class AllIssuesFragment extends Fragment {

@Bind(R.id.list_all_issues) ListView mListAllIssues;
IssuesGetter ai;
ArrayAdapter<IssuesResponse.Issue> adapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_all_issues, container, false);
    return view;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ButterKnife.bind(this, view);
    setRetainInstance(true);

    SharedPreferences user_data = this.getActivity().getSharedPreferences("user_data", Context.MODE_PRIVATE);
    UserManager.getInstance().setUsername(user_data.getString("username", null));
    UserManager.getInstance().setPassword(user_data.getString("password", null));

    if(UserManager.getInstance().getUsername() == null || UserManager.getInstance().getPassword() == null) {
        Intent intent = new Intent(getActivity(), ChangeUserActivity.class);
        startActivity(intent);
    }
    else {
        adapter  = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1);
        if(savedInstanceState == null) {
            getIssues(Constants.URI + Constants.ISSUES + Constants.OFFSET + 0);
        }
        mListAllIssues.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {

            }

            @Override
            public void onScroll(AbsListView absListView, int firstVisible, int visibleCount, int totalCount) {
                boolean loadMore = firstVisible + visibleCount >= totalCount;

                if (loadMore && ai.getStatus() == AsyncTask.Status.FINISHED) {
                    getIssues(Constants.URI + Constants.ISSUES + Constants.OFFSET + totalCount);
                    mListAllIssues.setSelection(totalCount);
                }
            }
        });
    }
}

private void getIssues(String url) {
    ai = new IssuesGetter(new AsyncCallback<IssuesResponse>() {
        @Override
        public void onSuccess(IssuesResponse response) {
            int index = mListAllIssues.getFirstVisiblePosition();
            View v = mListAllIssues.getChildAt(0);
            int top = (v == null)? 0 : v.getTop();

            adapter.addAll(response.getIssues());
            adapter.notifyDataSetChanged();
            mListAllIssues.setAdapter(adapter);
            mListAllIssues.setSelectionFromTop(index, top);
        }

        @Override
        public void onError() {
            Intent intent = new Intent(getActivity(), ChangeUserActivity.class);
            startActivity(intent);
        }
    });
    ai.execute(url);
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity {


@Bind(R.id.viewpager) ViewPager viewPager;
@Bind(R.id.tabs) PagerSlidingTabStrip tabStrip;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    viewPager.setAdapter(new MainActivityPagerAdapter(getSupportFragmentManager()));
    tabStrip.setViewPager(viewPager);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_change_user) {
        Intent intent = new Intent(this, ChangeUserActivity.class);
        this.startActivity(intent);
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

我尝试使用 setRetainInstance(true)并检查 savedInstanceState是否等于null ,但它没有解决我的问题。我卡住了:(

我的Asynctask使用回调返回结果。

1 个答案:

答案 0 :(得分:0)

我在这里看到了问题:

public void onCreate() {
    //..
    viewPager.setAdapter(new MainActivityPagerAdapter(getSupportFragmentManager()));
    tabStrip.setViewPager(viewPager);
}

每次重新创建活动时都会调用此方法。它的作用是创造新的适配器,创造全新的碎片。这是一个问题。因为您的活动不能控制片段的创建。为了保留碎片,这是必要的。

我建议你在onSaveInstanceState()回调中保存片段的状态,并在onCreateView()中恢复它。请注意,您不需要保存UI元素的状态只是片段类的变量。如果UI元素具有唯一ID,则会自动保存其状态。

编辑:

我的建议:

public class AllIssuesFragment extends Fragment {
    private List<String> issues;
    // ..

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // ..
        if (null != savedInstanceState) {
            issues = savedInstanceState.getStringArray("issues");
        } else {
            issues = new List<>();
        }
        adapter  = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, issues);
        // ..
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putStringArray("issues", issues);
    }

    private void getIssues(String url) {
        // ..
        ai = new IssuesGetter(new AsyncCallback<IssuesResponse>() {
            @Override
            public void onSuccess(IssuesResponse response) {
                // ..
                //adapter.addAll(response.getIssues());
                issues.addAll(response.getIssues());
                adapter.notifyDataSetChanged();
                // ..
            }
        };
        // ..
    }
}