解释一下Android P中的刘海。如何使用Android Cutout?

2007年9月烧毁。 2017年9月,苹果将时尚重新流行,推出了iPhone X.我们的中国朋友毫不犹豫地从苹果复制了这种设计也就不足为奇了(尽管第一个迷你条纹仍然在Essential Phone中,但并没有起飞)。 但是,我们现在看到了什么? 华为P20,华硕Zenfone 5,一加6,摩托罗拉One Power,小米Redmi 6和其他或多或少的知名制造商已经生产或宣布了刘海手机。 三星和谷歌是这场争夺无框技术的争夺战的最后据点。 还是不行 据传言,谷歌Pixel 3 XL也将带有优雅的领口。 好吧,作为开发人员,我们只能为此剪裁优化其应用程序,以便用户可以继续舒适地使用它们。 我要求猫下提供详细信息。



首先,我们需要确定应用程序是否需要任何优化?
如果您有一个全屏应用程序或主题中包含windowActionBarOverlay = true ,则很可能需要它。

几乎所有应用程序都离一个屏幕很远,并且您可能不会注意到其中一个布局的布局。 特别是在应用程序具有大量遗留代码的情况下。 因此,您仍应浏览所有主屏幕并仔细检查。 让我们找出为此需要做的事情。

1.准备测试设备/仿真器


为了使用刘海测试您的应用程序,您需要(谢谢,加油!)AndroidP。当前,Android P Preview 5可用于以下设备(感谢Project Treble):
基本电话
Google Pixel 2;
Google Pixel 2 XL;
Google Pixel
Google Pixel XL
诺基亚7 plus;
一加6;
Oppo R15 Pro;
索尼Xperia XZ2;
体内X21UD;
Vivo X21;
小米Mi Mix 2S。

要在您的设备上安装Android P,只需转到此处 ,然后为您的设备单击“获取Beta”。 空中飞行或自己滚动-选择是您的。 网站上的说明附后。
但是,如果您不能或不想在设备上安装Android P,则没有人取消模拟器。 此处的设置说明。

2.以编程方式打开爆炸本身(如果没有硬件)


一切都很简单:转到系统->开发人员选项->模拟带有切口的显示。
有3种选项可供选择:
  • 转角
  • 双倍
  • 高大


它们看起来如下:
转角双倍高大

3.浏览主屏幕


当然,每个人的情况都会有所不同。 有人有简单的逻辑,有人没有。 我将给出一些示例,这些示例在我的应用程序中都具有经过布局的屏幕。
探索个人资料

现在让我们看看消除布局缺陷的方法是什么。

不提高compileSdkVersion

从20 API开始,出现了WindowInsets类,它是一个Rect对象,它描述屏幕的可访问部分和不可访问部分。 这些方法与它们一起出现在View中,可用于处理屏幕无法访问部分的坐标:

 WindowInsets dispatchApplyWindowInsets(WindowInsets); WindowInsets onApplyWindowInsets(WindowInsets); void requestApplyInsets(); void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener); 

有关如何使用它们的详细信息在这里

有两种使用这些方法的方法:
a)在布局或视图的布局中放置标记android:fitsSystemWindows="true"
b)从代码中执行:

 layout.setFitsSystemWindows(true); layout.requestApplyInsets(); 

已成为

将compileSdkVersion升级到版本28

在不久的将来,您将不得不切换到该版本,那么为什么不现在就为此做准备呢? 但是要小心,如果您的项目中有单元测试(我希望您有它们),那么JUnit软件包已经移开了。 在此说明如何连接。

那么,Android P现在为我们提供了哪些选择?

答:WindowManager.LayoutParams具有3个新标志:

如何申请?

 window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 

B.如果选项A不适合您,并且您需要考虑到不幸的保险开关的位置(例如,状态栏中会显示某些内容,例如Telegram中的连接消息),那么在这种情况下,新的DisplayCutout类将有所帮助。
考虑其方法:

有了他们,您已经可以做所有想像得到的事情。 是否要-在其代码中移动marginOnApplyWindowInsetsListener需要,请在OnApplyWindowInsetsListener处理它,并进行consumeDisplayCutout() 。 也许您需要更复杂的操作。 我将举一个简单的例子来说明爆炸。

 class SampleFragment() : Fragment() { private lateinit var root: ViewGroup override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.sample_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) root = view.findViewById(R.id.root) addArrowsToCutout() } private fun addArrowsToCutout() { // ,      attach  window,    null' val cutoutList = root.rootWindowInsets?.displayCutout?.boundingRects cutoutList?.forEach { addArrow(context!!.getDrawable(R.drawable.left), it.left.toFloat(), it.top + (it.bottom - it.top).toFloat() / 2, ::calculateLeftArrow) addArrow(context!!.getDrawable(R.drawable.right), it.right.toFloat(), it.top + (it.bottom - it.top).toFloat() / 2, ::calculateRightArrow) addArrow(context!!.getDrawable(R.drawable.top), it.left + (it.right - it.left).toFloat() / 2, it.top.toFloat(), ::calculateTopArrow) addArrow(context!!.getDrawable(R.drawable.bottom), it.left + (it.right - it.left).toFloat() / 2, it.bottom.toFloat(), ::calculateBottomArrow) } } private fun addArrow(arrowIcon: Drawable, x: Float, y: Float, calculation: (View, Float, Float) -> Unit) { val arrowView = ImageView(context) arrowView.setImageDrawable(arrowIcon) arrowView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) root.addView(arrowView) arrowView.post { calculation(arrowView, x, y) } } private fun calculateLeftArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width arrowView.y = y - arrowView.height / 2 } private fun calculateRightArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x arrowView.y = y - arrowView.height / 2 } private fun calculateTopArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width / 2 arrowView.y = y - arrowView.height } private fun calculateBottomArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width / 2 arrowView.y = y } } 

人像


转角双倍高大


风景


转角
双倍
高大

因此,如我们所见,边缘将给我们带来一些不便,并使我们做出额外的手势/额外的操作。 原则上,一切都解决了。 最主要的是要尽快消除布局缺陷,以便有足够的准备时间。 成功处理您的修改。 希望Google不会破坏其Play!

Source: https://habr.com/ru/post/zh-CN419109/


All Articles