48

如您所料,我有一个片段可以在 onCreateView 中创建其视图。但是我想定期更改视图。

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

我可以制作两个片段 - 加载片段和显示片段,但似乎因为这是一个封装事件,我宁愿在一个片段内完成所有操作。

基本上我要问的是,片段内 setContentView 的等价物是什么。

4

9 回答 9

34

您可以使用Fragment.getView(). 这将返回包含Fragment. 在该视图上,您​​可以调用removeAllViews. 然后构建您的新视图并将它们添加到您从中获得的视图中getView()

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

于 2011-05-26T13:54:12.907 回答
27

如果出于任何原因,您想要更改整个片段视图(例如,将在成功时更改视图的异步 URL 请求),您可以在父活动中使用 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()

现在,我建议ViewModel为此目的使用。

于 2012-11-16T13:54:02.850 回答
4

您可以使用 aFrameLayout在进度条和数据视图之间切换,例如

<?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);
于 2011-08-23T13:06:56.817 回答
4

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

<?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);
于 2016-04-14T03:45:31.667 回答
3

这里有一个更简单的解决方案:将收到的充气机和容器保存在 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);
}
于 2016-05-22T10:44:58.773 回答
1

你可以使用事务删除和添加。我使用了一个片段,我可以在其中加载任何视图。Fragment 的构造函数必须有一个整数,该整数是 R.layout.... 我只是删除旧片段并放入一些新片段。!!!仅当您将此片段设为动态且不在 xml 布局中时,它才有效。只需创建类似 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);
}
于 2012-07-30T13:52:42.077 回答
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();
            }
        }
    }
于 2014-08-23T13:47:37.643 回答
-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;
于 2013-09-06T14:52:57.873 回答
-1

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

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

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

现在这个问题已经解决了,希望能帮到你

于 2016-01-18T03:53:06.677 回答