2011-05-10 105 views
39

我如你所期望它創建其內部onCreateView視圖中的片段。但是我想定期更改視圖。如何更改片段內的視圖?

我的使用情況是,該片段顯示了Web服務的一些數據。當用戶從列表(另一個片段)中選擇一個選項時,該片段應切換到進度條,然後加載後切換回數據視圖。

我可以讓兩個片段 - 裝載片段,以及顯示片段,但似乎因爲這是一個封裝的事件,我寧願做這一切的一個片段裏。

基本上,我問,是什麼,是的setContentView的片段內equivilent。

回答

31

您可以使用Fragment.getView()。這將返回包含Fragment的容器的視圖。根據該觀點,您可以致電removeAllViews。然後建立新視圖並將它們添加到從getView()獲得的視圖中。

http://developer.android.com/reference/android/app/Fragment.html#getView()

+2

這個答案在技術上是不正確的。 'getView()'返回'onCreateView()'中提供的'View'而不是容器'View' – 2014-10-03 08:55:37

+0

好點。儘管如此,它仍然是@monkjack問題的答案。 – bplayer 2014-10-03 09:36:03

+0

'getView()'返回視圖,但沒有'removeAllViews()'方法。該方法似乎在'ViewGroup'中。我錯過了什麼嗎? – Tim 2015-02-04 15:14:45

4

你可以使用一個FrameLayout你的進度條和數據視圖,例如之間切換

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <ImageView android:id="@+id/cover_image" 
     android:scaleType="fitCenter" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" /> 
    <ProgressBar android:id="@+id/cover_progress" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content" 
     android:layout_gravity="center"/> 
</FrameLayout> 

onViewCreate()那麼您需要儲存這兩種觀點爲實例字段

public View onCreateView(LayoutInflater inflater, 
     ViewGroup container, Bundle savedInstanceState) { 
    ... 
    image = (ImageView) container.findViewById(R.id.cover_image); 
    progress = container.findViewById(R.id.cover_progress); 
    ... 
} 

,只要你想在兩者之間切換(記得要做到這一點在你的UI /主線程),只是做一些事情像

progress.setVisibility(View.INVISIBLE); 
image.setVisibility(View.VISIBLE); 
+1

'ViewSwitcher'在這種情況下也很方便 – 2011-12-08 19:19:47

+0

view.findViewById(R.id.cover_image); 什麼是變量「視圖」? – Montaro 2013-09-06 05:20:01

+1

@Montaro應該是'容器',在答案中修復。謝謝! – 2013-09-06 10:49:09

1

U可以使用事務刪除和添加。我使用了可以加載任何視圖的片段。 片段的構造函數都必須有一個整數,該整數是R.layout .... 我只是刪除舊的片段,並把一些新的。 !!!它只適用於你使這個片段是動態的,而不是在xml佈局中。如果由於某種原因,你想改變整個片段視圖(例如,異步URL請求,這將改變對成功的看法) 就創造這樣一個的LinearLayout R.id.fragment_layout

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 

    setContentView(R.layout.wundlist_fragmente); 
    Log.v("WoundListActivity", "WoundListActivity gestartet..."); 

    Log.v("WoundListActivity", "Liste..."); 
    //dynamisch hinzufügen... 
    wlf=new WoundListFragment();   
    fm.beginTransaction().add(R.id.fragment_layout,wlf).commit(); 

} 

//If Menubutton Clicked change 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    if(item.getItemId()==R.id.itemaddwound){ 
     Log.v("List", "neue Wunde Activity"); 

     fm.beginTransaction().remove(wlf).commit(); 
     fm.beginTransaction().add(R.id.fragment_layout, new NewWoundFragment()).commit(); 

    } 

    return super.onOptionsItemSelected(item); 
} 
24

,你可以或者在父活動中使用FragmentTransaction並即時創建新的片段。

或者您可以保留片段並調用此片段的方法,該方法將自行刷新。 示例: 在父項活動中,我構建並存儲了片段列表List<RefreshFragment> mFragmentList

這裏是RefreshFragment類(和我所有的片段延長這個在我的例子):

