gpt4 book ai didi

android - 如何在不违反核心 OO 原则的情况下使用 Fragments?

转载 作者:太空狗 更新时间:2023-10-29 12:50:31 24 4
gpt4 key购买 nike

记录的 Android fragment 示例(FragmentBasicsNewsReader 违反了面向对象设计的核心原则。存在冗余条件来建立当前显示的 View 类型,将 FragmentActivity 与 View 紧密耦合类型和 fragment 类型。MainActivity 耦合到每个类(包括 XML):

enter image description here

有人可能会为作者找借口说他们试图“保持简单”,或者读者可能会感到困惑。如果这是 Intent ——我想读者可以接受;相反,它教导的是糟糕的编程实践,这将导致应用程序的可维护性降低。

如何实现 Fragments 以使 View 和 fragment 不与 FragmentActivity 紧密耦合?

最佳答案

从更简单的 FragmentBasics 开始demo, gut MainActivity 如下:

public class MainActivity extends FragmentActivity
implements OnHeadlineSelectedListener {
AbstractNewsView abstractNewsView;

@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
abstractNewsView = new AbstractNewsViewProvider(this).get();
abstractNewsView.onCreate(savedInstanceState);
}

@Override public void onArticleSelected(int position) {
abstractNewsView.onArticleSelected(position);
}
}

现在它的依赖图是这样的。您现在可以为不同的设备类型添加您想要的所有 news_articles View 变体,并且 MainActivity 不需要更改。

enter image description here

添加一个新类 AbstractNewsViewProvider,它的唯一职责是确定给定设备正在使用哪种类型的 View (单 Pane 或双 Pane )。如果您使用 Guice 或 RoboGuice 进行依赖项注入(inject),这将改为 Provider绑定(bind)模块中的方法。

public class AbstractNewsViewProvider {
private final FragmentActivity fragmentActivity;

public AbstractNewsViewProvider(FragmentActivity activity) {
this.fragmentActivity = activity;
}

public AbstractNewsView get() {
if (fragmentActivity.findViewById(R.id.fragment_container) != null) {
return new SinglePaneNewsView(fragmentActivity);
} else {
return new DoublePaneNewsView(fragmentActivity);
}
}
}

添加两个新类 SinglePaneNewsViewDoublePaneNewsView 来实现 AbstractNewsView,如下所示。这两个类负责在各自的 View 类型中设置初始 fragment 。他们还负责处理 fragment 之间的转换(如果有的话)。

interface AbstractNewsView extends OnHeadlineSelectedListener {
public void onCreate(Bundle savedInstanceState);
@Override public void onArticleSelected(int position);
}


public class SinglePaneNewsView implements AbstractNewsView {

private final FragmentActivity fragmentActivity;

public SinglePaneNewsView(FragmentActivity fragmentActivity) {
this.fragmentActivity = fragmentActivity;
}

@Override public void onCreate(Bundle savedInstanceState) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}

// Create an instance of ExampleFragment
HeadlinesFragment firstFragment = new HeadlinesFragment();

// In case this activity was started with special instructions from an
// Intent,
// pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(fragmentActivity.getIntent().getExtras());

// Add the fragment to the 'fragment_container' FrameLayout
fragmentActivity.getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}

@Override public void onArticleSelected(int position) {
// If the frag is not available, we're in the one-pane layout and must
// swap frags...

// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction =
fragmentActivity.getSupportFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment
// Add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();
}


public class DoublePaneNewsView implements AbstractNewsView {

private final FragmentActivity fragmentActivity;

public DoublePaneNewsView(FragmentActivity fragmentActivity) {
this.fragmentActivity = fragmentActivity;
}

@Override public void onCreate(Bundle savedInstanceState) {
}

@Override public void onArticleSelected(int position) {
((ArticleFragment) fragmentActivity.getSupportFragmentManager()
.findFragmentById(R.id.article_fragment)).updateArticleView(position);
}

}

您可以找到 complete source在谷歌代码上。

关于android - 如何在不违反核心 OO 原则的情况下使用 Fragments?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12554783/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com