如何动态使此子片段的TextView可见/不可见? [英] How do I dynamically make this child Fragment's TextView visible/invisible?
问题描述
我有一个主要的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屋!