Vishal Vijay
Vishal Vijay

Reputation: 2528

Why can't I use the same id in different layout for different fragements in ViewPager

I have 2 fragments in my application, Fragment1 and Fragment2. Both are using different layouts called content_view1 and content_view2. And I put both fragment into a ViewPager. Now see the code :
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>


Now you see both layout has one textView with same id.
When I run this application, the fragment1's TextView has text "hai" and fragment2's TextView has text "". But what I'm expecting is, the fragment1's TextView should have text "Hello" and fragment2's TextView should have text "hai".

Ok now I changed the TextView id of content_view2.xml to haiTextView2. Did the same in Fragment2.java also. Now the application is working perfectly as I expected.
Now my questions:
1) Why I did't get the expected out put when I keep both the TextView id same?
2) Why can't I use same ids here?

Upvotes: 2

Views: 4282

Answers (2)

Waseem Ahmed
Waseem Ahmed

Reputation: 21

To get the desired result with same ID's at different page of the view pager, You can use something like this

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

Upvotes: 0

user
user

Reputation: 87064

1) Why I did't get the expected out put when I keep both the TextView id same?

2) Why can't I use same ids here?

That is happening because of this line:

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

The problem is the findViewById() method will return the first occurrence of a View with the provided id(it also doesn't differentiate between the layouts of the two fragments), so when you're setting the text in either the first or second fragment the TextView that gets set is the first one(the one from the second fragment is left untouched).

On the other hand, when you use different ids the proper TextViews will get selected.

You should avoid looking for the views of a Fragment using the Activity reference, fragments should be designed as loosely coupled components(it doesn't make any sense to look for the fragment's views using the activity when you could simply use getView().findViewById(etc)). Also, you should really avoid using setRetainInstance() with fragments used in a ViewPager.

Upvotes: 10

Related Questions