问题
I am using material design tabs as follows :
Following is my MainActivity.class :
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
private TabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = (TabLayout) findViewById(R.id.tabs);
viewPager = (ViewPager) findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
System.out.println("onPageSelected Called");
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
My ViewPagerAdapter is as follows :
public class ViewPagerAdapter extends FragmentPagerAdapter {
private static int count = 2;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
}
return null;
}
@Override
public int getCount() {
return count;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position)
{
case 0 :
return "Tab One";
case 1 :
return "Tab Two";
}
return null;
}
}
and here are my Fragments :
This is my first fragment name is FragmentOne :
public class FragmentOne extends Fragment {
private EditText editText;
private Button btnSendData;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT ONE");
View view = inflater.inflate(R.layout.fragment_one,container,false);
editText = (EditText) view.findViewById(R.id.et_name);
btnSendData = (Button) view.findViewById(R.id.btn_send);
btnSendData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putString("username",editText.getText().toString());
fragment.setArguments(bundle);
getFragmentManager.beginTransaction.replace(R.id.frag_second,fragment).commit();
}
});
return view;
}
}
and here is another fragment with name FragmentTwo :
public class FragmentTwo extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT TWO");
View view = inflater.inflate(R.layout.fragment_two,container,false);
Bundle bundle = getArguments();
if(bundle!= null)
{
String value = getArguments().getString("username");
}
return view;
}
@Override
public void onResume() {
super.onResume();
System.out.println("onResume gets called");
}
}
In the second fragment i am getting data buts its adding another view with previous one. see the image :
so I want to pass data from FragmentOne to FragmentTwo in two scenario :
1. I want to pass the data when i click on button and
2. When I swipe to FragmentTwo data should be passed
Also when I try to swipe to FragmentTwo nothing gets called in FragmentTwo ? why is it so ? Also when I click to second tab nothing gets called . Please help me how should i pass data to FragmentTwo on button click ?
following are layout files: here is fragment_one
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<EditText
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="@+id/et_name"
android:hint="Username"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:padding="16dp"
android:text="Send Data"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:id="@+id/btn_send"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
and second fragment , fragment_second.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/second_frag"
android:gravity="center">
<TextView
android:textSize="24sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Fragment Two"
android:id="@+id/textView2" />
回答1:
Each fragment is associated with the parent activity. so you can't directly communicate from one fragment to another fragment. You will need to go through Parent Activity using interface.
Check this docs : https://developer.android.com/training/basics/fragments/communicating.html
On button click pass the value to methods in your custom interface and access those methods in second fragment.
when I try to swipe to FragmentTwo nothing gets called in FragmentTwo
For this you need to implement fragment life cycle - https://developer.android.com/reference/android/app/Fragment.html
UPDATE
Done with some modification in you code, just look at the foll. code -
Manifex.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
MainActivity.java
package com.app.onkar.tabdemo;
import android.support.v4.app.Fragment;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOne(), "ONE");
adapter.addFragment(new FragmentTwo(), "TWO");
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
System.out.println("onPageSelected Called");
}
@Override
public void onPageScrollStateChanged(int state) {
}
public static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
private static int count = 2;
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
}
return null;
}
@Override
public int getCount() {
return count;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Tab One";
case 1:
return "Tab Two";
}
return null;
}
}
}
FragmentOne.java
package com.app.onkar.tabdemo;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class FragmentOne extends Fragment {
private EditText editText;
private Button btnSendData;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT ONE");
View view = inflater.inflate(R.layout.fragment_one,container,false);
editText = (EditText) view.findViewById(R.id.et_name);
btnSendData = (Button) view.findViewById(R.id.btn_send);
btnSendData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putString("username",editText.getText().toString());
fragment.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.second_frag,fragment).commit();
}
});
return view;
}
}
FragmentTwo.java
package com.app.onkar.tabdemo;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentTwo extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("IN FRAGMENT TWO");
View view = inflater.inflate(R.layout.fragment_two,container,false);
TextView txt2 = (TextView) view.findViewById(R.id.textView2);
Bundle bundle = getArguments();
if(bundle!= null)
{
String value = getArguments().getString("username");
txt2.setText(value);
}
return view;
}
@Override
public void onResume() {
super.onResume();
System.out.println("onResume gets called");
}
}
No change in Layout files. Just try above code - it is working exactly as you want. Hope it will help!
SCREENS
回答2:
ViewPagerAdapter class
public class ViewPagerAdapter extends FragmentPagerAdapter {
private static int count = 2;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment fragmentone = new FragmentOne();
Bundle args = new Bundle();
args.putInt("code", 1);
fragmentone.setArguments(args);
return fragmentone;
break;
case 1:
Fragment fragmenttwo = new FragmentTwo();
Bundle args = new Bundle();
args.putInt("code", 2);
fragmenttwo.setArguments(args);
return fragmenttwo ;
break;
}
return null;
}
@Override
public int getCount() {
return count;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position)
{
case 0 :
return "Tab One";
case 1 :
return "Tab Two";
}
return null;
}
}
args is the bundle object, you can put String int and other values to use these values in fragment use below code in onCreateView method of Fragment.
int codeForthisFragment = getArguments().getInt("code");
for button click: FragmentTransaction ft = getFragmentManager().beginTransaction(); Fragment secondFragment = new FragmentTwo();
Bundle args = new Bundle();
args.putInt("code", 2);
secondFragment.setArguments(args);
ft.replace(R.id.content_frame, secondFragment);
ft.commit();
回答3:
In the second fragment i am getting data buts its adding another view with previous one. see the image
With reference to the answer by @Roy Miller(https://stackoverflow.com/users/5255021/roy-miller), you can solve it by doing the follwing changes:
In MainActivity.java ,replace the follwing switch:
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
}
return null;
}
With:
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return mFragmentList.get(0);
case 1:
return mFragmentList.get(1);
case 2:
return mFragmentList.get(2);
default:
return null;
}
}
And then, in FragmentOne.java
Replace this:
btnSendData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putString("username",editText.getText().toString());
fragment.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.second_frag,fragment).commit();
}
});
With:
btnSendData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*This one FragmentCollection is a Singleton class that contains list of fragments, set it during initialization itself(code is attached below this code)*/
FragmentCollection fragmentCollection=FragmentCollection.getInstance();
FragmentTwo fragment = (FragmentTwo) FragmentCollection.getmFragmentList().get(2); //getting the second fragment
fragment.setText(editText.getText().toString()); //add this method in fragment two
}
});
Now inside FragmentTwo.java Add the method:
public void updateTextView(String data){
Log.d("TabTwo","Update Text view");
TextView txt = (TextView)view.findViewById(R.id.textView2);
txt.setText(data);
}
At last, the singleton class i mentioned above:
public class FragmentCollection {
static FragmentCollection fragmentCollection=new FragmentCollection();
private final List<Fragment> mFragmentList = new ArrayList<>();
private FragmentCollection(){}
public static FragmentCollection getInstance(){
if(fragmentCollection!=null) {
return fragmentCollection;
}else {
return new FragmentCollection();
}
}
public void setmFragmentList(List<Fragment> mFragmentList){
this.mFragmentList.addAll(mFragmentList);
}
public List<Fragment> getmFragmentList(){
return mFragmentList;
}
}
The issue of getting older views overlapping is because of initializing the fragment again and again
like new FragmentTwo(); in more than one place.
So here we put it in a list and access it so only a single fragment is altered.
回答4:
I am not able to go to first fragment from Second fragment . I am using tab layout This is my code By clicking button from 2nd Fragment
Bundle bundle = new Bundle();
bundle.putString("uniqueList1", uniqueList.get(0));
bundle.putString("uniqueList2", uniqueList.get(1));
bundle.putString("kycUniquesNo", kycUniqueNum);
CustBasicFormFragement fragObj = new CustBasicFormFragement();
fragObj.setArguments(bundle);
In 1st Fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = DataBindingUtil.inflate(inflater, R.layout.cust_basic_form_fragment, container, false);
view = binding.getRoot();
if (getArguments() != null) {
string1 = getArguments().getString("uniqueList1");
string2 = getArguments().getString("uniqueList2");
kycUnique=getArguments().getString("kycUniquesNo");
System.out.print(string1);
System.out.print(string2);
System.out.print(kycUnique);
return view;
}
来源:https://stackoverflow.com/questions/37943474/pass-data-from-one-design-tab-to-another-tab