2012-02-10 32 views
3

所以,我有一個搜索標準片段,可以輸入搜索條件,並且執行搜索時,搜索結果顯示在搜索結果片段中。在平板電腦的橫向上,這兩個片段自然可以並排顯示。到目前爲止,這很簡單。片段在旋轉時是否可以從對話框切換到嵌入式?

在縱向和手機上,我希望搜索條件片段顯示爲彈出式對話框而不是搜索結果。在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(真)和全亂套了,所以我立即刪除該行。

謝謝你把我在這裏在正確的軌道上的任何幫助。

+0

我覺得有可能是一些關於你的configChanges屬性或可能會造成您的片段消失旋轉活動代碼。我認爲你會盡可能地分享盡可能多的代碼。 – nmr 2012-02-11 02:03:14

回答

0

我會說這個。

在手機上做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" . . . > 

這使得使用onSaveInstanceStateonRestoreInstanceState和活動週期方向改變的簡單。

然後在平板電腦上,你有你的兩個片段另一個活動

  <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> 

簡化。

+0

理想我想使用Android兼容性庫,並實際用於片段的UI元素。 – Thorinside 2012-02-11 00:33:39

+0

那正是我的意思嗎?編輯片段XML把它清除掉(它只是pseado反正) – Blundell 2012-02-11 00:36:00

+0

但我想知道如何使管理兩個片段適當的,而不是三個活動一個活動。 – Thorinside 2012-02-11 00:36:51