我正在使用MainActivity构建一个应用程序,它扩展了FragmentActivity,并且有一个带有三个选项卡的ActionBar.在每个选项卡上,我想附加一个ParentFragment,它应该控制内部页面之间的滑动.结果应该是按下用户应该从ParentFragment的不同实例更改的选项卡,并且滑动他应该在每个ParentFragment内的TextViewFragments之间进行更改.
现在我可以完全切换三个选项卡,但问题是没有正确显示ParentFragment,它似乎甚至没有创建,因为我甚至看不到onCreate(),onCreateView()和onViewCreated()函数LogCat视图.
我认为问题在于自定义TabListener类及其功能,但我无法真正理解问题所在.我试图在很多网站上搜索,我已经查看了很多例子,但没有一个与相同的情况有关.
我错过了什么或我在这里做错了什么?
现在我可以完全切换三个选项卡,但问题是没有正确显示ParentFragment,它似乎甚至没有创建,因为我甚至看不到onCreate(),onCreateView()和onViewCreated()函数LogCat视图.
我认为问题在于自定义TabListener类及其功能,但我无法真正理解问题所在.我试图在很多网站上搜索,我已经查看了很多例子,但没有一个与相同的情况有关.
我错过了什么或我在这里做错了什么?
这是我的MainActivity:
import java.util.Random; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import com.viewpagerindicator.PageIndicator; public class MainActivity extends FragmentActivity { MyAdapter mAdapter; ViewPager mPager; PageIndicator mIndicator; private View mCustomView; private static final Random RANDOM = new Random(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set up the action bar. ActionBar.LayoutParams params = new ActionBar.LayoutParams( ActionBar.LayoutParams.MATCH_PARENT,ActionBar.LayoutParams.MATCH_PARENT,Gravity.CENTER); final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayUselogoEnabled(false); actionBar.setDisplayShowHomeEnabled(false); actionBar.addTab(actionBar .newTab() .setIcon(getIcon(0,true)) .setTabListener( new TabListener<ParentFragment>(this,"home",ParentFragment.class))); actionBar.addTab(actionBar .newTab() .setIcon(getIcon(1,false)) .setTabListener( new TabListener<ParentFragment>(this,"apps",ParentFragment.class))); actionBar.addTab(actionBar .newTab() .setIcon(getIcon(2,"settings",ParentFragment.class))); } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { } public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment mFragment; private final FragmentActivity mActivity; private final String mTag; private final Class<T> mClass; private final Bundle mArgs; private FragmentTransaction fft; public static final String TAG = TabListener.class.getSimpleName(); public TabListener(FragmentActivity activity,String tag,Class<T> clz) { this(activity,tag,clz,null); } public TabListener(FragmentActivity activity,Class<T> clz,Bundle args) { mActivity = activity; mTag = tag; mClass = clz; mArgs = args; mFragment = mActivity.getSupportFragmentManager() .findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.detach(mFragment); fft.commit(); } } public void onTabSelected(Tab tab,android.app.FragmentTransaction ft) { System.out.println(TAG + (" - ") + " -> mTag " + mTag + " selected!"); fft = mActivity.getSupportFragmentManager().beginTransaction(); if (mFragment == null) { mFragment = Fragment.instantiate(mActivity,mClass.getName()); fft.add(android.R.id.content,mFragment,mTag); } else { System.out.println(TAG + (" - ") + " -> Fragment con mTag = " + mTag + " trovato con tag!"); fft.attach(mFragment); fft.commit(); } } @Override public void onTabReselected(Tab tab,android.app.FragmentTransaction ft) { } @Override public void onTabUnselected(Tab tab,android.app.FragmentTransaction ft) { mFragment = mActivity.getSupportFragmentManager() .findFragmentByTag(mTag); System.out.println(TAG + (" - ") + " -> mTag " + mTag + " unselected!"); if (mFragment != null && !mFragment.isDetached()) { fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.detach(mFragment); fft.commit(); } } } public Drawable getIcon(int tabPosition,boolean selected) { switch (tabPosition) { case 0: return getResources().getDrawable(R.drawable.actionbar_home); case 1: return getResources().getDrawable(R.drawable.actionbar_apps); case 2: return getResources().getDrawable(R.drawable.actionbar_settings); } return null; } }
这是我的ParentFragment,它现在出现了android.support.v4.app.Fragment类:
import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.viewpagerindicator.IconPageIndicator; import com.viewpagerindicator.PageIndicator; public class ParentFragment extends Fragment { public static final String TAG = ParentFragment.class.getSimpleName(); MyAdapter fragmentAdapter; ViewPager mPager; PageIndicator mIndicator; public static ParentFragment newInstance() { System.out.println(TAG + " - newInstance()"); System.out.println(TAG + " - " + methodName()); ParentFragment fragment = new ParentFragment(); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { System.out.println(TAG + " - onCreate()"); System.out.println(TAG + " - " + methodName()); super.onCreate(savedInstanceState); setRetainInstance(true); } @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { System.out.println(TAG + " - onCreateView()"); System.out.println(TAG + " - " + methodName()); fragmentAdapter = new MyAdapter(getFragmentManager()); View view = inflater.inflate(R.layout.simple_icons,container,false); mPager = (ViewPager) view.findViewById(R.id.pager); mPager.setAdapter(fragmentAdapter); return view; } @Override public void onViewCreated(View view,Bundle savedInstanceState) { System.out.println(TAG + " - onViewCreated()" ); System.out.println(TAG + " - " + methodName()); super.onViewCreated(view,savedInstanceState); mIndicator = (IconPageIndicator) getActivity().findViewById(R.id.indicator); mIndicator.setViewPager(mPager); } }
这是MyAdapter类:
import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import com.viewpagerindicator.IconPagerAdapter; public class MyAdapter extends PagerAdapter { FragmentManager myFragmentMgr; private FragmentTransaction mCurTransaction; protected static final String[] CONTENT = new String[] { "This","Is","A","Test",}; protected static final int[] ICONS = new int[] { R.drawable.icon_page_indicator,R.drawable.icon_page_indicator,R.drawable.perm_group_calendar,R.drawable.perm_group_camera,R.drawable.perm_group_device_alarms,R.drawable.perm_group_location }; private int mCount = CONTENT.length; public MyAdapter(FragmentManager fm) { super(); myFragmentMgr = fm; } @Override public int getCount() { return 3; } @Override public Object instantiateItem(ViewGroup viewGroup,int position) { ParentFragment fragment = ParentFragment.newInstance(); return fragment; } @Override public void destroyItem(ViewGroup viewGroup,int position,Object obj) { if (mCurTransaction == null) { mCurTransaction = myFragmentMgr.beginTransaction(); } mCurTransaction.detach((Fragment)obj); } @Override public boolean isViewFromObject(View arg0,Object arg1) { return false; } public Fragment getItem(int position) { Bundle args = new Bundle(); args.putInt(TextViewFragment.POSITION_KEY,position); return TextViewFragment.newInstance(args); } @Override public CharSequence getPageTitle(int position) { return "Fragment # " + position; } public int getIconResId(int index) { return ICONS[index % ICONS.length]; } public void setCount(int count) { if (count > 0 && count <= 10) { mCount = count; notifyDataSetChanged(); } } }
最后一个TextViewFragment类:
import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; public class TextViewFragment extends Fragment { public static final String POSITION_KEY = "POSITION"; public static final String TITLE_KEY = "TITLE"; public static TextViewFragment newInstance(Bundle args) { TextViewFragment fragment = new TextViewFragment(); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater,Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_test,false); } @Override public void onViewCreated(View view,Bundle savedInstanceState) { super.onViewCreated(view,savedInstanceState); TextView textview = (TextView) view.findViewById(R.id.textViewPosition); final int position; if (getArguments() != null) { position = getArguments().getInt(POSITION_KEY); textview.setText(Integer.toString(position)); } else { position = 0; textview.setText("Child Fragment"); } textview.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(),"Clicked Position: " + position,Toast.LENGTH_LONG).show(); } }); } }
—–编辑:解决方案—–
由于“低声誉”,我无法回答我自己的问题,但我无论如何都要分享解决方案,以帮助其他人,并希望能够收回一些选票.
我终于找到了让事情适合我的方法,我希望这对于遇到同样问题的其他人都有帮助.
我怀疑,问题出在TabListener中.我的问题解决了用这段代码更改该部分:
public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment mFragment; private final FragmentActivity mActivity; private final String mTag; private final Class<T> mClass; private final Bundle mArgs; private FragmentTransaction fft; public TabListener(FragmentActivity activity,Class<T> clz) { this(activity,null); } public TabListener(FragmentActivity activity,Bundle args) { mActivity = activity; mTag = tag; mClass = clz; mArgs = args; System.out.println(TAG + " - " + methodName() + " - Constructor of TabListener -> mTag = " + mTag); // Check to see if we already have a fragment for this tab,probably // from a prevIoUsly saved state. If so,deactivate it,because our // initial state is that a tab isn't shown. mFragment = mActivity.getSupportFragmentManager() .findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.detach(mFragment); fft.commit(); mActivity.getSupportFragmentManager() .executePendingTransactions(); } } public void onTabSelected(Tab tab,android.app.FragmentTransaction ft) { Fragment tmp = mActivity.getSupportFragmentManager() .findFragmentByTag(mTag); fft = mActivity.getSupportFragmentManager().beginTransaction(); if (mFragment == null) { System.out.println(TAG + " - " + methodName() + " - add mFragment " + mTag); // If not,instantiate and add it to the activity mFragment = Fragment.instantiate(mActivity,mClass.getName()); fft.add(android.R.id.content,mTag); fft.commit(); mActivity.getSupportFragmentManager() .executePendingTransactions(); } else { System.out.println(TAG + " - " + methodName() + " - attach mFragment " + mTag); // If it exists,simply attach it in order to show it fft.attach(mFragment); fft.commit(); mActivity.getSupportFragmentManager() .executePendingTransactions(); } } @Override public void onTabReselected(Tab tab,android.app.FragmentTransaction ft) { System.out.println(TAG + " - " + methodName() + " - mFragment " + mTag); } @Override public void onTabUnselected(Tab tab,android.app.FragmentTransaction ft) { mFragment = mActivity.getSupportFragmentManager() .findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { System.out.println(TAG + " - " + methodName() + " - detach mFragment " + mTag); fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.detach(mFragment); fft.commit(); mActivity.getSupportFragmentManager() .executePendingTransactions(); } } public static final String TAG = TabListener.class.getSimpleName(); private static final int CLIENT_CODE_STACK_INDEX; static { // Finds out the index of "this code" in the returned stack trace - // funny but it differs in JDK 1.5 and 1.6 int i = 0; for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { i++; if (ste.getClassName().equals(TabListener.class.getName())) { break; } } CLIENT_CODE_STACK_INDEX = i; } public static String methodName() { if (Thread.currentThread().getStackTrace().length < CLIENT_CODE_STACK_INDEX) return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX] .getMethodName() + "()"; else return new String( "methodName() - stackTrace index is out of bound"); } }
根本区别在于以下行的每个commit()之后的添加:
mActivity.getSupportFragmentManager().executePendingTransactions();
这个问题的记录很少,可能只在特定条件下发生,但我希望这个解决方案可以节省一些时间给其他有同样问题的人!
解决方法
谢谢你的答案,我在支持库中遇到了同样的问题,当我试图在标签之间切换时,片段将叠加在彼此之上.解决方案中有几个未使用的变量,所以我清理了一下:
public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment mFragment; private final FragmentActivity mActivity; private final String mTag; private final Class<T> mClass; private FragmentTransaction fft; public TabListener(FragmentActivity activity,Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; // Check to see if we already have a fragment for this tab,probably // from a prevIoUsly saved state. If so,because our // initial state is that a tab isn't shown. mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.detach(mFragment); fft.commit(); mActivity.getSupportFragmentManager() .executePendingTransactions(); } } @Override public void onTabSelected(Tab tab,FragmentTransaction ft) { mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag); fft = mActivity.getSupportFragmentManager().beginTransaction(); if (mFragment == null) { // If not,instantiate and add it to the activity mFragment = Fragment.instantiate(mActivity,mClass.getName()); ft.add(R.id.content_view,mTag); //fft.add(android.R.id.content,mTag); fft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } else { // If it exists,simply attach it in order to show it fft.attach(mFragment); fft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } } @Override public void onTabReselected(Tab tab,FragmentTransaction ft) { } @Override public void onTabUnselected(Tab tab,FragmentTransaction ft) { mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.detach(mFragment); fft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } }
}