如何更改片段内的视图?

我有一个片段,如你所期望的,在onCreateView里面创build它的视图。 不过,我想定期更改视图。

我的用例是该片段显示了来自Web服务的一些数据。 当用户从一个列表(另一个片段)中select一个选项时,这个片段应该切换到一个进度条,然后一旦加载,切换回数据视图。

我可以制作两个片段 – 加载片段和显示片段,但似乎由于这是一个封装事件,我宁愿在一个片段内部完成。

基本上我在问什么是一个片段内的setContentView equivilent。

你可以使用Fragment.getView() 。 这将返回包含Fragment的容器的视图。 在这个视图上,你可以调用removeAllViews 。 然后构build新的视图并将它们添加到getView()获得的视图中。

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

如果由于任何原因,你想改变整个片段视图(例如,asynchronous的URL请求,将改变视图的成功),你可以使用父活动中的FragmentTransaction并创build一个新的片段。

或者你可以保留这个片段,并调用这个片段的方法来刷新它自己。 示例:在父级活动中,我构build并存储了片段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(); } } } 

然后在我的活动asynchronouscallback我可以调用:

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

因此,每个片段都将被更新为正确的数据,并且当前附加的片段将立即更新。 你必须在片段中提供你自己的onCreateView。

重要的是片段可以使用getFragmentManager()重新加载。

你可以使用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); 

创build一个“虚拟”默认视图

 <?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); 

你可以使用事务删除和添加。 我用了一个可以加载任何视图的片段。 片段的构造函数必须有一个整数,该整数是R.layout ….我只是删除旧的片段,并把一些新的。 ! 它只适用于你使这个片段是dynamic的,而不是在xml布局。 只需创build一个类似于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); } 

使用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(); } } } 

来自Application类:

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

这里有一个更简单的解决scheme:将收到的inflater和容器保存在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); } 

这对我有用:

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

我有同样的问题,fragment.getView()总是返回null,虽然之前已经调用Fragment.onCreateView

我们不能在运行时更改片段的内容,因为我的片段被添加到ViewPager,所以我尝试使用其他方法来获取视图:

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

现在这个问题已经解决,我希望可以帮助你