通过使用选项卡android studio,而不是按钮的滑动视图将数据传递到另一个片段

时间:2015-10-07 02:53:42

标签: java android sqlite android-fragments

是否可以通过滑动将数据从片段传递到片段?

有许多文章教我们如何将数据从片段传递到片段,但大多数文章或问题都在第一个片段中实现了OnClickListener,用于将值传递给另一个片段。

但我的情况是从两个片段传递数据而没有任何按钮点击,最后通过单击最后一个片段中的按钮将它们保存在不同的表中。我能做些什么来实现这个目标?

流量为Information>> WorkForce>> WorkDetailsTable并通过单击按钮将其保存到不同的表格。

我试图解决它,但我在SQLite中得到NULL值。我想我错过了很多,但不知道。请帮助我...我已经被困在这里超过两天......谢谢

Tab.java

public class Tab extends ActionBarActivity implements ActionBar.TabListener {
    ViewPager Tab;
    TabPagerAdapter TabAdapter;
    ActionBar actionBar;
    public static String name = null;
    public static String subContractors = null;

// will be used for data communication 

    public static Force force_bean;;
    public static Info info_bean;


    public static Force getForce(){

        return force_bean;
    }
    public static void setForce(Force force){

        force_bean=force;
    }
    public static Info getInfo(){

        return info_bean;
    }
    public static void setInfo(Info info){

        info_bean=info;
    }



    final Activity mActivity = (Activity) this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab1);


        info_bean = new Info();
        force_bean = new Force();


        TabAdapter = new TabPagerAdapter(getSupportFragmentManager());


        Tab = (ViewPager) findViewById(R.id.pager);

        Tab.setOnPageChangeListener(
                new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {

                        actionBar = ((AppCompatActivity) mActivity).getSupportActionBar();
                        actionBar.setSelectedNavigationItem(position);
                    }
                });

        Tab.setAdapter(TabAdapter);

        actionBar = ((AppCompatActivity) mActivity).getSupportActionBar();

//Enable Tabs on Action Bar 
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);


//Add New Tabs 
        actionBar.addTab(actionBar.newTab().setText("Information").setTabListener(this));
        actionBar.addTab(actionBar.newTab().setText("Work Force").setTabListener(this));
        actionBar.addTab(actionBar.newTab().setText("Work Details").setTabListener(this));

    }


    @Override
    public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {

    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {

    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {

    }
}

TabPagerAdapter.java

public class TabPagerAdapter extends FragmentStatePagerAdapter {
        public TabPagerAdapter(FragmentManager fm) {
            super(fm);
        }
       @Override
        public Fragment getItem(int i) {
            switch (i) {
                case 0:
                    return  Information.newInstance("name");
                case 1:
                    return WorkForce.newInstance("SubCon");
                case 2:
                    return WorkDetailsTable.newInstance();
            }
            return null ;
        }
        @Override
        public int getCount() {
            return 3; //No of Tabs you can give your number of tabs
        }

Informmation.java

public class Information extends Fragment implements View.OnClickListener {
        private Spinner spinner, spinner2, spinner3;

        private static String a;
         public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            View info = inflater.inflate(R.layout.information, container, false);
            dialog = new DateDialog();
            spinner = (Spinner)info.findViewById(R.id.spinner);
            addItemsOnSpinner();
            a= spinner.getSelectedItem().toString();
            return info;
        }

     public static Information newInstance(String a)
        {
           Information fragment=new Information();
            Bundle bundle=new Bundle();
            bundle.putString("a",a);
            fragment.setArguments(bundle);
            return fragment;
        }

     public void addItemsOnSpinner() {
            List<String> list = new ArrayList<String>();
            list.add("1 ");
            list.add("2");
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, list);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);



        }

WorkForce.java

public class WorkForce extends Fragment {
        private static EditText txt1;
        private static String subCon;
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            View work = inflater.inflate(R.layout.workforce, container, false);
            txt1 = (EditText) work.findViewById(R.id.editText);
            subCon = txt1.getText().toString();
            return work;
        }

        public static WorkForce newInstance(String subCon) {

            WorkForce f = new WorkForce();
            Bundle bundle = new Bundle();
            bundle.putString("subCon", subCon);
            f.setArguments(bundle);
            return f;
        }
    }

