2014-11-24 63 views
0

我有兩個片段:FragmentA和FragmentB。 FragmentA有一個按鈕,FragmentB有一個ListView,它的適配器被設計爲使用自定義行。我想通過單擊FragmentA中的按鈕在FragmentB中添加一行到這個ListView。我已經研究了一些來自Google的文檔片段之間的通信,我寫了一些代碼,但我沒有成功。我試過在一個片段中都有按鈕和ListView。單擊按鈕時,我成功地使用了適配器的notifiyDataSetChanged()方法。 Hovewer,我不知道如何解決這個問題。如何通過單擊另一個片段中的按鈕將一行添加到一個片段中的ListView?

MainActiviy.java

public class MainActivity extends ActionBarActivity implements ActionBar.TabListener, FragmentA.ButtonClickListener{ 
    private static final int NUM_PAGES = 2; 
    private ViewPager mPager; 
    private PagerAdapter mPagerAdapter; 
    private ActionBar actionBar; 
    private String[] tabs = { "A", "B"};  
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mPager = (ViewPager) findViewById(R.id.pager); 
     mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager()); 
     mPager.setAdapter(mPagerAdapter); 
     // ViewPager's PageChangeListener. 
     mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageSelected(int position) { 
       actionBar.setSelectedNavigationItem(position); 
      }   
      @Override 
      public void onPageScrolled(int arg0, float arg1, int arg2) { 
      }   
      @Override 
      public void onPageScrollStateChanged(int arg0) { 
      } 
     });   
     // Retrieve actionbar and set some properties. 
     actionBar = getSupportActionBar(); 
     // actionBar.setHomeButtonEnabled(true); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     actionBar.setDisplayShowCustomEnabled(true); 
     actionBar.setDisplayShowTitleEnabled(true); 
     Fragment frag1 = new FragmentA(); 
     Fragment frag2 = new FragmentB(); 
     FragmentTransaction fragmentTransaction; 
     FragmentManager fragMgr = getSupportFragmentManager(); 
     fragmentTransaction = fragMgr.beginTransaction(); 
     fragmentTransaction.add(frag1, "frag1Tag"); 
     fragmentTransaction.add(frag2, "frag2Tag"); 
     fragmentTransaction.commit(); 
     for (String tab_name : tabs) { 
      actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this)); 
     } 
    } 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
    private class ViewPagerAdapter extends FragmentStatePagerAdapter { 
     public ViewPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 
     @Override 
     public Fragment getItem(int position) { 
      switch (position){ 
       case 0: 
        return new FragmentA(); 
       case 1: 
        return new FragmentB(); 
      } 
      return null; 
     } 
     @Override 
     public int getCount() { 
      return NUM_PAGES; 
     } 
    } 
    @Override 
    public void onButtonClicked() { // IMPLEMENTATION OF INTERFACE METHOD 
     FragmentB fragmentB = (FragmentB)getSupportFragmentManager().findFragmentByTag("frag2Tag"); 
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
     if (fragmentB != null) { 
      fragmentB.updateList(); 
     } else { 
      FragmentB newFragment = new FragmentB(); 
     } 
    }  
} 

FragmentA.java

public class FragmentA extends Fragment { 
    ButtonClickListener mCallback; 
    FragmentTransaction ft; 
    List<String> values = new ArrayList<String>(); 
    // Container Activity must implement this interface. 
    // INTERFACE DEFINATION. 
    public interface ButtonClickListener { 
     public void onButtonClicked(); 
    } 
    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity);   
     // This makes sure that the container activity has implemented 
     // the callback interface. If not, it throws an exception 
     try { 
      mCallback = (ButtonClickListener) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
       + " must implement OnHeadlineSelectedListener"); 
     } 
    } 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     ViewGroup vG = (ViewGroup)inflater.inflate(R.layout.fragment1_layout, container,false); 
     Button btn = (Button)vG.findViewById(R.id.button1); 
     btn.setOnClickListener(new View.OnClickListener() {   
      @Override 
      public void onClick(View v) {    
       mCallback.onButtonClicked(); 
      } 
     }); 
     return vG; 
    } 
} 

