我相信大家在网上已经看到很多介绍Activity与Fragment数据交互的问题。但大家都看到都是在Activity.onCreate方法中加载数据,这是初始时加载数据,我相信大家对这个一定很熟悉。我今天讲的这种是Fragment已经加载完后,然后再重新向Fragment内的控件加载数据。
1、先说说适用场合:
比如我想制作一个销售订单的图表,但通常客户要求的不只一个图表,可能会要求LineChart,BarChart,PieChart等等显示出来。如果我们每个图表都用一个Activity,系统显得很复杂,因此,大家会选择用类似TabActivity的方式。但发现TabHost通常情况是放在布局文件的根目录,让其与LinearLayout放在同一级的条件下,我试了N次,就是不行。不知道我是哪里出错,还是怎么的,放在同级条件下怎么都显示不出来。没办法,只能用RadioButton+FragmentPagerAdapter+Fragment的方式解决。
2、FragmentPagerAdapter加载Fragment问题
通常情况下,如果多个Fragment同时放在一个Activity,我们可以通过findViewById(id)的方法找到对应的控件,然后赋值就可以更新Fragment内控件的内容。但如果是通过Adapter加载的多个Fragment,这种方法根本不灵。
经过多次试验,FragmentPagerAdapter加载的Pager,通常只有两个有效,下面以三个Fragment为例:
A:有三个Fragment1,Fragment2,Fragment3。Activity.onCreate启动时加载FragmentPagerAdapter进这三个Fragment,如果当前Page是Fragment1,那么只有Fragment1,Fragment2上的控件存在内存中,如果你取出第三个Fragment(Fragment3),然后读取其上的控件,那么出来的结果都是空,一定抛出异常。
B:当前的Page是Fragment2时,那么只有Fragment2,Fragment3有效,Fragment1内的控件读出来也是空。
C:当前的Page是Fragment3时,只有Fragment2,Fragment3有效,Fragment1内的控件读出来也是空。
结论:
1)当前的页(按Fragment加入ArrayList的顺序)有效时,只有当前页和其后一页内的控件在内存中,其他的Fragment内的控件都会着销毁。
2)当前的页(Fragment)为最后一页时,只有最后一页和倒数第二页内的控件存在内在中。
3、代码实现
三个Fragment,一个Adapter,三个RadioButton构建整个程序,然后更新里面TextView的内容,原代码实现如下:
1)fragment1.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvN1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="t1" />
</LinearLayout>
2)fragment2.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvN2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="t2" />
</LinearLayout>
3)fragment3.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvNM3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="t3" />
</LinearLayout>
5)Fragment2.java代码如下
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment2, null);
}
}
6)Fragment1.java代码如下
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment2, null);
}
}
7)Fragment3.java代码如下
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment3 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment3, null);
}
}
8)DemoFragmentPagerAdapter.java代码如下
import java.util.ArrayList;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class DemoFragmentPagerAdapter extends FragmentPagerAdapter {
private ArrayList items;
public DemoFragmentPagerAdapter(FragmentManager fm, ArrayList items) {
super(fm);
this.items = items;
}
@Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
switch(position)
{
case 0:
return (Fragment)items.get(position);
case 1:
return (Fragment)items.get(position);
case 2:
return (Fragment)items.get(position);
}
return (Fragment)items.get(position);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
}
9)MainActivity.java原码如下:
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.TextView;
public class MainActivity extends FragmentActivity implements OnPageChangeListener {
private ViewPager viewPager;
private RadioButton r1,r2,r3;
private Button btn1,btn2;
private FragmentManager fm;
private DemoFragmentPagerAdapter adapter;
private ArrayList items=new ArrayList();
private int currentPageIndex=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fm=this.getSupportFragmentManager();
//adapter=new DemoFragmentPagerAdapter(fm);
items.add(new Fragment1());
items.add(new Fragment2());
items.add(new Fragment3());
adapter=new DemoFragmentPagerAdapter(fm,items);
viewPager=(ViewPager)this.findViewById(R.id.viewPager);
r1=(RadioButton)this.findViewById(R.id.r1);
r2=(RadioButton)this.findViewById(R.id.r2);
r3=(RadioButton)this.findViewById(R.id.r3);
btn1=(Button)this.findViewById(R.id.btnN1);
btn2=(Button)this.findViewById(R.id.btnN2);
btn1.setOnClickListener(btnSendListener);
btn2.setOnClickListener(btnGetListener);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(this);
currentPageIndex=0;
r1.setOnClickListener(listener);
r2.setOnClickListener(listener);
r3.setOnClickListener(listener);
}
private OnClickListener btnGetListener=new OnClickListener(){
public void onClick(View v) {
Fragment1 frag1=(Fragment1)fm.findFragmentById(R.layout.fragment1);
TextView tv=(TextView)frag1.getActivity().findViewById(R.id.tvN1);
tv.setText("我的测试数据1");
Fragment2 frag2=(Fragment2)fm.findFragmentById(R.layout.fragment2);
TextView tv2=(TextView)frag2.getActivity().findViewById(R.id.tvN1);
tv.setText("我的测试数据2");
Fragment3 frag3=(Fragment3)fm.findFragmentById(R.layout.fragment3);
TextView tv3=(TextView)frag3.getActivity().findViewById(R.id.tvNM3);
tv.setText("我的测试数据2");
}};
private OnClickListener btnSendListener=new OnClickListener(){
public void onClick(View v) {
if(currentPageIndex==0)
{
FillCurrentOnePage();
}
if(currentPageIndex==1)
{
FillCurrentTwoPage();
}
if(currentPageIndex==2)
{
FillCurrentThreePage();
}
}};
private OnClickListener listener=new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.r1:
viewPager.setCurrentItem(0);
break;
case R.id.r2:
viewPager.setCurrentItem(1);
break;
case R.id.r3:
viewPager.setCurrentItem(2);
break;
}
}};
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int pageIndex) {
currentPageIndex=pageIndex;
switch(pageIndex)
{
case 0:
r1.setChecked(true);
FillCurrentOnePage();
break;
case 1:
r2.setChecked(true);
FillCurrentTwoPage();
break;
case 2:
r3.setChecked(true);
FillCurrentThreePage();
break;
}
}
private void FillCurrentOnePage()
{
Fragment1 frag1=(Fragment1)items.get(0);
TextView tv1=(TextView)frag1.getView().findViewById(R.id.tvN1);
tv1.setText("我的测试数据1");
}
private void FillCurrentTwoPage()
{
Fragment2 frag2=(Fragment2)items.get(1);
TextView tv2=(TextView)frag2.getView().findViewById(R.id.tvN2);
tv2.setText("我的测试数据2");
}
private void FillCurrentThreePage()
{
Fragment3 frag3=(Fragment3)items.get(2);
TextView tv3=(TextView)frag3.getView().findViewById(R.id.tvNM3);
tv3.setText("我的测试数据3");
}
}
OK了,大功告成!