WorkDetails.java

 private com.example.project.project.API.InfoAPI ts;
     private com.example.project.project.API.WorkDetailsAPI WD;
     private com.example.project.project.API.WorkForceAPI WF;
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     View workDetails = inflater.inflate(R.layout.tableworkdetails, container, false);
                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        spinnerTra = (Spinner) workDetails.findViewById(R.id.spinner6);
        addItemsOnSpinner();
        Button btn1 = (Button)workDetails.findViewById(R.id.button2);
        WD = new com.example.project.project.API.WorkDetailsAPI(getActivity());
        ts = new com.example.project.project.API.InfoAPI(getActivity());
        WF = new com.example.project.project.API.WorkForceAPI(getActivity());
        a1 = spinnerTra.getSelectedItem().toString();
        Bundle bundle = new Bundle();
        final String name = bundle.getString("a");
        final String subContractors = bundle.getString("subCon");
        btn1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {



                 add(name, subContractors);
                }
            });

            return workDetails;
        }

     public void  add(String name,String subContractors)
        {
            Toast.makeText(getActivity(),+name+subContractors, Toast.LENGTH_SHORT).show();
ts.insertTimeSheet(name);
WF.insertWorkForce(subContractors);

        }

注意:我的情况是从两个片段传递数据而不点击任何按钮,最后通过单击最后一个片段中的按钮将它们保存在不同的表中。

4 个答案:

答案 0 :(得分:9)

如果我理解你的问题,你实际上是在实施一些类似于&#34;向导&#34;当您在选项卡之间滑动或选择它们时,每个步骤将信息传递到下一步。

所以实际上你的问题是如何在取消选择片段时从片段中获取信息,并在选择时将片段输出到片段中。

在最简单的层面上,我建议您的活动包含&#34; master&#34;所有信息的副本,并将其传递到标签寻呼机适配器中的每个片段/从中获取。

你需要某种&#34; Domain&#34;反对收集您需要收集的所有信息。每个标签只会更新它关心的信息。

public class WorkData {
 string information;
 string subCon;
... etc..
}

您可以添加此实例以将主副本保存到&#34;标签&#34;活性:

public class Tab extends ActionBarActivity implements ActionBar.TabListener {
...
 WorkData workData = new WorkData();
...

然后,我会建议一个简单的界面,每个&#34;标签&#34;片段实现;类似的东西:

public interface DataUpdate {
 void setData(WorkData data);
 WorkData getData();
}

每个标签片段都会实现此界面,根据需要更新WorkData ..

public class WorkForce extends Fragment implements DataUpdate {
...
  private WorkData workData; // this fragment's "copy" of the data
...
@Override
public WorkData getData() {
  this.workData.subCon = this.subCon; // Assuming subcon has been updated.. else use txt1.getText();
  return this.workData;
}

@Override
public void setData(WorkData workData) {
 this.workData = workData;
 // Update this page's views with the workData...
 // This assumes the fragment has already been created and txt1 is set to a view
 txt1.setText(workData.subCon);
 this.subCon = workData.subCon; // Actually could just use subCon in workData, but be aware that workData actually points to the Activity's copy (kinda makes getdata redundant.. but I like symmetry and couldn't be bothered making lots of copies of the object).
}

然后你只需要添加代码就可以向前和向后传递数据..在你的&#34; Tab&#34;活动看起来像......

@Override
public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {
 int position = tab.getPosition();
 DataUpdate dataUpdate = (DataUpdate) TabAdapter.getItem(position);
 // Pass the master workdata to the selected fragment
 dataUpdate.setData(this.workData);
}

@Override
public void onTabUnselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {
 int position = tab.getPosition();
 DataUpdate dataUpdate = (DataUpdate) TabAdapter.getItem(position);
 // Update the master workdata from the unselected fragment
 this.workData = dataUpdate.getData();
}

@Override
public void onTabReselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {
 // This might be pointless, but we'll do it anyway..
 int position = tab.getPosition();
 DataUpdate dataUpdate = (DataUpdate) TabAdapter.getItem(position);
 // Pass the master workdata to the selected fragment
 dataUpdate.setData(this.workData);
}

这里需要注意的一点是,每次调用getItem()时,你的TabPagerAdapter都会创建一个新片段..这意味着我们永远不会得到任何更新,因为每次我们尝试获取片段时它都返回一个新的,空片段。我们需要对此进行更改,以便在首次要求时仍然创建片段,但只创建一次,以便我们不会丢弃我们的工作。

public class TabPagerAdapter extends FragmentStatePagerAdapter {
 private static final int NUMBER_OF_TABS = 3;
 private Fragment[] tabList = new Fragment[NUMBER_OF_TABS];

