如何动态地使这个子Fragment的TextView可见/不可见?

时间:2016-05-04 01:52:54

标签: java android xml android-fragments fragmenttransaction

我有一个包含父片段的主Activity,后者又包含一个子片段。我试图在子片段中使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>

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

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

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

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

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

1 个答案:

答案 0 :(得分:3)

我要做的是保持文本视图的可见性状态,以便在创建视图后可以正确更新它,如果它还没有。 setTextVisible()setTextInvisible的单独方法不是单独的setTextVisibile(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(),而无需担心ChildFragmentmIsTextVisible的视图当前状态,因为mTextView已正确设置。如果调用setTextVisible()onCreateView()为空,则仍会在mIsTextVisible中正确设置可见性。

重新创建片段时(例如旋转设备时),请务必保存并恢复ParentFragment标志。

使用回叫的替代答案

使用回调更新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; } }

var lat