更改方向后,片段中的getActivity为null(单窗格和单窗格布局)

时间:2015-07-10 09:56:02

标签: java android android-fragments

我有一个问题,我发现的解决方案对我不起作用(检查null等)。

我有一个简单的活动,它在横向模式下承载2个片段,在纵向模式下承载1个framelayout。当我更改设备的方向然后将其更改回来时,单击处理程序不起作用(DetailFragment中的getActivity()为null)。

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

//UserListActivity.java
public class UserListActivity extends AppCompatActivity implements UserListFragment.OnUserListSelectedListener {

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

        // Check whether the activity is using the layout version with
        // the fragment_container FrameLayout. If so, we must add the first fragment
        if (findViewById(R.id.fragment_container) != null) {

            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (savedInstanceState != null) {
                return;
            }

            UserListFragment fragment = new UserListFragment();

            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.add(R.id.fragment_container, fragment, "");
            fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            fragmentTransaction.commit();
        }
    }   

    @Override
    public void onUserListSelected(User selectedUser) {
        UserDetailFragment userDetailFragment = (UserDetailFragment) getSupportFragmentManager().findFragmentById(R.id.user_detail_fragment);

        if (userDetailFragment != null) {
            // If detail frag is available, we're in two-pane layout...

            userDetailFragment.updateSelectedView(selectedUser);
        } else {
            // Otherwise, we're in the one-pane layout and must swap frags...

            //create detailFragment
            UserDetailFragment newFragment = new UserDetailFragment();
            Bundle args = new Bundle();
            args.putString(UserDetailFragment.ARG_SELECTED_USER, new Gson().toJson(selectedUser));
            newFragment.setArguments(args);

            //replace fragment
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, newFragment, "");
            fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
        }
    }
}

//UserListFragment.java
public class UserListFragment extends ListFragment implements AdapterView.OnItemClickListener {    

    private OnUserListSelectedListener mCallback;
    private User[] users;   

    public interface OnUserListSelectedListener {
        void onUserListSelected(User selectedUser);
    }

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

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);        

        if (users == null) {
            getAllUsers();
        } else {
            setAdapter();
        }

        getListView().setOnItemClickListener(this);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnUserListSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnUserListSelectedListener");
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mCallback.onUserListSelected(users[position]);
    }

    private void setAdapter() {
        setListAdapter(new UserListAdapter(getActivity(), R.layout.user_list_row, users));
    }

    private void getAllUsers() {
        try {
            //...
            //Async webCall using volley
            //...
            users = tmp.getUsers().toArray(new User[tmp.getUsers().size()]);
            setAdapter();
            //...
    }
}

//UserDetailFragment.java
public class UserDetailFragment extends Fragment {
    final public static String ARG_SELECTED_USER = "selectedUser";
    private User mSelectedUser;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            mSelectedUser = new Gson().fromJson(savedInstanceState.getString(ARG_SELECTED_USER), User.class);
        }

        return inflater.inflate(R.layout.user_detail_fragment, container, false);
    }    

    @Override
    public void onStart() {
        super.onStart();
        Bundle args = getArguments();
        if (args != null) {
            updateSelectedView(new Gson().fromJson(args.getString(ARG_SELECTED_USER), User.class));
        } else {
            updateSelectedView(null);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString(ARG_SELECTED_USER, new Gson().toJson(mSelectedUser));
    }

    public void updateSelectedView(User selectedUser) {
        //??? WHY IS GETACTIVITY() AFTER CHANGE OF ORIENTATION NULL ???
        if (getActivity() != null) {
            TextView textUserName = (TextView) getActivity().findViewById(R.id.textUserName);
            TextView textUserEmail = (TextView) getActivity().findViewById(R.id.textUserEmail);

            if (selectedUser != null) {
                textUserName.setText(selectedUser.getName());
                textUserEmail.setText(selectedUser.getEmail());
                mSelectedUser = selectedUser;
            } else {
                textUserName.setText(null);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

UserDetailFragment userDetailFragment = (UserDetailFragment) getSupportFragmentManager().findFragmentById(R.id.user_detail_fragment);

创建片段的新实例。

 if (findViewById(R.id.fragment_container) != null) {

            // However, if we're being restored from a previous state, 
            // then we don't need to do anything and should return or else 
            // we could end up with overlapping fragments. 
            if (savedInstanceState != null) {
                return; 
            } 

            UserListFragment fragment = new UserListFragment();

            FragmentManager fragmentManager = getSupportFragmentManager(); 
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
            fragmentTransaction.add(R.id.fragment_container, fragment, "");
            fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
            fragmentTransaction.commit(); 
        } 

正在重用旧的片段实例。

因此,使用getFragmentByTag()并且在调用.add

时不要将标记保留为空字符串(&#34;&#34;)