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

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

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

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

Поток InformationWorkForceWorkDetailsTable и сохранит их в другой таблице одним нажатием кнопки.

Я попытался это обработать, но я получил значение NULL в 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);



        }

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

        }

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

Ответ 1

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

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

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

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

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

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

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

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

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

Каждый из ваших фрагментов вкладок реализует этот интерфейс, обновляя WorkData по мере необходимости.

public class WorkForce extends Fragment implements DataUpdate {
...
  private WorkData workData; // this fragment "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 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 copy (kinda makes getdata redundant.. but I like symmetry and couldn't be bothered making lots of copies of the object).
}

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

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

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

Ответ 2

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

Надеюсь, это поможет:)

Ответ 3

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

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

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

Фрагмент B увидит изменение Tru Observer.

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

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

Ответ 4

Чтобы перенести данные из одного фрагмента в другой фрагмент при выполнении салфетки, сначала вы должны получить представление о каждом фрагменте. Вот пример кода, который может немного помочь вам. напишите этот код в Управлении:

 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, будет выполнена. Для табуляции: Tabunselected, Tabselected Tab повторно выбран - последовательность выполнения. поэтому напишите соответствующим образом в соответствующих положениях фрагментов. Надеюсь, это поможет вам.