我正在尝试更新片段中的TextView,点击另一个片段上的按钮。
实际上我对Activity实现了回调函数,它确实有效,因为Logcat报告TextView中的文本已被更改。问题是第一个片段中显示的Textview没有更新为新值!这就像片段需要更新或者其他东西......
这是ActionBarTabsPager活动代码:
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>
修改
即使更改为0,ft.add()中的ContainerViewId也不会影响最终渲染。我猜这个渲染是由
管理的mTabsAdapter.addTab(tab1, FirstFragment.class);
mTabsAdapter.addTab(tab2, SecondFragment.class);
无论如何,这个问题仍然是一样的。
这是 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"
/>
答案 0 :(得分:4)
<强>解决!强>
在TabsAdapter中覆盖 instantiateItem(),并在FragmentTransaction中将ViewPager添加为ContainerViewID!
这是整个FragmentActivity的功能!
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);
Log.i("ONCREATE START","ONCREATE START");
setContentView(R.layout.actionbar_tabs_pager);
if (savedInstanceState == null) {
Fragment newFragment = new FirstFragment();
Fragment newFragment2 = new SecondFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.pager, newFragment, "FirstFragment");
ft.add(R.id.pager, newFragment2, "SecondFragment");
ft.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"));
}
Log.i("ONCREATE END","ONCREATE END");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
Log.i("onSaveInstanceState START","onSaveInstanceState START");
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar().getSelectedNavigationIndex());
Log.i("onSaveInstanceState END","onSaveInstanceState END");
}
/**
* 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>();
private FragmentTransaction mCurTransaction = null;
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) {
Log.i("addTab","addTab");
mTabs.add(clss.getName());
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Object instantiateItem(View container, int position) {
if (mCurTransaction == null) {
mCurTransaction = getSupportFragmentManager().beginTransaction();
}
// TODO Auto-generated method stub
Fragment fragment = getItem(position);
if (fragment!=null){
Log.i("Fragment Found!","Fragment Found! "+fragment.getTag());
mCurTransaction.attach(fragment);
}
return fragment;//super.instantiateItem(container, position);
}
@Override
public Fragment getItem(int position) {
Log.i("getItem","getItem");
if (position==0)
{Log.i("position=0","position=0");
return getSupportFragmentManager().findFragmentByTag("FirstFragment");}
else if (position==1)
{Log.i("position=1","position=1");
return getSupportFragmentManager().findFragmentByTag("SecondFragment");}
else return null;//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
}
}
感谢vbsteven!
答案 1 :(得分:2)
我认为你在屏幕上看到的碎片不是你手动添加标签的碎片&#34; FirstFragment&#34;和#34; SecondFragment&#34;而是由TabsAdapter的getItem方法添加的片段。
如果你看一下它的实现,就会实例化新的Fragments。
@Override
public Fragment getItem(int position) {
return Fragment.instantiate(mContext, mTabs.get(position), null);
}
这些新创建的片段将添加到FragmentManager中,并在FragmentPagerAdapter中生成自定义标签(TabsAdapter扩展)
答案 2 :(得分:0)
我的猜测是这是“重叠”片段的情况 - 对于第一次尝试片段的人来说并不罕见。每次重新显示片段(显示片段,显示片段,然后返回到您显示的第一个片段)时,您将在可见片段后面创建一个新片段。 “镜像片段”仍然位于顶部,阻止您查看其后面的片段。只有通过滚动该片段,您才会看到后面的片段确实会更新。
大多数情况下,你只是重复你在FragmentActivity中用XML做的事情。发布您的布局xml,以便片段专业人员可以更好地诊断您的问题。
答案 3 :(得分:0)
请发布actionbar_tabs_pager.xml。
不知道它是否解决了您的问题,但在您的代码的这一部分中,您为这两个片段添加了FirstFragment()...
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();
...你可以写得更简单:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.abs__custom, newFragment, "FirstFragment");
ft.add(R.id.abs__custom, newFragment2, "SecondFragment");
ft.commit();