        public TabPagerAdapter(FragmentManager fm) {
            super(fm);
        }
       @Override
        public Fragment getItem(int i) {
            if (tabList[i] != null) {
              // Return a tab we created earlier..
              return tabList[i];
            } else {
              switch (i) {
                  case 0:
                      tabList[0] = Information.newInstance("name");
                      return  tabList[0];
                  case 1:
                      tabList[1] = WorkForce.newInstance("SubCon");
                      return tabList[1];
                  case 2:
                      tabList[2] = WorkDetailsTable.newInstance();
                      return tabList[2];
              }
            }
            return null ;
        }
        @Override
        public int getCount() {
            return NUMBER_OF_TABS;
        }

希望这会有所帮助。祝你好运: - )

答案 1 :(得分:2)

虽然C James提供了解决问题的好方法,但我想在不使用接口的情况下介绍另一种方法。请检查下面的链接。如果您使用事件总线库http://square.github.io/otto/,则可以轻松地在片段甚至活动之间传递要共享的数据。此外,您可以减少大量代码行,因为它只需要发送者(PUBLISHING),Receiver(订阅者),而接口的实现需要额外的代码行。 这是奥托图书馆的教程。 http://www.vogella.com/tutorials/JavaLibrary-EventBusOtto/article.html

希望有所帮助:)

答案 2 :(得分:2)

我会更多地采用观察者模式的方式。 每个片段都会以某种方式更改POJO,并在片段中呈现。你只需要观察片段中的pojo。更改碎片会在不知情的情况下通知感兴趣的观察者。

我相信这是一种更清洁的方式来实现这一点。

片段A - &gt; PojoInstance.setXY( “富”); 片段A - &gt;通知观察者e.b通知片段B:

片段B将看到更改为观察者。

因为ViewPagers或其他组件将缓存碎片,这是一种在已创建的碎片中获取信息的方法,即使它们未被看到也是如此。

您也可以尝试使用传递POJO的EventBus。

答案 3 :(得分:1)

要在执行滑动时将数据从一个片段传输到另一个片段,首先应该获取每个片段的视图。这样的示例代码可以帮助您解决一些问题。 在Activity:

中编写此代码
 mviewpager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    mviewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            adapter = ((SOFragmentPagerAdapter) mviewpager.getAdapter());

//getting the view of fragments at positions              


 if(position==0)
            {
                View v = null;
             Fragment1=(Fragment1)adapter.getFragment(position);
                v=fragment1.getMyView();//this is how you get the view
                ListView lv=(ListView)v.findViewById(R.id.lv_services);
                ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(SOListItemSelectedActivity.this,android.R.layout.simple_list_item_1,soRequestFragment.al_list_of_services);
                lv.setAdapter(arrayAdapter);
            }

            if(position==1)
            {


            }
        }

        @Override
        public void onPageSelected(int position) {
            if(position==0)
            {
                View v = null;
                soRequestFragment=(SORequestFragment)adapter.getFragment(position);
                v=soRequestFragment.getMyView();
            }
            if(position==1)
            {


            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mviewpager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

并创建一个FragmentPagerAdapter:

public class SOFragmentPagerAdapter extends FragmentPagerAdapter {
HashMap<Integer,Fragment> mPageReferenceMap;
int mNumOfTabs;
public SOFragmentPagerAdapter(FragmentManager fm,int mNumOfTabs) {
    super(fm);
    this.mNumOfTabs=mNumOfTabs;
    mPageReferenceMap=new HashMap<Integer,Fragment>();
}

@Override
public Fragment getItem(int position) {
      switch (position)
      {
          case 0:
              Fragment1 fragment1=new tFragment1();
              mPageReferenceMap.put(position,fragment1);
              return fragment1;

          case 1:
              Fragment2 fragment2=new Fragment2();
              mPageReferenceMap.put(position,fragment2);
              return fragment2;

          default:
              return null;
      }

}
public Fragment getFragment(int key) {
    return mPageReferenceMap.get(key);
}
@Override
public int getCount() {
    return 2;
}}

在Fragments中添加getmyview(),它将返回该片段的视图:

public void getmyview()

{ return myview; // myview是片段视图,你将在oncreateview方法中返回 }

注意:Viewpager首先执行onpagescroll并获取位置0,1,当您滚动时,将执行位置1,2的视图,并执行页面选择0。 对于tabselections:Tabunselected,重新选择Tabselected Tab是执行的顺序。 所以相应地写在片段的各个位置。 希望这会对你有所帮助。