Is it the correct way? : To change a view/layout of Fragment on click

What I ought to do is change the view/layout of Fragment without creating another class for fragment on click of a button.

For example I have an activity - ContactsActivity and I have a fragment - ContactsFragment.

The Standard way of using Fragments:


From ContactsActivity I call ContactsFragment by -

getFragmentManager().beginTransaction().replace(android.R.id.content, new ContactsFragment())
            .commit();

Code for setting View in ContactsFragment class -

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

**Now comes how I do what I want to do ** (Change the view of fragment)


I change only the view of ContactsFragment by doing a bad kind of hack.

I change the onCreateView() shown above to this -

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
        //Set the view to R.layout.contacts_primary
        rootView = inflater.inflate(R.layout.contacts_primary, container, false);

        //Set the view to R.layout.contacts_secondary
        if(getActivity().getIntent()!=null && getActivity().getIntent().getBooleanExtra("s", false)) {
            rootView = inflater.inflate(R.layout.contacts_secondary, container, false);
            Log.e(tag,getActivity().getIntent().getExtras().toString());
            return rootView;
        }

        //This is the onClickListener which again calls the ContactsActivity class,
        //this time with an Intent which I used above to change the view from 
        //R.layout.contacts_primary to R.layout.contacts_secondary
        Button button = (Button)rootView.findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(getActivity(), ContactsActivity.class).putExtra("s",true));
            }
        });

Now everything works as I want and flawlessly.

But I have a very strong feeling that either all of it is wrong and Fragments aren't supposed to work this way or I am using a hectic hack to achieve what can be done by few lines of code.

So please let me know what is it? And if there is a standard way of doing what I am trying to do.

Answers


For me passing additional argument on which base fragment decides wich layout to use seems totally ok. But there is cleaner way of doing what you want to achieve without starting another activity.

First of all pass argument to fragment by making standard static new instance method in fragment (we cannot pass this argument in constructor as android always recreates fragments using empty constructor). Something like this:

    public static ContactsFragment newInstance(boolan firstView) {
         ContactsFragment fragment = new ContactsFragment();
         Bundle args = new Bundle();
         args.putBoolean("yourArg", firstView);
         fragment.setArguments(args);
         return fragment;
    }

Every time you have to initiate your fragment do this with this method.

Then declare interface in your fragment to communicate with your activity. Like this

public interface NewViewListener {

    public void showNewView(boolen firstView);

}

Than make your activity implement it so your activity han a method where it can place new fragment in container view. In your fragments onAttach and onDetach methodsmake sure your activity implements this interface and hold reference to your activity in private NewViewListener field in your fragment. Like this:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (NewViewListener ) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement NewViewListener ");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

Then in on button click method call showNewView method on your activity with whatever argument you want indicating which view you want in new fragment instance. And in your activity method showNewVew fragment in the container. Like this:

@Override
public void showNewView(boolean firstView) {
   getFragmentManager().beginTransaction().replace(android.R.id.content,  ContactsFragment.newInstance(firstView)
        .commit();
}

In your fragments onCreateView you may get passed arguments and decide which view you want to use.


Need Your Help


About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.