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

Vis*_*jay 2 android textview android-layout android-fragments android-viewpager

我的应用程序中有2个片段,Fragment1并且Fragment2.两者都使用不同的布局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);
}

}
Run Code Online (Sandbox Code Playgroud)


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");
}
}
Run Code Online (Sandbox Code Playgroud)


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");
}
}
Run Code Online (Sandbox Code Playgroud)

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);
}
}
Run Code Online (Sandbox Code Playgroud)


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>
Run Code Online (Sandbox Code Playgroud)


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>
Run Code Online (Sandbox Code Playgroud)


现在你看到两个布局都有一个textView相同id.
当我运行这个应用程序时,fragment1的TextView文本为"hai",而fragment2的TextView文本为"".但是我期待的是,fragment1 TextView应该有文本"Hello"而fragment2 TextView应该有文本"hai".

好的,现在我将TextViewid 更改content_view2.xmlhaiTextView2.也是一样的 Fragment2.java.现在应用程序正如我预期的那样完美运行.
现在我的问题:
1)当我保持两个TextViewid相同时,为什么我没有得到预期的输出?
2)为什么我不能在这里使用相同的ID?

Luk*_*rog 9

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

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

这是因为这条线:

((TextView)mainActivity.findViewById(R.id.haiTextView)).setText("Hai");
Run Code Online (Sandbox Code Playgroud)

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

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

您应该避免Fragment使用Activity引用来查找使用该引用的视图,片段应该被设计为松散耦合的组件(当您可以简单地使用时,使用该活动查找片段的视图没有任何意义getView().findViewById(etc)).此外,你应该真的避免使用setRetainInstance()在a中使用的片段ViewPager.

  • @VishalVijay如果你正在使用`ListFragment`那么`ListView`必须有一个id为'android.R.id.list`(在xml布局文件中为`@android:id/list`),除非你的片段有多一个`ListView`.想法是你应该传入一个`Bundle`(在适配器的`getItem()`方法中:`Bundle b = new Bundle(); b.put("position",position); mFragments.get(position ).setArgs(b);返回mFragments.get(position);`)片段的`position`并根据该位置更新片段.然后在片段中使用`getArguments().getInt("position")`并且你会知道你在哪个页面. (2认同)