передача данных в другой фрагмент с помощью swipe view с вкладкой android studio, а не кнопки

можно ли передавать данные от фрагмента к фрагменту с помощью салфетки?

есть много статей, которые учат нас, как передавать данные от фрагмента к фрагменту, но большинство статей или вопросов реализовали OnClickListener в своем первом фрагменте, который использовал для передачи значения другому фрагменту.

но мой случай-передать данные из двух фрагментов без нажатия кнопки и, наконец, сохранить их в разных таблицах, нажав кнопку в последнем фрагменте. Что? могу ли я это сделать??

поток Information >> WorkForce >>WorkDetailsTable и сохранить их в другой таблице одним нажатием кнопки.

Я попытался разобраться, но я получаю нулевое значение в SQLite. Я думаю, что пропустил много, но понятия не имею. Пожалуйста, помогите мне...Я застрял здесь больше двух лет. дни...Спасибо

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);



        }

рабочая сила.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 ответов


если я правильно понимаю вашу проблему, вы по существу реализуете что-то вроде "мастера", где каждый шаг передает информацию на следующий шаг, когда вы проводите между вкладками или выбираете их.

таким образом, на самом деле ваша проблема заключается в том, как получить информацию из фрагмента, когда он снят и во фрагмент, когда выбран.

на самом простом уровне я бы предложил, чтобы ваша деятельность содержит" мастер " копию всей информации и проходит он в/берет его из каждого фрагмента в вашем адаптере пейджера вкладки.

вам понадобится какой-то объект" домен " для хранения всей информации, которую вам нужно собрать. Каждая вкладка будет обновлять только те биты информации, о которых она заботится..

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

вы добавляете экземпляр этого, чтобы удерживать мастер-копию в действие "вкладка":

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

Я бы предложил простой интерфейс, который реализует каждый из ваших фрагментов "tab"; что-то например:

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).
}

тогда вам просто нужно добавить код для передачи данных назад и вперед.. в вашей" вкладке " активность, которая выглядит так...

@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);
}

важно отметить, что ваш TabPagerAdapter будет создавать новый фрагмент каждый раз, когда вы вызываете getItem().. это будет означать, что мы никогда не получим никаких обновлений, потому что каждый раз, когда мы пытаемся чтобы получить фрагмент, он возвращает новый пустой фрагмент. Нам нужно изменить это так, чтобы фрагменты все еще создавались по первому требованию, но только один раз, чтобы мы не выбрасывали свою работу.

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;
        }

надеюсь, что это помогает. Удачи :-)


хотя C James предоставляет хорошие советы для решения ваших проблем, я хотел бы представить другой способ без использования реализации интерфейсов. Пожалуйста, проверьте ниже ссылку. Если вы используете библиотеку шины событий, такуюhttp://square.github.io/otto/, Вы можете легко передавать данные, которые вы хотите поделиться между фрагментами и даже деятельности. Кроме того, вы можете уменьшить количество строк кода, так как для этого требуется только отправитель(публикация), получатель(подписчик) при реализации интерфейсов требуются дополнительные строки кода. Вот учебник Отто libarary. http://www.vogella.com/tutorials/JavaLibrary-EventBusOtto/article.html

надеюсь, что это помогает :)


Я бы больше пошел по шаблону наблюдателя. Каждый фрагмент изменяет POJO с каким-то образом отображается в ваших фрагментах. Вы просто должны наблюдать pojo в своих фрагментах. Изменение фрагментов будет уведомлять заинтересованных наблюдателей, не зная их.

Я считаю, что это гораздо более чистый способ реализовать это.

Фрагмент A - > PojoInstance.setXY ("foo"); Фрагмент A - > сообщает наблюдателям, что e.B сообщает фрагмент B:

фрагмент B увидит измените tru наблюдателя.

поскольку ViewPagers или другие компоненты будут кэшировать фрагменты, это способ получить информацию в уже созданных фрагментах, даже если их не видно.

вы также можете попробовать использовать EventBus, где вы передаете POJO.


для передачи данных из одного фрагмента в другой фрагмент при выполнении салфетки, во-первых, вы должны получить представление о каждом фрагменте.вот пример кода, который может помочь вам немного. напишите этот код в 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;
}}

во фрагментах добавьте getmyview (), который вернет представление этого фрагмента как:

public void getmyview()

{ return myview; / / myview-вид фрагмента, который вы вернете в метод oncreateview }

Примечание: Viewpager сначала выполнить onpagescroll и получить позицию 0,1 и при прокрутке, представления в позиции 1,2 будет выполняться и страница выбрана 0 будет выполняться. Для tabselections: Tabunselected, вкладка Tabselected reselected-это последовательность выполнения. так и пишите соответственно в соответствующих фрагментов. Надеюсь, это поможет вам.