在 Single Activity Architecture 中设置片段的横向方向

Set landscape orientation for fragment in Single Activity Architecture

如何在单个 Activity 架构 中实现仅一个 Fragment 的锁定屏幕方向(整个应用程序只有一个 Activity) ?

是否有比在每个 Fragment 中指定请求方向更好的解决方案? 我试图避免将 activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 放在每个不相关的 Fragment

如果是 activity,您可以在清单文件中仅指定 activity 标签。

万一 activity 中的片段意味着我猜你可以在下面的代码

getActivity().setRequestedOrientation(
            ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

in activity 即通过传递布尔值(如果为真 PORTRAIT 否则为 LANDSCAPE)编写一个方法,并从片段中调用它。我的意思是如果 activity 包含需要不同方向的不同片段。

Orientation 属性符合 activity,因此您可以仅为包含片段的 activity 声明方向,使其处于横向状态,其余活动将保持原样。

在您想要特定(在本例中为纵向)方向的片段中使用以下代码行。

getActivity().setRequestedOrientation(
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

如果你想在片段中有一个方向,即基于用户持有他的设备的方式,那么使用下面的代码行。

getActivity().setRequestedOrientation(
            ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
<activity
    android:name=".user_interface.activities.MainActivity"
    android:screenOrientation="landscape"
    android:theme="@style/MyMaterialTheme"/>

Landscape 模式下要分段的位置添加以下行:

     @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;
    }

如果您在片段中添加以上代码,那么所有片段都将以 Landscape 模式显示。但是你想要一个片段。所以在 Other Fragment 添加下面的代码

     @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;
        }

注意:无需在manifest.xml

中添加Orientation

我会扩展 Fragment 并为我的所有片段创建一个 BaseFragment。在这个基本片段中,我将使用 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);
        }
    }
}

对于特定的锁定片段,我将只使用 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);
        }
    }
}

您现在要做的唯一更改是让所有片段都扩展 BaseFragment 而不是 Fragment,但这对其他共享功能也有好处。


我对 Kotlin 不熟悉,但 Kotlin 代码可能是这样的:

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)
        }
    }
}

我有和你一样的场景,我从我的 Activity 调用我所有的片段。我可以通过哪种方式将代码放在一个地方。

    int id = item.getFragmentId();

    if (id == R.id.nav_camera) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
    // Here you can have your fragment calls
    getSupportFragmentManager().beginTransaction().replace(
           R.id.content_main,
           new YourFragmentForId(),
           NotificationFragment.class.getSimpleName())
          .commit();

我仍然认为这是最好的方法。

首先让我说 @madlymad 有正确的想法,如果你还没有,你应该创建一个 BaseFragment class。

但是,如果出于某种原因您不能或不想这样做,您可以改为在 FragmentonAttached()onCreate() 或 [= 中设置方向16=]

activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

然后在各自对应的 onDetached()onDestroy()onDestroyView()

中重置
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

这将确保您只会在正确的片段中获得不同的方向。