FragmentB.java

public class FragmentB extends Fragment { 
    List<String> values = new ArrayList<String>(); 
    List<String> valuesRefresh = new ArrayList<String>(); 
    ListView list; 
    MyListAdapter adapter; 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     values.add("asda"); 
     values.add("kasd"); 
     ViewGroup vG = (ViewGroup)inflater.inflate(R.layout.fragment2_layout, container,false); 
     list = (ListView)vG.findViewById(R.id.listView2); 
     adapter = new MyListAdapter(getActivity(),values); 
     list.setAdapter(adapter); 
     return vG; 
    } 
    public void updateList(){  
     adapter.notifyDataSetChanged(); 
    } 
    public static class MyListAdapter extends ArrayAdapter<String>{  
     private final Context context; 
     private final List<String> values = new ArrayList<String>(); 
     public MyListAdapter(Context context, List<String> values) { 
      super(context, R.layout.list_item, values); 
      this.context = context; 
      for (int i=0; i<values.size(); i++) { 
       this.values.add(values.get(i)); 
      } 
     } 
     @Override 
     public long getItemId(int position) { 
      // TODO Auto-generated method stub 
      return 0; 
     } 
     public long getCount(int position) { 
      // TODO Auto-generated method stub 
      return values.size(); 
     } 
     @Override 
     public View getView(final int position, View convertView, ViewGroup parent) { 
      LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View list = inflater.inflate(R.layout.list_item,parent,false); 
      return list; 
     } 
    }   
} 

回答

1

你的問題是,你在你活動的onCreate創建您的片段,再你的尋呼機適配器,並再次在onButt onClicked(FragmentB)。你只應該創建一次。由於您在活動中完成了所有這些工作,因此最簡單的方法就是在活動字段中保留對碎片的引用。但是,您需要確保處理重新創建活動的情況,因爲在這種情況下,Android已經重新創建了您的片段,並且不需要再次創建和添加它們。

public class MainActivity extends ActionBarActivity implements ActionBar.TabListener, FragmentA.ButtonClickListener{ 
    private static final int NUM_PAGES = 2; 
    private ViewPager mPager; 
    private PagerAdapter mPagerAdapter; 
    private ActionBar actionBar; 
    private String[] tabs = { "A", "B"};  
    private Fragment frag1; 
    private Fragment frag2; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     // First check if Android has already created the fragments 
     FragmentManager fragMgr = getSupportFragmentManager(); 
     frag1 = fragMgr.findFragmentByTag("frag1Tag"); 
     frag2 = fragMgr.findFragmentByTag("frag2Tag"); 
     if (frag1 == null && frag2 == null) { 
      // Create and add fragments only if needed 
      frag1 = new FragmentA(); 
      frag2 = new FragmentB(); 
      FragmentTransaction fragmentTransaction = fragMgr.beginTransaction(); 
      fragmentTransaction.add(frag1, "frag1Tag"); 
      fragmentTransaction.add(frag2, "frag2Tag"); 
      fragmentTransaction.commit(); 
     } 
     mPager = (ViewPager) findViewById(R.id.pager); 
     ... 
    } 
    ... 
    private class ViewPagerAdapter extends FragmentStatePagerAdapter { 
     public ViewPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 
     @Override 
     public Fragment getItem(int position) { 
      switch (position){ 
       case 0: 
        return frag1; 
       case 1: 
        return frag2; 
      } 
      return null; 
     } 
     @Override 
     public int getCount() { 
      return NUM_PAGES; 
     } 
    } 
    @Override 
    public void onButtonClicked() { // IMPLEMENTATION OF INTERFACE METHOD 
     frag2.updateList(); 
    }  
}