如何更改片段内的视图?
我有一个片段,如你所期望的,在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");
现在这个问题已经解决,我希望可以帮助你