我有一个包含TextView
,EditText
和Button
的片段。我还有2个活动,包括其中一个活动的按钮fragment
和onClick
,另一个活动开始。通过intent
,text
中的edittext
成为另一个text
textview
的{{1}}。
我有两个可供选择的设计决定
考虑如果有100个此类活动会发生什么。第一种方法是让我们用自定义方法编写100个不同的片段类,但在第二种方法中,它是一个单独的类,并且活动在特别命名的方法中具有自定义逻辑。
因此我选择了第二种选择并且我意识到UI元素无法在activity
活动方法中实例化,因为片段的布局尚未膨胀。我正在onCreate
中进行实例化作为解决方法。
这是不好的做法,还是有更好的onStart
可供使用?
答案 0 :(得分:1)
建议的模式是创建一个holder接口,任何想要实例化你的片段的活动都必须实现。另外,要为新片段中的视图设置数据,请在片段上创建newInstance()
工厂方法。
我倾向于像这样接近它;
class FooFragment implements Fragment {
private static final String TEXT_FOR_TEXTVIEW = "textForTextView";
private FooFragmentHolder mHolder;
/*
* Rather than creating your fragment in your layout directly
* you should instead instantiate it using this class in your
* activity.
*/
public static FooFragment newInstance(String text) {
Bundle data = new Bundle();
data.putString(TEXT_FOR_TEXTVIEW, text);
FooFragment fooFragment = new FooFragment();
fooFragment.setArguments(data);
return fooFragment;
}
public interface FooFragmentHolder {
public void buttonPressed(String editTextContent);
}
/*
* When we create the fragment with the activity we use onAttach to get
* our holder implementation (the activity)
*/
@Override
public void onAttach(Activity activity) {
if (activity instanceof FooFragmentHolder) {
mHolder = (FooFragmentHolder) activity;
} else {
throw new IllegalStateException("Containing activity must implement FooFragmentHolder");
}
}
@Override
public void onCreateView(Inflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_foo, container, false);
final EditText editText = (EditText) view.findViewById(R.id.edit_text);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(Button button) {
mHolder.buttonPressed(editText.getText());
}
})};
TextView textView = (TextView) view.findViewById(R.id.text_view);
Bundle args = getArguments();
if (args != null) {
textView.setText(args.getString(TEXT_FOR_TEXTVIEW));
}
return view;
}
}
现在,在您的活动中,您只需要实现FooFragmentHolder接口并使用我们创建的newInstance
方法;
class FooActivity extends Activity implements FooFragment.FooFragmentHolder {
private static final String TEXT_FOR_TEXTVIEW = "textForTextView";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentLayout(R.layout.activity_foo);
// Instead of creating your fragment in your layout, create a holder
// layout and attach a new instance of your fragment using a fragment
// transaction.
FooFragment fooFragment = FooFragment.newInstance(getIntent().getStringExtra(TEXT_FOR_TEXTVIEW));
getFragmentManager().beginTransaction()
.replace(R.id.content, fooFragment)
.commit();
}
@Override
public void buttonPressed(String editTextContent) {
// In this case just starting the next FooActivity, but logic could be
// applied for any other activity.
Intent intent = new Intent(this, FooActivity.class)
.putExtra(TEXT_FOR_TEXTVIEW, editTextContent);
startActivity(intent);
}
}
答案 1 :(得分:0)
我决定以下面的模式解决 -
包含此片段的任何活动都应实现类似
的接口public interface ViewsCreatedListener {
public void onViewsCreated();
}
该活动看起来像
public class ExampleActivity extends Activity implements ViewsCreatedListener {
.
.
.
.
@Override
public void onViewsCreated() {
//Initiate the views here and do what gotta be done
}
}
该片段应检查包含此片段的任何活动是否应使用onAttach
方法和onActivityCreated
实现该接口,并通知活动
public class ExampleFragment extends Fragment {
ViewsCreatedListener listener = null;
.
.
.
.
@Override
public onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (ViewsCreatedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ViewsCreatedListener");
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listener.onViewsCreated();
}
}
这样做,片段只提供UI,包含活动决定应该通过片段包含的UI元素做什么。这最大化了可重用性.. DRY ...... :-D