【问题标题】:Why can't I use the same id in different layout for different fragements in ViewPager为什么我不能在不同的布局中为 ViewPager 中的不同片段使用相同的 id
【发布时间】:2016-10-29 00:42:49
【问题描述】:

我的应用程序中有 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”。

好的,现在我将content_view2.xmlTextView id 更改为haiTextView2。在Fragment2.java 中也做了同样的事情。现在该应用程序按我的预期完美运行。
现在我的问题:
1) 当我保持TextView id 相同时,为什么我没有得到预期的输出?
2) 为什么我不能在这里使用相同的 ID?

【问题讨论】:

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


    【解决方案1】:

    1) 为什么我在同时保留 TextView 时没有得到预期的输出 一样吗?

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

    这是因为这条线:

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

    问题是findViewById() 方法将返回 first 出现的 View 并带有提供的 id(它也不区分两个片段的布局),所以当您在第一个或第二个片段中设置文本,设置的TextView 是第一个(第二个片段中的那个保持不变)。

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

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

    【讨论】:

    • 我为什么要避免setRetainInstance()
    • 非常感谢。 getView() 对我来说是非常有用的信息。
    • @VishalVijay setRetaininstance(true) 将在配置更改期间保留该片段,另一方面,ViewPager 在旋转更改后自行处理片段。该方法不适用于所有情况下的片段。
    • 好的。考虑我有一个布局,它有一个ListView。我正在使用ListFragment。那么我如何通过使用getView() 函数来使用setListAdapter() 类型的函数。 (考虑到我提出的主要问题。即;我有 2 个带有列表视图的片段。我使用的是ListFragment,因此id 应该是@+id/list)。
    • @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);return mFragments.get(position);position 并根据该位置更新片段。然后在片段中使用getArguments().getInt("position"),你就会知道你在哪个页面。
    【解决方案2】:

    要在视图寻呼机的不同页面上获得具有相同 ID 的所需结果,您可以使用类似这样的东西

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多