Android 怎么将fragment 动态地添加到布局中的任意位置?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 怎么将fragment 动态地添加到布局中的任意位置?相关的知识,希望对你有一定的参考价值。
android 怎么将fragment 动态地添加到布局中的任意位置而不受布局文件的限制?
我们通常是用getSupportFragmentManager().beginTransaction().replace(R.id.fragment_view, fragment).commit();
来添加fragment到指定的视图位置。所以你的需求只需你动态的改变需要替换的这个view的位置就好了,替换流程还是不变的。
动态的改变view的位置,这需要你在java代码里动态的设置view的位置。追问
恩 这个方案应该可以,改变Fragment容器的位置应该是可以的
参考技术A 好像不能这样做。必须要指定容器的id。如何动态地使这个子 Fragment 的 TextView 可见/不可见?
【中文标题】如何动态地使这个子 Fragment 的 TextView 可见/不可见?【英文标题】:How do I dynamically make this child Fragment's TextView visible/invisible? 【发布时间】:2016-08-29 06:22:56 【问题描述】:我有一个包含父 Fragment 的主 Activity,而父 Fragment 又包含一个子 Fragment。我正在尝试使子 Fragment 中的 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_
android:layout_>
<TextView
android:layout_
android:layout_
android:text="This text belongs to the Activity"
android:id="@+id/textView"/>
<FrameLayout
android:id="@+id/parent_container"
android:layout_
android:layout_ />
</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_
android:layout_>
<TextView
android:layout_
android:layout_
android:text="This text belongs to the parent fragment"
android:id="@+id/textView"/>
<FrameLayout
android:id="@+id/child_container"
android:layout_
android:layout_ />
</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_
android:layout_>
<TextView
android:layout_
android:layout_
android:text="This text belongs to the child fragment"
android:id="@+id/textView"/>
<TextView
android:layout_
android:layout_
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() 时形成?
【问题讨论】:
制作回调接口,在子fragment中实现,由父调用 like public interface Foo public void onPerform(Textview v); 下面的答案就像我想回答的一样。我在远程所以无法输入完整的代码.. :( 抱歉 【参考方案1】:我要做的是保持文本视图可见性的状态,以便在视图创建后可以正确更新(如果尚未创建)。而不是 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()
而不必担心ChildFragment
中视图的当前状态,因为mIsTextVisible
已正确设置。如果在调用setTextVisible()
时mTextView
为空,则可见性仍将在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;
【讨论】:
假设有父片段,有没有办法在没有 ChildFragment 的情况下做到这一点?即 MainActivity 可能是 ChildFragment 的父级等。换句话说,它可以先与 Activity 通信,然后再与 ParentFragment 通信吗? 给我一分钟,因为我也在用我将使用的解决方案而不是回调来更新它。 我还更新了答案以展示如何使回调方法同时适用于活动和片段。基本上你也只是看看activity是否也实现了回调接口。 有什么理由你更喜欢第一种方法而不是回调方法? 那是个人喜好。逻辑对我来说似乎更简单,不必等待回调方法来处理Fragment
。以上是关于Android 怎么将fragment 动态地添加到布局中的任意位置?的主要内容,如果未能解决你的问题,请参考以下文章