为什么我不能在ViewPager中为不同的片段使用不同布局中的相同id

时间:2013-04-28 12:53:36

标签: android android-layout android-fragments android-viewpager textview

我的应用中有2个片段,Fragment1Fragment2。两者都使用称为content_view1content_view2的不同布局。我将两个片段放入ViewPager。现在看代码:
MainActivity.java

public class MainActivity extends FragmentActivity {

public ViewPager vp;
FragmentAdapter fragmentAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    vp = new ViewPager(this);
    vp.setId("VP".hashCode());
    fragmentAdapter = new FragmentAdapter(
            getSupportFragmentManager());
    vp.setAdapter(fragmentAdapter);
    setContentView(vp);
    vp.setCurrentItem(0);
}

}


Fragment1.java

public class Fragment1 extends Fragment {

MainActivity mainActivity;

public Fragment1() {
    setRetainInstance(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    mainActivity=(MainActivity)getActivity();
    return inflater.inflate(R.layout.content_view1, null);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ((TextView)mainActivity.findViewById(R.id.haiTextView)).setText("Hello");
}
}


Fragment2.java

public class Fragment2 extends Fragment {

MainActivity mainActivity;

public Fragment2() {
    setRetainInstance(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    mainActivity=(MainActivity)getActivity();
    return inflater.inflate(R.layout.content_view2, null);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ((TextView)mainActivity.findViewById(R.id.haiTextView)).setText("Hai");
}
}

FragmentAdapter.java

public class FragmentAdapter extends FragmentPagerAdapter {

private ArrayList<Fragment> mFragments;

public FragmentAdapter(FragmentManager fm) {
    super(fm);
    mFragments = new ArrayList<Fragment>();
    mFragments.add(new Fragment1());
    mFragments.add(new Fragment2());
}

@Override
public int getCount() {
    return mFragments.size();
}

@Override
public Fragment getItem(int position) {
    return mFragments.get(position);
}
}


content_view1.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal" >

<TextView
    android:id="@+id/haiTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textIsSelectable="true" />

</FrameLayout>


content_view2.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal" >

<TextView
    android:id="@+id/haiTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textIsSelectable="true" />

</FrameLayout>


现在您看到两个布局都有一个textView具有相同的id 当我运行此应用程序时,fragment1的TextView包含文本“hai”而fragment2的TextView包含文本“”。但是我期待的是,fragment1的TextView应该有文本“Hello”而fragment2的TextView应该有文本“hai”。

好了,我现在将TextView的{​​{1}} ID更改为content_view2.xml。在haiTextView2中也是如此。现在应用程序正如我预期的那样完美运行。
现在我的问题:
1)当我保持Fragment2.java id相同时,为什么我没有得到预期的输出? 2)为什么我不能在这里使用相同的ID?

2 个答案:

答案 0 :(得分:9)

  

1)当我同时保留TextView时,为什么我没有得到预期的输出   id相同吗?

     

2)为什么我不能在这里使用相同的ID?

这是因为这一行:

((TextView)mainActivity.findViewById(R.id.haiTextView)).setText("Hai");

问题是findViewById()方法会返回带有提供ID的View第一次次出现(它也不区分两个片段的布局) ),所以当您在第一个或第二个片段中设置文本时,设置的TextView是第一个(第二个片段中的一个未被触及)。

另一方面,当您使用不同的ID时,将选择正确的TextViews

你应该避免使用Fragment引用来查找Activity的视图,片段应该被设计为松散耦合的组件(使用它来查找片段的视图没有任何意义。只需使用getView().findViewById(etc))即可进行活动。 此外,您应该避免将setRetainInstance()ViewPager中使用的片段一起使用。

答案 1 :(得分:0)

要在视图寻呼机的不同页面上使用相同的ID获得所需的结果,您可以使用类似的内容

TextView textView = (TextView) vp.getChildAt(vp.getCurrentItem).findViewById(R.id.haiTextView);