public class RefreshFragment extends Fragment { 
    protected Data data; // here your asynchronously loaded data 

    public void setData(Data data) { 
     this.data = data; 
     // The reload fragment code here ! 
     if (! this.isDetached()) { 
      getFragmentManager().beginTransaction() 
       .detach(this) 
       .attach(this) 
       .commit(); 
     } 
    } 
} 

然後在我的活動異步回調,我可以打電話:

for (RefreshFragment f : mFragmentList) f.setData(data); 

所以每次片段將用正確的數據更新,當前附加的片段將立即更新。你必須在片段中提供你自己的onCreateView。

重要的是片段可以用getFragmentManager()重新加載自己。

+0

這對我很有用。謝謝。 – Jacek 2012-11-22 19:37:48

+0

問題是,當你加載你的數據或當用戶點擊一個按鈕時,碎片永遠不會被分離... – 2013-12-25 12:55:10

+0

@Waza_Be我認爲這是一個類型,應該看起來像這樣:'if(!this.isDetached()){'' 。 – sulai 2015-11-04 13:22:48

-1

這是什麼工作對我來說:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View v = inflater.inflate(R.layout.fragment_recipe, container, false); 
    Button recipeBuyButton = (Button) v.findViewById(
      R.id.recipe_buy_button); 
    Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/GE_SS_Two_Medium.otf"); 
    recipeBuyButton.setTypeface(tf); 
    return v; 
+1

爲什麼人們對正確答案進行反對投票?這個答案沒有什麼是錯的。 +1從我身邊。 – 2015-07-08 04:10:59

+0

因爲這個答案與當前問題無關。 – Sierisimo 2015-10-26 19:15:58

1

使用Solostaran14s響應我現在這樣做:

接口:

public interface FragmentReattachListener { 

    public void reAttach(); 

} 

片段:

public class MyFragment extends Fragment implements FragmentReattachListener { 
//... 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    //... 
    App.registerFragmentReattachListener(this); 
    //... 
} 

//...  

@Override 
public void reAttach() { 
    FragmentManager f = getFragmentManager(); 
    if (f != null) { 
     f.beginTransaction() 
        .detach(this) 
        .attach(this) 
        .commit(); 
     } 
    } 

} 

從應用類:

private static void reattachFragments() { 
     if (fragmentReattachListeners.size() > 0) { 
      for (FragmentReattachListener listener : fragmentReattachListeners) { 
       listener.reAttach(); 
      } 
     } 
    } 
+0

我贊同:更好的界面。 – Solostaran14 2015-11-23 14:03:24

-1

我有同樣的問題,fragment.getView()始終返回null,雖然Fragment.onCreateView已經調用之前

我們不能在運行時改變片段的內容,因爲我的片段添加到ViewPager所以我嘗試用其他方法來獲得視圖:

View view = viewPager.getChildAt(0); 
TextView text = (TextView) (view.findViewById(R.id.textView)); 
text.setText("12345"); 

這個問題現在是resoloved,希望可以幫到你

2

創建一個「虛擬」的默認視圖

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

</LinearLayout> 

充氣片段中的onCreateView法「虛擬」默認視圖,並把它作爲一個佔位符來添加視圖需要

private LayoutInflater mInflater; 
private ViewGroup mContainer; 

@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){ 
    mInflater = inflater; 
    mContainer = container; 

    View v =inflater.inflate(R.layout.home_view,container,false); 
    placeholder = (ViewGroup) v; 

    return placeholder; 
} 

要更改視圖到一個新的觀點,你首先刪除所有以前的觀點則擡高新的視圖,並添加

View newView = mInflater.inflate(R.layout.custom_dash, mContainer, false); 
placeholder.removeAllViews(); 
placeholder.addView(newView); 
1

這裏有一個簡單的解決方案:爲您節省在onCreateView收到充氣和容器,並在以後使用它們。例如:

private LayoutInflater mInflater; 
private ViewGroup mRootView; 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    mInflater = inflater; 
    mRootView = container; 
    return null; 
} 

public void someCallBackLater() { 
    // mRootView.removeAllViews(); // in case you call this callback again... 
    mInflater.inflate(R.layout.my_layout, mRootView); 
}