Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set landscape orientation for fragment in Single Activity Architecture

How to achieve to lock screen orientation for only one Fragment in Single Activity Architecture (only one Activity for whole app)?

Is there better solution than specify requested orientation in each Fragment? I'm trying to avoid putting activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED to each unrelated Fragment

like image 870
Francis Avatar asked Aug 06 '18 14:08

Francis


People also ask

How do I open the fragment in landscape mode?

setRequestedOrientation(ActivityInfo. SCREEN_ORIENTATION_LANDSCAPE); The fragment does load in landscape mode.

How to set Fragment in activity in android?

Add a fragment to an activity You can add your fragment to the activity's view hierarchy either by defining the fragment in your activity's layout file or by defining a fragment container in your activity's layout file and then programmatically adding the fragment from within your activity.

Which layout is used to implement fragments?

A FrameLayout is used because it's going to be the container of the Fragment. In other words, the Fragment will be stored inside of this layout.


3 Answers

Let me start by saying that @madlymad has the right idea, and you should create a BaseFragment class if you haven't already.

However if for some reason you can't or don't want to, you can instead set the orientation in the Fragment's onAttached(), onCreate() or onCreateView()

activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

and then reset in their respective counterparts onDetached(), onDestroy() or onDestroyView()

activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

This will ensure that you only get different orientation in the correct fragment.

like image 125
Abbas Avatar answered Nov 11 '22 06:11

Abbas


Add below line where you want to fragment in Landscape Mode:

     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Inflate the layout for this fragment 
            //ADD BELOW LINE
            getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

            view = inflater.inflate(R.layout.fragment_dashboard, container, false);

       return view;
    }

If you add above code in fragment then all fragment are show in Landscape mode. But You want to a single fragment. so in Other Fragment add below code

     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            //ADD BELOW LINE
            getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

            view = inflater.inflate(R.layout.fragment_inventory, container, false);


            return view;
        }

Note: No need to add Orientation in manifest.xml

like image 37
Ali Avatar answered Nov 11 '22 04:11

Ali


I would extend the Fragment and create a BaseFragment for all my fragments. At this base fragment I would use the activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR

public abstract class BaseFragment extends Fragment {
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser) {
            Activity a = getActivity();
            if(a != null)
             a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
        }
    }
}

For the specific locked fragment I would just use the activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE.

public class LandscapeFragment extends BaseFragment {
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser) {
            Activity a = getActivity();
            if(a != null)
             a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
    }
}

The only change you would now have is to make all your fragments extend the BaseFragment instead of Fragment, but this can be beneficial in other shared features as well.


I am not familiar with Kotlin but Kotlin code may be like this:

abstract class BaseFragment : Fragment() {
  override fun setUserVisibleHint(isVisibleToUser : Boolean){
     super.setUserVisibleHint(isVisibleToUser)
     if(isVisibleToUser) {
       getActivity()?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR)    
     }
  }
}

class LandscapeFragment : BaseFragment() {
    override fun setUserVisibleHint(isVisibleToUser : Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if(isVisibleToUser) {
             getActivity()?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
        }
    }
}
like image 30
madlymad Avatar answered Nov 11 '22 04:11

madlymad