在 Android 中使用 Fragment 而不是 View 有什么好处?
在针对 Android
进行开发时,您可以将目标(或最小)sdk 设置为 4 (API 1.6),并添加 android 兼容性包 (v4) 以添加对 Fragments
的支持。昨天,我做到了这一点,并成功实现了 Fragments
来可视化来自自定义类的数据。
我的问题是:与简单地从自定义对象获取视图相比,使用 Fragments 有什么好处,并且仍然支持 API 1.5?
例如,假设我有 Foo.java 类:
public class Foo extends Fragment {
/** Title of the Foo object*/
private String title;
/** A description of Foo */
private String message;
/** Create a new Foo
* @param title
* @param message */
public Foo(String title, String message) {
this.title = title;
this.message = message;
}//Foo
/** Retrieves the View to display (supports API 1.5. To use,
* remove 'extends Fragment' from the class statement, along with
* the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)})
* @param context Used for retrieving the inflater */
public View getView(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.foo, null);
TextView t = (TextView) v.findViewById(R.id.title);
t.setText(this.title);
TextView m = (TextView) v.findViewById(R.id.message);
m.setText(this.message);
return v;
}//getView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
View v = inflater.inflate(R.layout.foo, null);
TextView t = (TextView) v.findViewById(R.id.title);
t.setText(this.title);
TextView m = (TextView) v.findViewById(R.id.message);
m.setText(this.message);
return v;
}//onCreateView
}//Foo
这两种方法在 Activity 中创建和使用都非常简单,例如,有一个要显示的 List
(例如,以编程方式将每个添加到 ScrollView 中),那么 Fragments 真的那么有用吗,或者它们只是获取 View 的过度简化,例如通过上面的代码?
When developing for Android
, you can set your target (or minimum) sdk to 4 (API 1.6) and add the android compatibility package (v4) to add support for Fragments
. Yesterday I did this and successfully implemented Fragments
to visualize data from a custom class.
My question is this: what is the benefit for using Fragments
as opposed to simply getting a View from a custom object, and still supporting API 1.5?
For example, say I have the class Foo.java:
public class Foo extends Fragment {
/** Title of the Foo object*/
private String title;
/** A description of Foo */
private String message;
/** Create a new Foo
* @param title
* @param message */
public Foo(String title, String message) {
this.title = title;
this.message = message;
}//Foo
/** Retrieves the View to display (supports API 1.5. To use,
* remove 'extends Fragment' from the class statement, along with
* the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)})
* @param context Used for retrieving the inflater */
public View getView(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.foo, null);
TextView t = (TextView) v.findViewById(R.id.title);
t.setText(this.title);
TextView m = (TextView) v.findViewById(R.id.message);
m.setText(this.message);
return v;
}//getView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
View v = inflater.inflate(R.layout.foo, null);
TextView t = (TextView) v.findViewById(R.id.title);
t.setText(this.title);
TextView m = (TextView) v.findViewById(R.id.message);
m.setText(this.message);
return v;
}//onCreateView
}//Foo
Both methods are very simple to create and to work with in an Activity that, say, has a List<Foo>
to display (for example, programmatically adding each to a ScrollView
), so are Fragments
really all that useful, or are they just an over-glorified simplification of getting a View, such as through the code above?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 Fragment 的主要原因是为了后台堆栈和生命周期功能。否则,自定义视图更轻量且更容易实现。
起初,我实际上尝试使用自定义视图构建手机/平板电脑应用程序。一切似乎都可以在手机和平板电脑上运行,甚至可以从单面板切换到分屏面板。我遇到麻烦的地方是后退按钮和生命周期。由于我只是手动更新视图...没有任何东西可以跟踪视图的历史记录及其状态。因此,后退按钮无法按预期工作,并且在生命周期事件期间(例如旋转应用程序时)甚至很难重新创建最新状态。为了解决这个问题,我必须将自定义视图包装在片段中并使用 FragmentManager,以便保存并重新创建以前的状态。
在回答后我意识到我一年前发布了类似的问题: https://stackoverflow.com/ a/11126397/618881
The main reason to use Fragments are for the backstack and lifecycle features. Otherwise, custom views are more light weight and simpler to implement.
At first, I actually tried to build a phone/tablet app using custom views. Everything appeared to work across phones AND tablets, even switching from single panel to split panel. Where I ran into trouble was with the back button and life cycle. Since I was simply updating views manually...there was nothing keeping track of the history of views and their states. Therefore, the back button did not work as expected and it was difficult to recreate even the latest state during life cycle events, such as when rotating the app. To fix that, I had to wrap my custom views in fragments and use the FragmentManager so that the previous states would be saved and recreated.
I realized after answering that I posted to a similar question a year earlier: https://stackoverflow.com/a/11126397/618881
我想说片段在两种情况下很有用:如果您在某些设备/方向上拆分视图并在两个活动中显示它们,并在其他设备上的一个活动中显示所有内容。如果您使用平板电脑,甚至可能在手机上处于横向模式,这将是一个用例:例如,您在一个屏幕上显示项目列表和详细信息。在手机或纵向模式下,您只显示一部分。
另一个用例是可重用视图。因此,如果您有一些在不同活动中可见的视图,并且还执行一些操作,您可以将此行为放入片段中,然后重用它。显然,您也可以使用自定义小部件来做到这一点。
我认为没有任何理由为每个视图使用片段,我想这只是一种开销。我只在第一个用例中使用它们,我想说这是一种简化。
I'd say Fragments are useful in two scenarios: if you split up views on some devices/orientations and show them in two activities and show all the content in one on other devices. That would be a use case if you go on a tablet or maybe even in landscape mode on a phone: e.g. you show the list of items and the details on one screen. on a phone or in portrait mode you just show one part.
Another use case are reusable views. So if you have some views that are visible on different activities and also perform some actions you could put this behaviour into a fragment and then reuse it. Obviously you could probably do that with custom widgets too.
I wouldn't see any reason for using Fragments for every View and I guess it would just be an overhead. I'm only using them in the first use case and I'd say here it is a simplification.
在这里您可以阅读更多内容。
Here you can read more.
如果您有简单的应用程序,场景一是很好的。
如果您想要多个 Fragment 和多个 FragmentActivities,则场景二是不错的选择
你可以将其中每一个结合起来。您还可以在片段之间进行交互。
我有分屏 Fragmentactivity,我可以用“Intent Extras”来调用它,并告诉fragmentActivity 要加载哪个片段。片段很好,因为它们不在清单中,因此您可以制作可重用的片段和 FragmentActivity。
但它会让你的项目变得更大。但如果你做大型项目,你可以节省很多。因为您可以使用相同的片段或相同的片段活动。
我认为这些片段来得有点晚,所以你必须尝试以新的方式思考。
也许只是尝试将您的 Activity 转换为 FragmentActivity。稍后尝试找到可重用的代码并从中制作片段。
它很有用,但我现在不知道如何。但我有一些想法。
这始终是个问题。 Android 团队做了一些思考,但没有人知道什么是好的。因为我们很难像以前那样学习,而这里出现了一些新事物。
在我看来,这很好,但不是因为谷歌告诉我们的原因。
Scenario one is good if you have simple application.
Scenario two is good if you want to have Multiple Fragments and multiple FragmentActivities
and you can combine each of those. Also you can make interaction between fragments.
I have split screen Fragmentactivity i can call it with 'Intent Extras' and tell to fragmentActivity which fragment are to be loaded. Fragments are good because they are not in manifest so you could make reusable fragments and FragmentActvity.
But it make your project larger. But if you make large project you can save many. Because you can use same Fragments or same Fragment activity.
And i thing that this fragments come little late so you must try to think in new way.
Maybe just try to convert your activity to FragmentActivity. Later try to find reusable code and make Fragment from it.
Its usefull but i dont know how right now. But i have some ideas.
This is always problem. Android Team made somethink and nobody know what is good for. Because we are hardly learn like it was and here it comes some new things.
In my opinion it is good but not for reason that google tell us.
在 CustomView 上使用 Fragment 或 Activity 时添加一种情况:
当您使用 CursorLoader 观察某些视图、ListView 或 TextView 并希望在您的 ContentProvider 的数据在后端更新时更新其显示值(最常见的情况是您有一项服务可以更新您的内容)通过定期轮询远程数据库/云的数据来本地数据库)
Add one case when using Fragment or Activity over CustomView:
When you are using CursorLoader to observe certain views, ListView or TextView and want to update their display value whenever your ContentProvider's data updates at back end(most common case you have a service which updates your local database by polling data from remote database/cloud periodically)
上述所有评论都没有提到的一件大事是,即使 Android 终止 Activity 并在您执行诸如更改设备方向之类的操作时重新启动它,片段仍驻留在内存中。这样做是出于性能原因,但如果您期望片段被销毁,却发现它们突然被重新创建,也可能会导致意外结果。
One big thing all the above comments don't mention is that a fragment remains resident in memory even if Android kills the activity and restarts it when you do something like change the orientation of your device. This is done for performance reasons but can also lead to unexpected results if you were expecting fragments to be destroyed only to find that they are getting recreated out of nowhere.