【发布时间】:2015-09-13 16:44:08
【问题描述】:
我正在学习 android 片段。我为大屏幕做了一个单独的布局。这是布局:
<?xml version="1.0" encoding="utf-8"?>
<!-- Used in layout-large folder -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:baselineAligned="false"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.muktadir.news.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.muktadir.news.ArticleFragment"
android:id="@+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
这是 article_view 布局。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="@+id/article"
android:padding="@dimen/article_view_padding"
android:textSize="@dimen/article_view_text_size"
android:text="I should be here">
</TextView>
现在我从MainActivity 调用updateArticleView(),这实际上是在更新由ArticleFragment 膨胀的TextView。我通过这一行得到NULL:
getActivity().findViewById(R.id.article);
但是 getView() 工作正常,我可以更新文本。我打印了视图层次结构,它有元素,但不知何故,活动的findViewById() 无法返回对象。能解释一下吗?
public class ArticleFragment extends Fragment{
final static String ARG_POSITION = "position";
final static String TAG = "ArticleFragment";
int mCurrentPosition = -1;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(savedInstanceState != null){
mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
}
return inflater.inflate(R.layout.article_view, container, false);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(ARG_POSITION, mCurrentPosition); //can save negative!
}
@Override
public void onStart() {
super.onStart();
Bundle args = getArguments(); // this is to get the position of article for the first instantiation.
if(args != null){
updateArticleView(args.getInt(ARG_POSITION));
} else if(mCurrentPosition != -1) {
updateArticleView(mCurrentPosition);
}
}
public void updateArticleView(int selectedArticle){ // this is also called from mainactivity
Activity myActivity = getActivity();
Log.d(TAG, myActivity.toString());
ViewGroup view = (ViewGroup) myActivity.findViewById(android.R.id.content);
//printViewHierarchy(view , "debug");
Log.d(TAG, "article id " + String.valueOf(R.id.article));
// TextView article = (TextView) getActivity().findViewById(R.id.article);
TextView article = (TextView) getView();
Log.d(TAG, article.toString());
article.setText(IpSum.Articles[selectedArticle]);
mCurrentPosition = selectedArticle;
}
public static void printViewHierarchy(ViewGroup $vg, String $prefix)
{
for (int i = 0; i < $vg.getChildCount(); i++) {
View v = $vg.getChildAt(i);
String desc = $prefix + " | " + "[" + i + "/" + ($vg.getChildCount()-1) + "] "+ v.getClass().getSimpleName() + " " + v.getId();
Log.v("x", desc);
if (v instanceof ViewGroup) {
printViewHierarchy((ViewGroup)v, desc);
}
}
}
}
【问题讨论】:
-
我相信因为 TextView 是布局中的顶级元素,所以它的 ID 会被片段的 ID 覆盖。如果您查找 R.id.article_fragment 它应该返回 TextView。在某些平台上,有时(不确定确切的条件)片段被包裹在 NoSaveStateFrameLayout 中。
-
@EugenPechanec:如果您打印活动的视图层次结构,您将看到元素存在并且当片段返回视图时,它附加到活动的线性布局。在活动的布局中还有另一个片段。那么,实际上覆盖了什么以及在哪里覆盖?
-
顺便说一句,如果我动态添加片段(在活动布局中没有类名),它确实有效。
-
你片段布局的根(也是唯一)元素是一个带有@id/article 的TextView。当您对提供的片段进行膨胀时,@id/headlines_fragment(或@id/article_fragment)会覆盖片段的根视图的 ID。您会发现带有@id/headlines_fragment 和@id/article_fragment 的视图,它们都是TextView。
-
当您动态添加片段时,您需要提供一个容器的 ID,片段会膨胀到该容器中,因此不会覆盖任何内容。请注意,现在您在活动中实际上有两个带有@id/article 的 TextView,因此无论何时调用 activity.findViewById,您总是会得到第一个。 fragment.getView().findViewById 是要走的路。
标签: android android-fragments android-view