在宽度为 600dp 及以上的设备中旋转片段
Rotate a fragment in devices with width 600dp and higher
我有一个应用程序,其中 BaseActivity
的屏幕旋转被锁定,它是清单中具有此代码的所有视图的父级:
android:configChanges="uiMode"
因此所有片段和活动都是垂直的,不能旋转。
我需要创建一个将绑定到此 activity 的片段,并且需要在宽度为 600dp 或更高的设备上旋转并以水平模式显示。当片段被销毁(或视图被销毁)时,事情需要按原样进行。 activity 和所有片段应垂直显示。
有办法实现吗?
编辑
这是我在片段中添加的代码,但片段变得滞后,最终显示黑屏。
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
requireActivity().window.setSoftInputMode(SOFT_INPUT_ADJUST_PAN)
return inflater.inflate(R.layout.my_fragment, container, false).apply {
post {
if (measuredWidth > 600) {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}
}
}
}
override fun onDestroyView() {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
如果我假设您正在使用 NavigationComponent
,您可以处理所有方向并检查 activity 本身的宽度。
我已经为普通设备和大型设备创建了布尔资源值。
values\bools.xml
这适用于常规设备
我们故意把它设置为false,因为我们知道宽度很小
<resources>
<bool name="isLarger">false</bool>
</resources>
values-sw600dp/bools.xml
这适用于较大的设备。您需要创建此文件。
我们将其设置为真,因为我们知道现在宽度很大
<resources>
<bool name="isLarger">true</bool>
</resources>
现在,在您的 activity 或片段中,当您执行此检查调用此资源时,如果应用程序在移动设备中 运行,它将 return 错误。如果是平板电脑或更大的设备,它将 return 为真。
有了 NavigationComponent
和 destinationListener
你可以处理这里的一切。
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.firstFragment -> {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
R.id.secondFragment -> {
if (resources.getBoolean(R.bool.isLarger)) {
// Screen is larger, change orientation here
} else {
// Screen is smaller, perform your action
}
}
}
}
如果您还没有使用 NavigationComponent
,您可以通过这种方式检查 fragment
onCreate()
。
class SecondFragment : Fragment() {
private var mTwoPane = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (resources.getBoolean(R.bool.isLarger)) {
mTwoPane = true;
}
if (mTwoPane) {
Toast.makeText(context, "Larger", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, "Smaller", Toast.LENGTH_SHORT).show()
}
}
}
就是这样。
我有一个应用程序,其中 BaseActivity
的屏幕旋转被锁定,它是清单中具有此代码的所有视图的父级:
android:configChanges="uiMode"
因此所有片段和活动都是垂直的,不能旋转。
我需要创建一个将绑定到此 activity 的片段,并且需要在宽度为 600dp 或更高的设备上旋转并以水平模式显示。当片段被销毁(或视图被销毁)时,事情需要按原样进行。 activity 和所有片段应垂直显示。
有办法实现吗?
编辑 这是我在片段中添加的代码,但片段变得滞后,最终显示黑屏。
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
requireActivity().window.setSoftInputMode(SOFT_INPUT_ADJUST_PAN)
return inflater.inflate(R.layout.my_fragment, container, false).apply {
post {
if (measuredWidth > 600) {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}
}
}
}
override fun onDestroyView() {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
如果我假设您正在使用 NavigationComponent
,您可以处理所有方向并检查 activity 本身的宽度。
我已经为普通设备和大型设备创建了布尔资源值。
values\bools.xml
这适用于常规设备
我们故意把它设置为false,因为我们知道宽度很小
<resources>
<bool name="isLarger">false</bool>
</resources>
values-sw600dp/bools.xml
这适用于较大的设备。您需要创建此文件。
我们将其设置为真,因为我们知道现在宽度很大
<resources>
<bool name="isLarger">true</bool>
</resources>
现在,在您的 activity 或片段中,当您执行此检查调用此资源时,如果应用程序在移动设备中 运行,它将 return 错误。如果是平板电脑或更大的设备,它将 return 为真。
有了 NavigationComponent
和 destinationListener
你可以处理这里的一切。
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.firstFragment -> {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
R.id.secondFragment -> {
if (resources.getBoolean(R.bool.isLarger)) {
// Screen is larger, change orientation here
} else {
// Screen is smaller, perform your action
}
}
}
}
如果您还没有使用 NavigationComponent
,您可以通过这种方式检查 fragment
onCreate()
。
class SecondFragment : Fragment() {
private var mTwoPane = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (resources.getBoolean(R.bool.isLarger)) {
mTwoPane = true;
}
if (mTwoPane) {
Toast.makeText(context, "Larger", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, "Smaller", Toast.LENGTH_SHORT).show()
}
}
}
就是这样。