片段在旋转时是否可以从对话框切换到嵌入式?
所以,我有一个搜索标准片段,可以输入搜索条件,并且执行搜索时,搜索结果显示在搜索结果片段中。在平板电脑的横向上,这两个片段自然可以并排显示。到目前为止,这很简单。片段在旋转时是否可以从对话框切换到嵌入式?
在纵向和手机上,我希望搜索条件片段显示为弹出式对话框而不是搜索结果。在DialogFragment的Selecting Between Dialog or Embedding部分,我看到我可以嵌入片段,或将其显示为对话框。如果方向改变并不复杂,这可能适用于我。
如果我在活动的布局中使用< fragment> XML标记,当我进行方向更改时,会遇到各种麻烦。
编辑:今天我决定尝试,看看我是否可以得到一个简单的工作流程使用DialogFragment切换显示对话框和嵌入取决于设备的方向之间切换。事实证明这是相当困难的,我仍然没有找到有效的东西。这是迄今为止我所拥有的。
package org.nsdev.experiments;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class FragmentSearchTestActivity extends FragmentActivity
{
private static SearchCriteriaFragment searchCriteriaFragment;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View container = findViewById(R.id.search_criteria_container);
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (searchCriteriaFragment == null)
{
searchCriteriaFragment = SearchCriteriaFragment.newInstance();
searchCriteriaFragment.setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}
android.support.v4.app.Fragment f = getSupportFragmentManager().findFragmentByTag("search_criteria");
if (f != null)
{
ft.remove(f);
}
if (container == null)
{
searchCriteriaFragment.setCancelable(true);
searchCriteriaFragment.setHasOptionsMenu(false);
searchCriteriaFragment.show(getSupportFragmentManager(), "search_criteria");
}
else
{
ft.remove(searchCriteriaFragment);
ft.add(R.id.search_criteria_container, searchCriteriaFragment, "search_criteria");
ft.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == R.id.menu_item_search)
{
searchCriteriaFragment.show(getSupportFragmentManager(), "search_criteria");
}
return super.onOptionsItemSelected(item);
}
}
具体我无法得到任何工作,除非我不停的SearchCriteriaFragment的静态副本,并重新使用它时的onCreate在活动被调用。这对我来说似乎是非常错误的。
SearchResultsFragment.java:
package org.nsdev.experiments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SearchResultsFragment extends android.support.v4.app.Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.results, container);
}
}
SearchCriteriaFragment.java:
package org.nsdev.experiments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SearchCriteriaFragment extends android.support.v4.app.DialogFragment
{
private static final String TAG = "SearchCriteriaFragment";
View v;
static SearchCriteriaFragment newInstance()
{
Log.e(TAG, "newInstance");
SearchCriteriaFragment d = new SearchCriteriaFragment();
return d;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (v == null)
{
v = inflater.inflate(R.layout.criteria, container, false);
}
else
{
if (v.getParent() instanceof ViewGroup)
{
Log.e(TAG, "Removing from viewgroup");
((ViewGroup)v.getParent()).removeAllViews();
}
}
return v;
}
}
你可以看到,在这里,我不得不解决一个问题的观点被重复使用。有一个错误,说明该视图已经有了一个父项,并且在它被添加到另一个父项之前需要将其从中删除。再次,这似乎是我必须以错误的方式来做。
RES /布局/ main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="@+id/search_results"
android:name="org.nsdev.experiments.SearchResultsFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
RES /布局,土地/ main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="@+id/search_criteria_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<fragment
android:id="@+id/search_results"
android:layout_toRightOf="@+id/search_criteria_container"
android:name="org.nsdev.experiments.SearchResultsFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
可以从以下两个布局看,我试图做的。在正常的方向上,FrameLayout不存在,所以我们可以检测到它并显示DialogFragment。否则,我们可以将DialogFragment嵌入到FrameLayout中。
最后两个布局,我只是把占位符的结果和标准布局:
RES /布局/ criteria.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#300F">
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="21dp"
android:paddingRight="30dp"
android:text="Test Criteria" />
</RelativeLayout>
RES /布局/ results.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#f00">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:text="Results"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
我想我已经想通了,直到我开始旋转设备和检查的ICS设备上的复选框。请注意,我已将颜色设置为针对criteria.xml RelativeLayout背景的半透明。我注意到的是,在横向,嵌入视图实际上是保留旧版本的视图的左右,而这些将与每次我切换到肖像,然后再返回视图的新副本覆盖。这是我试图保留从SeachCriteriaFragment的onCreateView返回的视图的一个副本的原因之一。这不能解决这个问题。
我只能得出一个结论:我必须这样做不对。我怀疑Fragments框架从来没有被设计用来做这种片段重用。我怎样才能得到一个不错的旋转工作在哪里在肖像我显示DialogFragment作为一个对话框,并在景观它嵌入?我可以让框架更自动地做这样的事吗?
我试着设置searchCriteriaFragment.setRetainInstance(真)和全乱套了,所以我立即删除该行。
谢谢你把我在这里在正确的轨道上的任何帮助。
我会说这个。
在手机上做SearchFormFragment的活动,并给它的主题对话。 然后SearchResultsFragment也是它自己的独立活动。
的SearchForm XML看起来像:
<LinearLayout >
<fragment class="com.your.package.ui.fragment.SearchFormFragment" />
</LinearLayout>
要获得Dialog theme:
<manifest . . . >
<application . . . >
<activity
android:name=".ui.phone.SearchFormFragmentActivity"
android:theme="@android:style/Theme.Dialog" . . . >
<activity
android:name=".ui.phone.SearchResultsFragmentActivity" . . . >
这使得使用onSaveInstanceState
和onRestoreInstanceState
和活动周期方向改变的简单。
然后在平板电脑上,你有你的两个片段另一个活动
<activity
android:name=".ui.tablet.SearchFragmentActivity" . . . >
SearchFragmentActivity.xml:
<LinearLayout >
<fragment class="com.your.pacakage.ui.fragment.SearchFormFragment"/>
<fragment class="com.your.package.ui.fragment.SearchResultsFragment" />
</LinearLayout>
简化。
理想我想使用Android兼容性库,并实际用于片段的UI元素。 – Thorinside 2012-02-11 00:33:39
那正是我的意思吗?编辑片段XML把它清除掉(它只是pseado反正) – Blundell 2012-02-11 00:36:00
但我想知道如何使管理两个片段适当的,而不是三个活动一个活动。 – Thorinside 2012-02-11 00:36:51
我觉得有可能是一些关于你的configChanges属性或可能会造成您的片段消失旋转活动代码。我认为你会尽可能地分享尽可能多的代码。 – nmr 2012-02-11 02:03:14