如何动态使此子片段的TextView可见/不可见? [英] How do I dynamically make this child Fragment's TextView visible/invisible?

查看:59
本文介绍了如何动态使此子片段的TextView可见/不可见?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主要的Activity,其中包含一个父Fragment,而父Fragment又包含一个子Fragment.我正在尝试使子片段中的TextView动态可见/不可见.

I have a main Activity containing a parent Fragment, which in turn contains a child Fragment. I am trying to make a TextView in the child Fragment visible/invisible dynamically.

activity_main.xml

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>

fragment_parent.xml

fragment_parent.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 parent fragment"
        android:id="@+id/textView"/>


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

</LinearLayout>

fragment_child.xml

fragment_child.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 child fragment"
        android:id="@+id/textView"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="But make this text visible dynamically!"
        android:id="@+id/make_this_text_visible"
        android:visibility="invisible"/>
</LinearLayout>

MainActivity.java

MainActivity.java

public class MainActivity extends AppCompatActivity {
    public static final String PARENT_TAG = "parent_tag";
    private ParentFragment mParentFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            mParentFragment = ParentFragment.newInstance();
            getSupportFragmentManager().beginTransaction().replace(R.id.parent_container, mParentFragment, PARENT_TAG).commit();
        }
        else {
            mParentFragment = (ParentFragment) getSupportFragmentManager().findFragmentByTag(PARENT_TAG);
        }
    }
}

ParentFragment.java

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
        }
    }
}

ChildFragment.java

ChildFragment.java

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()时形成子片段?

How can I ensure that the child fragment is formed by the time I call doStuff() in the ParentFragment?

推荐答案

我要做的是保持文本视图可见性的状态,以便一旦尚未创建视图就可以正确地对其进行更新.代替单个方法 setTextVisible() setTextInvisible 的方法,只有一个方法 setTextVisibile(boolean isVisible)并实现如下:

What I would do is keep the state of the text view visibility so it can be updated properly once the view has been created if it hasn't been already. Instead of separate methods for setTextVisible() and setTextInvisible have a single method setTextVisibile(boolean isVisible) and implement it as follows:

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 为null,则可见性仍将在 onCreateView()中正确设置.

and then in the parent fragment you can call doStuff() without worrying about the current state of the views in the ChildFragment since mIsTextVisible is properly set. If the mTextView is null at the time setTextVisible() is called the visibility will still be properly set in onCreateView().

在重新创建片段(例如旋转设备)时,请务必小心保存并恢复 mIsTextVisible 标志.

Just take care to save and restore the mIsTextVisible flag when the fragment is recreated such as when the device is rotated.

使用回调更新 ParentFragment 以实现 ChildFragment.OnViewCreatedListener 及其方法.

Using callbacks update the ParentFragment to implement ChildFragment.OnViewCreatedListener and its method.

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

这篇关于如何动态使此子片段的TextView可见/不可见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