I am trying to update a TextView in a Fragment clicking on a button on another Fragment.
Actually I implemented the callback function to the Activity and it does work, since the Logcat reports that the text in the TextView has been changed. The problem is the Textview shown in the first fragment is not updated to the new value! It's like the Fragment needs to be updated or something...
Here's the ActionBarTabsPager activity code:
import java.util.ArrayList;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentManager.OnBackStackChangedListener;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ActionBar.Tab;
import android.support.v4.app.SupportActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.TextView;
/**
* Demonstrates combining the action bar with a ViewPager to implement a tab UI
* that switches between tabs and also allows the user to perform horizontal
* flicks to move between the tabs.
*/
public class ActionBarTabsPager extends FragmentActivity implements SecondFragment.OnButtonClickedXListener{
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
FragmentManager fm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actionbar_tabs_pager);
if (savedInstanceState == null) {
Fragment newFragment = new FirstFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.abs__custom, newFragment, "FirstFragment").commit();
Fragment newFragment2 = new FirstFragment();
FragmentTransaction ft2 = getSupportFragmentManager().beginTransaction();
ft2.add(R.id.abs__custom, newFragment2, "SecondFragment").commit();
}
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = getSupportActionBar().newTab().setText("Fragment 1");
ActionBar.Tab tab2 = getSupportActionBar().newTab().setText("Fragment 2");
//ActionBar.Tab tab3 = getSupportActionBar().newTab().setText("Fragment 1");
//ActionBar.Tab tab4 = getSupportActionBar().newTab().setText("Fragment 2");
mViewPager = (ViewPager)findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
mTabsAdapter.addTab(tab1, FirstFragment.class);
mTabsAdapter.addTab(tab2, SecondFragment.class);//LoaderCursorSupport.CursorLoaderListFragment.class);
//mTabsAdapter.addTab(tab3, FirstFragment.class);//LoaderCustomSupport.AppListFragment.class);
//mTabsAdapter.addTab(tab4, SecondFragment.class);//LoaderThrottleSupport.ThrottledLoaderListFragment.class);
if (savedInstanceState != null) {
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt("index"));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar().getSelectedNavigationIndex());
}
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
*/
public class TabsAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
public TabsAdapter(FragmentActivity activity, ActionBar actionBar, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss) {
mTabs.add(clss.getName());
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
return Fragment.instantiate(mContext, mTabs.get(position), null);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
@Override
public void OnButtonClickedX(View v) {
if (v==findViewById(R.id.button1)){
Log.i("TRIGGERED","TRIGGERED");
FirstFragment ff = (FirstFragment) getSupportFragmentManager().findFragmentByTag("FirstFragment");
View root = ff.getView();
TextView tv = (TextView) root.findViewById(R.id.textView1);
Log.i("Text before Edit",""+tv.getText());
tv.setText("MODIFIED");
Log.i("Text after Edit",""+tv.getText());
}
// TODO Auto-generated method stub
}
}
FirstFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FirstFragment extends Fragment {
int mNum;
/**
* Create a new instance of FirstFragment, providing "num"
* as an argument.
*/
static FirstFragment newInstance(int num) {
FirstFragment f = new FirstFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.myfrag1, container, false);
return v;
}
}
SecondFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.SupportActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
public class SecondFragment extends Fragment {
int mNum;
OnButtonClickedXListener mListener;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static SecondFragment newInstance(int num) {
SecondFragment f = new SecondFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.myfrag2, container, false);
View button1 = v.findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.OnButtonClickedX(v);
// TODO Auto-generated method stub
}
});
return v;
}
public interface OnButtonClickedXListener{
public void OnButtonClickedX(View v);
}
@Override
public void onAttach(SupportActivity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
try {
mListener = (OnButtonClickedXListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnButtonClickedXListener");
}
}
}
myfrag1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="No String"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
myfrag2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Button" />
</LinearLayout>
EDIT:
Even changing to 0 the ContainerViewId in ft.add() doesn't impact at all in final rendering. SO I guess the rendering is managed by
mTabsAdapter.addTab(tab1, FirstFragment.class);
mTabsAdapter.addTab(tab2, SecondFragment.class);
The issue is still the same, anyway.
Here's actionbar_tabs_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>