一、从fragment中启动Activity
在讲解fragment argument前,我们先来看看使用一般的方法从fragment 中启动Activity并传递参数。
1.首先创建CrimeActivity类
当点击CrimeListFragment中的某一个列表项时,启动CrimeActivity,用以显示每一项的详细信息。CrimeActivity中有一个onCreateFragment方法,我们将用来创建CrimeFragment实例,CrimeFragment在笔记(一)中已经创建
public class CrimeActivity extends SingleFragmentActivity { @Override protected Fragment createFragment() { return new CrimeFragment(); } }
2.修改CrimeListFragment中的onListItemClick方法:
创建一个intent,并附加extra信息,点击后启动CrimeActivity
public void onListItemClick(ListView l, View v, int position, long id) { Crime crime= (Crime) getListAdapter().getItem(position); Intent intent=new Intent(getActivity(),CrimeActivity.class); intent.putExtra("extra_crimeId",crime.getUuid()); startActivity(intent); }
3.修改CrimeFragment类中的onCreate方法, 获取extra信息,修改onCreateView方法,更新视图
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); UUID id= (UUID) getActivity().getIntent().getSerializableExtra("extra_crimeId"); crime=CrimeLab.getInstance(getActivity()).getCrime(id); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment_crime,container,false); titleFiled= (TextView) view.findViewById(R.id.crime_title); titleFiled.setText(crime.getTitle()); //新增的 titleFiled.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { crime.setTitle(charSequence.toString()); } @Override public void afterTextChanged(Editable editable) { } }); dateButton= (Button) view.findViewById(R.id.crime_date); dateButton.setText(crime.getDate().toString()); dateButton.setEnabled(false); solvedCheckBox= (CheckBox) view.findViewById(R.id.crime_solved); solvedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean isSolved) { crime.setSolved(isSolved); } }); solvedCheckBox.setChecked(crime.isSolved());//新增的 return view; }
效果如图所示:
二、使用fragment argument 传递数据
通过以上方式,CrimeFragment需要的id存储在CrimeActivity 的intent里,他总是需要由某个具体的Activity托管着,CrimeFragment就不能用于别的Activity。而通过argument 的方式,就可以解决上述问题。fragment实例可附带一个Bundle对象,可以bundle对象存储信息,然后调用Fragment.setArguments(Bundle),argument附加给fragment。通过getArgument()方法可获取argument。
1.修改CrimeFragment类,新增newInstance方法,将信息封装在fragment实例中
//增加newInstance方法,该方法将信息存储在bundle中,用setArgument将参数附加给fragment实例。 public static CrimeFragment newInstance(UUID uuid){ Bundle bundle=new Bundle(); bundle.putSerializable("extra_crimeId",uuid); CrimeFragment fragment=new CrimeFragment(); fragment.setArguments(bundle); return fragment; }
2.修改CrimeActivity类的createFragment方法,调用CrimeFragment的静态方法newInstance创建实例
protected Fragment createFragment() { UUID uuid= (UUID) getIntent().getSerializableExtra("extra_crimeId"); return new CrimeFragment().newInstance(uuid); }
3.修改CrimeActivity类的onCreate方法,将获取数据的方式该为getArgument ()
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // UUID id= (UUID) getActivity().getIntent().getSerializableExtra("extra_crmeId"); UUID id= (UUID) getArguments().getSerializable("extra_crimeId"); crime=CrimeLab.getInstance(getActivity()).getCrime(id); }
4.在CrimeListFragment中重写onResume()方法刷新列表项
在CrimeFragment中的EditText控件设置了监听器,一旦改变就更新数据,但是点击回退后没有刷新显示,暂停的Activity的onStart()方法是不起作用的,在onResume()方法中更新代码是最安全的选择,重写后再修改EditText返回后发现数据以经更新
@Override public void onResume() { super.onResume(); ((CrimeAdapter)getListAdapter()).notifyDataSetChanged(); }
5.通过fragment获取返回结果(修改CrimeListFragment的onListItemClick方法,重写onActivityResult方法)
调用Fragment.startActivityForResult()方法启动另一个Activity,调用Fragment.onActivityResult()方法获取返回信息
@Override public void onListItemClick(ListView l, View v, int position, long id) { Crime crime= (Crime) getListAdapter().getItem(position); Intent intent=new Intent(getActivity(),CrimeActivity.class); intent.putExtra("extra_crimeId", crime.getUuid()); //用startActivityForResult 可以获取返回信息 startActivityForResult(intent, 1); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode==1){ //处理返回信息data } }
同时在CrimeFragment中也要有返回信息的方法
public void returnResult(){ //Fragment 本身没有setResult方法,因此要通知托管Activity返回结果值 getActivity().setResult(Activity.RESULT_OK,null); }