采用的方式为:
回调机制 ,为多态的应用。父类调用子类的方法,极限就为接口,没有方法区,完全由子类提供,获得了大的自由。
类似行为:
接口告诉要干什么事情,具体的事情由其子类来实现。
eg.飞机起飞,控制台告诉飞机起飞,具体怎么起飞由飞行员来决定。
实现机制:(自己猜想。。)
在Fragment1 中调用 onMyClick.TransportValue(list.get(position))时,系统会在内存的方法区中找对应的方法,如果没有方法体,就会报空指针异常;
如果有该接口的实现类,则可以进行数据传输。
并且整个apk 相当于在一个大类中。此时在 Fragment2中重新加载了 Fragment1类,并实现了该接口方法,数据就会进行传输。
内存中存在 堆内存和方法区,在java加载类的时候,类中的方法 会在 堆内存中有引用,指向方法区中。
此时的状态为 Fragment1 onMyClick.TransportValue(list.get(position))为方法的引用,其指向Fragment2 的实现类为方法区中的方法。
应用:
在实际应用中,可以通过接口获得想要的数据,只要实现对方提供接口的方法,接口进行数据的传输。如同 Fragment2获取数据信息。
目前已知的fragment的数据传输方式有三种:
第二种
- 在活动内获取 fragment里面的控件信息,在活动中类似控件进行数据处理
需求:在同一个页面内,加载两个Fragment 视图,左边为listview ,右边为 textview ,点击左边listview 的条目,右边展示相关数据。
1.1 在src 中
1.1.1 Fragment1类
public class Fragment1 extends Fragment { private ArrayList<String> list; private OnMyClick onMyClick; /* * 加载视图 * 获取控件后,对控件进行赋值,数据传递定义接口,方便回调 */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment1, container, false); //找控件赋值 ListView fragment1_listview=(ListView) view.findViewById(R.id.fragment1_listview); //找数据源 list = new ArrayList<String>(); for (int i = 0; i < 20; i++) { list.add("数据"+i); } //配置适配器 fragment1_listview.setAdapter(new MyAdapter(list)); //设置条目点击事件 fragment1_listview.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //定义接口进行数据传输 onMyClick.TransportValue(list.get(position)); } } ); return view; } //定义接口 interface OnMyClick{ //定义接口方法 public void TransportValue(String value); } //定义外部访问的方法 public void setOnMyClick(OnMyClick onMyClick){ this.onMyClick=onMyClick; } class MyAdapter extends BaseAdapter { private ArrayList<String> list; public MyAdapter(ArrayList<String> list) { this.list = list; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv=new TextView(getActivity()); tv.setText(list.get(position)); return tv; } } }
1.1.2 Fragment2类
public class Fragment2 extends Fragment { private TextView fragment2_textview; /* * 加载视图 */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment2, container, false); //1.找控件 fragment2_textview = (TextView) view.findViewById(R.id.fragment2_textview); //2.给控件赋值 //通过接口接收数据 //找到同一个activity 中的fragment1 ,通过活动,找到事务管理器,找到碎片的id Fragment1 fragment1=(Fragment1) getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment1); //通过碎片1,设置接口 效果为当fragment1设置点击事件的时候,该方法被调用,且只能为碎片1进行操作。 fragment1.setOnMyClick(new OnMyClick() { @Override public void TransportValue(String value) { // TODO Auto-generated method stub fragment2_textview.setText(value); } }); return view; } }
1.1.3 在main_activity 类中实现
public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
1.2 在res->layout中定义xml
1.2.1 fragment1.xml