我得到了一个带有 SherlockActionbar 的动态布局。在横向模式下,我得到了两个应该并排显示的片段。但不显示第二个片段。
MainActivity onCreate
@Override
public void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH){
this.setTheme(R.style.Theme_Sherlock);
}
if (savedInstanceState != null)
{
savedInstanceState.remove ("android:support:fragments");
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tab1 = actionbar.newTab().setText("Search");
tab2 = actionbar.newTab().setText("Found");
tab3 = actionbar.newTab().setText("Account");
Class[] clzs;
String[] tags;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
clzs = new Class[2];
tags = new String[2];
clzs[0] = ListSearchFragment.class;
tags[0] = "listsearch";
clzs[1] = DetailSearchFragment.class;
tags[1] = "detailsearch";
}
else
{
clzs = new Class[1];
tags = new String[1];
clzs[0] = ListSearchFragment.class;
tags[0] = "listsearch";
}
tab1.setTabListener(new MainTabListener<SherlockFragment>(this, clzs,tags));
clzs = new Class[1];
tags = new String[1];
clzs[0] = AccountOverviewFragment.class;
tags[0] = "accountoverview";
tab2.setTabListener(new MainTabListener<SherlockFragment>(this, clzs,tags));
tab3.setTabListener(new MainTabListener<SherlockFragment>(this, clzs,tags));
actionbar.addTab(tab1);
actionbar.addTab(tab2);
actionbar.addTab(tab3);
}
MainTabListener:
public class MainTabListener <T extends SherlockFragment> implements ActionBar.TabListener{
public SherlockFragment fragments[];
private Activity mActivity;
private Class<T>[] mClasses;
private String[] tags;
public MainTabListener(Activity activity, Class<T>[] clzs, String[] tags) {
this.mActivity = activity;
this.mClasses = clzs;
this.tags = tags;
this.fragments = new SherlockFragment[mClasses.length];
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
FragmentManager fragMgr = ((FragmentActivity) mActivity).getSupportFragmentManager();
ft = fragMgr.beginTransaction();
for(int i = 0; i < mClasses.length; i++)
{
if (fragments[i] == null) {
fragments[i] = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClasses[i].getName());
ft.add(R.id.fragment_container, fragments[i],tags[i]);
}
else {
ft.attach(fragments[i]);
}
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
FragmentManager fragMgr = ((FragmentActivity) mActivity).getSupportFragmentManager();
ft = fragMgr.beginTransaction();
for(int i = 0; i < mClasses.length; i++)
{
if (fragments[i] != null) {
ft.detach(fragments[i]);
}
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
当屏幕方向处于横向模式时,布局重力和宽度设置为 1/3 和 2/3。
在纵向模式下,我有一个带有列表的片段。当我单击一个项目时,将启动一个新的 Activity,其中另一个 Fragment 被添加到新的 LinearLayout 中。
详细活动:
public class DetailSearchActivity extends SherlockFragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_found_detail);
FragmentManager fragMgr = this.getSupportFragmentManager();
FragmentTransaction ft = fragMgr.beginTransaction();
ft.add(R.id.fragment_container,SherlockFragment.instantiate(this, DetailSearchFragment.class.getName()) ,"detailsearch");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
fragMgr.executePendingTransactions();
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
finish();
return;
}
Bundle extras = getIntent().getExtras();
try{
DetailSearchFragment fragmentdetail = (DetailSearchFragment) this.getSupportFragmentManager().findFragmentByTag("detailsearch");
if (extras != null) {
String s = extras.getString("title");
String d = extras.getString("description");
fragmentdetail.setText(s, d);
}
}catch(RuntimeException e){
e.printStackTrace();
}
}
}
纵向模式下的问题是,当我尝试设置文本时,片段中的视图似乎没有被初始化。尝试获取已膨胀的 FragmentLayout 中的 Textview 时出现 NullPointerException(显示默认文本)。那么在 FragmentLayout 成功充气后如何调用我的 setText() 方法?
编辑: 当我在 TabListener 中记录我的标签时,在 LandscapeMode 中,两个片段(列表和详细信息)似乎都添加到了 FragmentTransaction
当我将此添加到我的 ListItemClickListener 时:
DetailSearchFragment fragmentdetail = (DetailSearchFragment) getActivity().getSupportFragmentManager().findFragmentByTag("detailsearch");
Log.d("detailfrag","exists: "+(fragmentdetail != null) + " is in Layout:" + (fragmentdetail.isInLayout()));
我得到:
12-23 13:39:07.440: D/detailfrag(13403): exists: true is in Layout:false
Edit2好的,我解决了两个布局的问题。您不能将两个 Fragment 添加到同一个容器中。
选项卡监听器:
public class MainTabListener <T extends SherlockFragment> implements ActionBar.TabListener{
public SherlockFragment fragments[];
private Activity mActivity;
private Class<T>[] mClasses;
private String[] tags;
private View[] myViews;
private int id = 1;
public MainTabListener(Activity activity, Class<T>[] clzs, String[] tags) {
this.mActivity = activity;
this.mClasses = clzs;
this.tags = tags;
this.fragments = new SherlockFragment[mClasses.length];
this.myViews = new View[mClasses.length];
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
FragmentManager fragMgr = ((FragmentActivity) mActivity).getSupportFragmentManager();
ft = fragMgr.beginTransaction();
for(int i = 0; i < mClasses.length; i++)
{
if (fragments[i] == null) {
fragments[i] = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClasses[i].getName());
View myView = (View)new LinearLayout(mActivity);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
myView.setLayoutParams(llp);
ViewGroup container = (ViewGroup)mActivity.findViewById(R.id.fragment_container);
container.addView(myView);
myView.setId(findId());
myViews[i] = myView;
ft.add(myView.getId(), fragments[i],tags[i]);
}
else {
myViews[i].setVisibility(View.VISIBLE);
}
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
for(int i = 0; i < mClasses.length; i++)
{
if (fragments[i] != null) {
myViews[i].setVisibility(View.GONE);
}
}
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
public int findId(){
View v = (ViewGroup)mActivity.findViewById(id);
while (v != null){
v = (ViewGroup)mActivity.findViewById(++id);
}
return id++;
}
}
当纵向模式下只有一个 Fragment 时,仍然遇到在创建 FragmentView 之前调用 setText() 方法的问题。