Reputation: 329
I have one activity and two tabs in that activity Tab1 and Tab2. These are the two fragments. In my Tab1 have an EditText field and a Button field and Tab2 have only one TextView Field.I want to get the value in EditText field in the Tab1 in to TextView field in Tab2 when I click the button in the Tab1 and also get value when swipe Tab1 to Tab2. I also check many websites but did't get any solution. If anyone know it please help me.
MainActivity.java
package reubro.com.fragment;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
TabLayout tabLayout;
ViewPager viewPager;
Tab1 t2;
EditText ed1;
Tab1 t1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t1 = new Tab1();
ed1 = (EditText) findViewById(R.id.ed1);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tab);
viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab2"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
Pager pager = new Pager(getSupportFragmentManager(),tabLayout.getTabCount());
viewPager.setAdapter(pager);
tabLayout.setOnTabSelectedListener(this);
}
public void onTabSelected(TabLayout.Tab tab){
viewPager.setCurrentItem(tab.getPosition());
// ed1.setText(t1.ed.getText());
// Log.d("cccccc",ed1.getText().toString());
}
public void onTabUnselected(TabLayout.Tab tab) {
}
public void onTabReselected(TabLayout.Tab tab) {
}
}
Tab1.java
package reubro.com.fragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
/**
* Created by pc84 on 20/1/17.
*/
public class Tab1 extends Fragment {
Button b1;
EditText ed;
String val;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, final Bundle bundle){
View view = inflater.inflate(R.layout.tab1,viewGroup,false);
b1 = (Button) view.findViewById(R.id.btn1);
ed = (EditText) view.findViewById(R.id.ed1);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
val = ed.getText().toString().trim();
if(!(val.isEmpty())){
Log.d("inner",val);
Tab2 tab2 = new Tab2();
Bundle bundle = new Bundle();
bundle.putString("val",val);
tab2.setArguments(bundle);
Toast.makeText(getActivity(),"This is value: "+val,Toast.LENGTH_LONG).show();
}
}
});
return view;
}
}
Tab2.java
package reubro.com.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by pc84 on 20/1/17.
*/
public class Tab2 extends Fragment {
TextView tv;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle){
View view = inflater.inflate(R.layout.tab2,viewGroup,false);
tv = (TextView) view.findViewById(R.id.tv1);
Bundle bundle1 = this.getArguments();
if (bundle1 != null){
String val = bundle1.getString("val");
tv.setText(val);
Log.d("tttttt",val);
}
return view;
}
}
Pager.java
package reubro.com.fragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
/**
* Created by pc84 on 20/1/17.
*/
public class Pager extends FragmentStatePagerAdapter {
int tabCount;
public Pager(FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
Tab1 tab1 = new Tab1();
return tab1;
case 1:
Tab2 tab2 = new Tab2();
return tab2;
default:
return null;
}
}
@Override
public int getCount() {
return tabCount;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="@+id/tab"
/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ed1"
android:hint="Enter something"
android:layout_margin="20dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:id="@+id/btn1"
android:layout_below="@+id/ed1"
android:text="Send to Next Fragment"
android:textAllCaps="false"/>
</RelativeLayout>
tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Tab2"
android:gravity="center"/>
</RelativeLayout>
Upvotes: 1
Views: 5030
Reputation: 62519
if your willing to wait until the tab is resumed:
it can be done like this: in your main activity navigation host have a function like this:
fun moveToTabPosition(tabPosition: Int, bundle: Bundle?) {
myFragment?.arguments?.let { it.putAll(bundle) } ?: run { myfragment?.arguments = bundle }
binding.tablayout.setSelectedTab(tabPosition)
binding.yourViewPager.currentItem = tabPosition
}
then just call that with your new bundle updates.
important: in onResume of each tab fragment have a function called updateBundle() and parse the arguments you want again.
the key here is the the arguments have a method called putAll
UPDATE: I want to avoid putAll now ...i notice after Android N it cannot allow to add values to the arguments after the fragment is attached. During QA testing it passed but some users had this issue so had to remove this call.
i got an error on some devices of: java.lang.UnsupportedOperationException : ArrayMap is immutable
Now im in favor of a common interface to call to update the set the arguments data. it would take a bundle as param.
Upvotes: 0
Reputation: 53
Use ViewModel as a parent data sharing in the parent activity so you can use the same context as viewLifeCycleOwner so you can easily handle the data view and data
Upvotes: 1
Reputation: 518
I've encountered a similar scenario and came up with the following:
MainActivityViewModel
hold any data you may need, and set
it accordingly when the event you are interested in is triggered.MainActivityViewModel
.null
so it won't be
used again by mistake. You should also have a default behavior, for
when the tab comes up for other reasons, and that variable is null
.Honestly, I'm not sure if by doing this I've gone against some best practices or something, but it has proven useful, and doesn't feel too "hacky".
Upvotes: 0
Reputation: 53
You Can use Live Data object with View Model You can Implement it easily with new Android Architecture.
Doc : https://developer.android.com/topic/libraries/architecture/livedata
No need to EventBus Anymore and Interface for getting LiveData.
Upvotes: 0
Reputation: 1791
You try to use BroadcastReceiver.
In Tab1 : you send broadcast with data
In Tab2 : you get data from broadcast and set page index
Upvotes: 0
Reputation: 5709
You can place your data into a Singleton referenced both into Tab1 and Tab2.
A Singleton is a programming pattern that let you to use always the same and the only one instance of a class. This is an example:
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
Take a look here to have a more detailed description:
Upvotes: 3
Reputation: 1075
To pass data from one tab to another, you can either send a broadcast or if you don't want to broadcast then first pass it to activity through callback then from activity to tab2.
Upvotes: 0