将所有布局包装在 CoordinatorLayout 中是一种好习惯吗?
Is it a good practice to wrap all layouts in CoordinatorLayout?
我正在考虑一种在我的应用程序中实现 Android Snackbars 的方法。基本上,我希望能够在应用程序的任何位置显示 Snackbar。
正如我发现的那样,android.support.design.widget.Snackbar
在 android.support.design.widget.CoordinatorLayout
中表现最佳。否则,我无法将其滑开,它显示在导航抽屉上方并且不与浮动操作按钮交互。
所以问题是:在 CoordinatorLayout
中 包装我所有的布局 是一个好习惯,在 BaseActivity 中获取它的引用,以便它可以从几乎任何地方传递给 Snackbar?
这似乎是确保 Snackbar 和其他布局组件正确运行的可靠方法,但是......好吧,这意味着接触所有布局并拥有一个由所有其他 Activity 扩展并且可以从中访问的 BaseActivity任何想要显示 Snackbar 的片段。
有没有更好的方法?
这些是您的选择。在项目中根据需要使用其中之一。
最好的方法
最好的方法就是您在问题中已经说过的,添加一个 BaseActivity
并从中扩展您的所有活动。根据CoordinatorLayout
的official documentation,
CoordinatorLayout
is intended for two primary use cases:
- As a top-level application decor or chrome layout
- As a container for a specific interaction with one or more child views
所以CoordinatorLayout
主要是出于这个原因创建的(尽管也有other原因)。文档中提到的性能问题最少。
通过使用 FrameLayout
正如 Rainmaker 已经回答的那样,您可以使用 Activity 并引用布局文件夹中的 CoordinatorLayout
布局,子项将成为框架布局。
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/activity_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
那么您将只使用一个 activity 和 setContentView(R.layout.root_coordinate_layout)
。然后,您将所有其他活动转换为片段并添加它们:
MyFragment myf = new MyFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction()
.add(R.id.your_layout, myf)
.commit();
编程方式
这是做同样事情的另一种方法。但这有点复杂,需要做很多工作。
在你所有的 activity 中,而不是 setContentView(R.id.your_layout)
,使用这个:
LayoutInflater inflater = LayoutInflater.from(this);
ConstraintLayout yourLayout = (ConstraintLayout) inflater.inflate(R.layout.your_layout, null, false);
CoordinatorLayout layout = new CoordinatorLayout(this);
// Set its property as you wish ...
layout.addView(mainScreen);
setContentView(layout);
我在应用程序的任何地方实现了与打开 Snackbar
相同的功能。
我创建了一种常用方法,只需传递我需要显示的上下文和字符串消息,无需传递任何视图。查看我的代码片段。
public static void showSnackBar(Activity context, String msg) {
Snackbar.make(context.getWindow().getDecorView().findViewById(android.R.id.content), msg, Snackbar.LENGTH_LONG).show();
}
使用它,您每次都会将 Snackbar
放在底部。
是的,您可以将您的布局包装成协调器布局,例如
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Button
android:id="@+id/btnSimpleSnackbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="Simple Snackbar" />
<Button
android:id="@+id/btnActionCallback"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="With Action Callback" />
<Button
android:id="@+id/btnCustomSnackbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Custom Color" />
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
我正在考虑一种在我的应用程序中实现 Android Snackbars 的方法。基本上,我希望能够在应用程序的任何位置显示 Snackbar。
正如我发现的那样,android.support.design.widget.Snackbar
在 android.support.design.widget.CoordinatorLayout
中表现最佳。否则,我无法将其滑开,它显示在导航抽屉上方并且不与浮动操作按钮交互。
所以问题是:在 CoordinatorLayout
中 包装我所有的布局 是一个好习惯,在 BaseActivity 中获取它的引用,以便它可以从几乎任何地方传递给 Snackbar?
这似乎是确保 Snackbar 和其他布局组件正确运行的可靠方法,但是......好吧,这意味着接触所有布局并拥有一个由所有其他 Activity 扩展并且可以从中访问的 BaseActivity任何想要显示 Snackbar 的片段。
有没有更好的方法?
这些是您的选择。在项目中根据需要使用其中之一。
最好的方法
最好的方法就是您在问题中已经说过的,添加一个 BaseActivity
并从中扩展您的所有活动。根据CoordinatorLayout
的official documentation,
CoordinatorLayout
is intended for two primary use cases:
- As a top-level application decor or chrome layout
- As a container for a specific interaction with one or more child views
所以CoordinatorLayout
主要是出于这个原因创建的(尽管也有other原因)。文档中提到的性能问题最少。
通过使用 FrameLayout
正如 Rainmaker 已经回答的那样,您可以使用 Activity 并引用布局文件夹中的 CoordinatorLayout
布局,子项将成为框架布局。
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/activity_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
那么您将只使用一个 activity 和 setContentView(R.layout.root_coordinate_layout)
。然后,您将所有其他活动转换为片段并添加它们:
MyFragment myf = new MyFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction()
.add(R.id.your_layout, myf)
.commit();
编程方式
这是做同样事情的另一种方法。但这有点复杂,需要做很多工作。
在你所有的 activity 中,而不是 setContentView(R.id.your_layout)
,使用这个:
LayoutInflater inflater = LayoutInflater.from(this);
ConstraintLayout yourLayout = (ConstraintLayout) inflater.inflate(R.layout.your_layout, null, false);
CoordinatorLayout layout = new CoordinatorLayout(this);
// Set its property as you wish ...
layout.addView(mainScreen);
setContentView(layout);
我在应用程序的任何地方实现了与打开 Snackbar
相同的功能。
我创建了一种常用方法,只需传递我需要显示的上下文和字符串消息,无需传递任何视图。查看我的代码片段。
public static void showSnackBar(Activity context, String msg) {
Snackbar.make(context.getWindow().getDecorView().findViewById(android.R.id.content), msg, Snackbar.LENGTH_LONG).show();
}
使用它,您每次都会将 Snackbar
放在底部。
是的,您可以将您的布局包装成协调器布局,例如
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Button
android:id="@+id/btnSimpleSnackbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="Simple Snackbar" />
<Button
android:id="@+id/btnActionCallback"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="With Action Callback" />
<Button
android:id="@+id/btnCustomSnackbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Custom Color" />
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>