Java 如何动态生成此子片段';s文本视图可见/不可见?

Java 如何动态生成此子片段';s文本视图可见/不可见?,java,android,xml,android-fragments,fragmenttransaction,Java,Android,Xml,Android Fragments,Fragmenttransaction,我有一个包含父片段的主活动,父片段又包含一个子片段。我正在尝试动态地使子片段中的TextView可见/不可见 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"

我有一个包含父片段的主活动,父片段又包含一个子片段。我正在尝试动态地使子片段中的TextView可见/不可见

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This text belongs to the Activity"
        android:id="@+id/textView"/>

    <FrameLayout
        android:id="@+id/parent_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
ParentFragment.java

public class ParentFragment extends Fragment {
    public static final String CHILD_TAG = "child_tag";
    private ChildFragment mChildFragment;
    private List<Integer> mList;

    public static ParentFragment newInstance() {

        Bundle args = new Bundle();

        ParentFragment fragment = new ParentFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_parent, container, false);
        mList = new ArrayList<Integer>();

        if (savedInstanceState == null) {
            mChildFragment = ChildFragment.newInstance();
            getChildFragmentManager().beginTransaction().replace(R.id.child_container, mChildFragment, CHILD_TAG).commit();
        }
        else {
            mChildFragment = (ChildFragment) getChildFragmentManager().findFragmentByTag(CHILD_TAG);
        }
        getChildFragmentManager().executePendingTransactions(); //doesn't seem to do anything!
        doStuff();

        return view;
    }

    void doStuff() {
        mList.add(4); //pretend this is actually querying a database.
        //for simplicity it just receives a single 4.

        if (mList.size() > 0) { //the list is not empty, display the text!
            mChildFragment.setTextVisible(); //error! the textivew of the child fragment is null right now
        }
        else {
            mChildFragment.setTextInvisible(); //error! the textivew of the child fragment is null right now
        }
    }
}
public class ChildFragment extends Fragment {
    private TextView mTextView;

    public static ChildFragment newInstance() {

        Bundle args = new Bundle();

        ChildFragment fragment = new ChildFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_child, container, false);
        mTextView = (TextView) view.findViewById(R.id.make_this_text_visible);
        return view;
    }

    public void setTextVisible() {
        mTextView.setVisibility(View.VISIBLE);
    }
    public void setTextInvisible() {
        mTextView.setVisibility(View.INVISIBLE);
    }
}

如何确保在调用ParentFragment中的doStuff()时形成子片段?

我要做的是保持文本视图的状态可见性,以便在创建视图(如果尚未创建)后可以正确更新它。对于
setTextVisible()
setTextInvisible
而言,不是单独的方法,而是使用一个方法
setTextVisible(boolean isVisible)
,并按如下方式实现它:

public class ChildFragment extends Fragment {
    private TextView mTextView;
    private boolean mIsTextVisible;

    public static ChildFragment newInstance() {
        Bundle args = new Bundle();
        ChildFragment fragment = new ChildFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_child, container, false);
        mTextView = (TextView) view.findViewById(R.id.make_this_text_visible);
        setTextVisible(mIsTextVisible);

        return view;
    }

    public void setTextVisible(boolean isVisible) {
        mIsTextVisible = isVisible;
        if(mTextView != null) {
            mTextView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
        }
    }
}
然后在父片段中,您可以调用
doStuff()
,而不必担心
ChildFragment
中视图的当前状态,因为
mIsTextVisible
已正确设置。如果调用
setTextVisible()
mTextView
为空,则可见性仍将在
onCreateView()
中正确设置

只要在重新创建片段时(如设备旋转时),小心保存并恢复
mIsTextVisible
标志即可


使用回调的备选答案 使用回调更新父片段以实现
ChildFragment.OnViewCreatedListener及其方法

public class ParentFragment extends Fragment
    implements ChildFragment.OnViewCreatedListener {

    @Override
    public void onViewCreated() {
        doStuff();
    }
}
然后在
ChildFragment

public class ChildFragment extends Fragment {
    public interface OnViewCreatedListener {
        void onViewCreated();
    }

    public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_child, container, false);
        mTextView = (TextView) view.findViewById(R.id.make_this_text_visible);

        if(getParentFragment() instanceof OnViewCreatedListener) {
            ((OnViewCreatedListener) getParentFragment()).onViewCreated();
        } else if (getActivity() instanceof OnViewCreatedListener) {
            ((OnViewCreatedListener) getActivity()).onViewCreated();
        }

        return view;
    }
}

制作一个接口来执行回调,并在子片段中实现它,并通过类似parentlike的公共接口Foo{public void onPerform(Textview v);}调用它。下面的答案与我想要回答的答案类似。Im处于远程状态,因此无法键入完整代码..:(对不起,假设存在父片段,有没有办法在没有ChildFragment的情况下执行此操作?例如,MainActivity可能是ChildFragment的父片段,等等。换句话说,它是否可以先通过活动进行通信,然后再与ParentFragment进行通信?请稍等,因为我正在使用解决方案更新此内容我将使用而不是回调。我还更新了答案,以说明如何使回调方法同时适用于活动和片段。基本上,您还可以查看活动是否也实现了回调接口。您是否有任何理由更喜欢第一种方法而不是回调方法?这更符合个人偏好。逻辑ems对我来说更简单,不必等待回调方法来处理
片段
public class ChildFragment extends Fragment {
    private TextView mTextView;
    private boolean mIsTextVisible;

    public static ChildFragment newInstance() {
        Bundle args = new Bundle();
        ChildFragment fragment = new ChildFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_child, container, false);
        mTextView = (TextView) view.findViewById(R.id.make_this_text_visible);
        setTextVisible(mIsTextVisible);

        return view;
    }

    public void setTextVisible(boolean isVisible) {
        mIsTextVisible = isVisible;
        if(mTextView != null) {
            mTextView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
        }
    }
}
public class ParentFragment extends Fragment
    implements ChildFragment.OnViewCreatedListener {

    @Override
    public void onViewCreated() {
        doStuff();
    }
}
public class ChildFragment extends Fragment {
    public interface OnViewCreatedListener {
        void onViewCreated();
    }

    public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_child, container, false);
        mTextView = (TextView) view.findViewById(R.id.make_this_text_visible);

        if(getParentFragment() instanceof OnViewCreatedListener) {
            ((OnViewCreatedListener) getParentFragment()).onViewCreated();
        } else if (getActivity() instanceof OnViewCreatedListener) {
            ((OnViewCreatedListener) getActivity()).onViewCreated();
        }

        return view;
    }
}