0

The layout of my StartupPreference is defined with only one ViewPager as:

<?xml version="1.0" encoding="utf-8"?>

    <androidx.viewpager.widget.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/startPref_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

and the associated activity associates this as:

public class StartupPreference extends AppCompatActivity implements StartupPrefFrag_interfaces{
    private final static int no_of_prefs = 2;
    private LinearLayout dot_animation_holder;
    private static int temp_count = 0;

    public void ViewUpdater(View updatedView){
        dot_animation_holder = (LinearLayout) updatedView;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_startup_preference);
        //we're not using the layout natively, but using Fragment's layout
        //but setContentView is required -> it is accessed by : R.id.startPref_pager

        dot_animation_holder= findViewById(R.id.dot_animation_holder);

        StartPrefPagerAdapter prefPagerAdapter =
                new StartPrefPagerAdapter(getSupportFragmentManager());

        ViewPager StartPref_Viewpager = findViewById(R.id.startPref_pager);
        StartPref_Viewpager.setAdapter(prefPagerAdapter);




        StartPref_Viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                    ((ImageView)(findViewById(R.id.dot_animation_holder).findViewById(R.id.page1))).setImageResource(R.drawable.active_dot);
                    ((ImageView)(findViewById(R.id.dot_animation_holder).findViewById(R.id.page2))).setImageResource(R.drawable.inactive_dot);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });




    }


    private class StartPrefPagerAdapter extends FragmentPagerAdapter {
        public StartPrefPagerAdapter(FragmentManager fm){
            super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        }

        @Override
        public int getCount(){
            return StartupPreference.no_of_prefs;//no. of preference pages
        }

        @Override
        public Fragment getItem(int position) {
            switch (position){
                case 0:
                    return new Frag_StartPref_Layout();
                case 1:
                    return new Frag_StartPref_Theme();
            }
            return null;
        }

    }

}

The problem I am having is that I'm not getting it how to access different Views associated with the ViewPager. Since both the layout of the fragments include a common layout called dot_animation.xml using the <include...> tag, but the code in the onPageSelected method above updates only the first page, and if I use different ids in the <include...> like:

fragment_startpref_layout.xml:

...

<include
        layout="@layout/dot_animation"
        android="@+id/dot_animation_holder1"
        />
...  

fragment_startpref_theme.xml

...
    <include
            layout="@layout/dot_animation"
            android="@+id/dot_animation_holder2"
    />

...  

and I use these ids to update the ImageView then I get a NullPointer Exception.(I use the code in the activity)

So, what can I do to access the different Views in the respective pages of the ViewPager?
The layout of the fragments are given below:
fragment_startpref_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout

    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/C_startPref_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    >

    <ImageView
        android:id="@+id/startPref_Layout"
        android:layout_width="0dp"
        android:layout_height="0dp"

        android:scaleType="centerCrop"
        app:layout_constraintBottom_toTopOf="@+id/startPref_layout_info"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher" />


    <TextView
        android:id="@+id/startPref_layout_info"
        android:layout_width="0dp"
        android:layout_height="0dp"

        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:gravity="center"
        android:text="@string/Frag_startPref_layout_info"

        android:textSize="25sp"
        app:layout_constraintBottom_toTopOf="@+id/startPref_layout_select1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent=".125"
        app:layout_constraintStart_toStartOf="parent" />

    <RadioGroup
        android:id="@+id/startPref_layout_select1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"

        android:layout_marginEnd="8dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toTopOf="@+id/dot_animation_holder"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent=".125"
        app:layout_constraintStart_toStartOf="parent">

        <RadioButton
            android:id="@+id/radioButton1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:checked="true"
            android:text="@string/Frag_startPref_Radio1"
            android:textSize="15sp" />

        <RadioButton
            android:id="@+id/radioButton2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="@string/Frag_startPref_Radio2"
            android:textSize="15sp" />
    </RadioGroup>

    <include
        layout="@layout/dot_animation"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

fragment_theme_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/C_startPref_theme"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    >

    <ImageView
        android:id="@+id/startPref_Theme"
        android:layout_width="0dp"
        android:layout_height="0dp"

        android:scaleType="centerCrop"
        app:layout_constraintBottom_toTopOf="@+id/startPref_layout_info"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher" />


    <TextView
        android:id="@+id/startPref_layout_info"
        android:layout_width="0dp"
        android:layout_height="0dp"

        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:gravity="center"
        android:text="@string/Frag_startPref_layout_info"

        android:textSize="25sp"
        app:layout_constraintBottom_toTopOf="@+id/startPref_layout_select2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent=".125"
        app:layout_constraintStart_toStartOf="parent" />

    <RadioGroup
        android:id="@+id/startPref_layout_select2"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"

        android:layout_marginEnd="8dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toTopOf="@+id/dot_animation_holder"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent=".125"
        app:layout_constraintStart_toStartOf="parent">

        <RadioButton
            android:id="@+id/radioButton1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:checked="true"
            android:text="@string/Frag_startPref_Radio1"
            android:textSize="15sp" />

        <RadioButton
            android:id="@+id/radioButton2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="@string/Frag_startPref_Radio2"
            android:textSize="15sp" />
    </RadioGroup>


    <include
        layout="@layout/dot_animation"
        />


</androidx.constraintlayout.widget.ConstraintLayout>
juztcode
  • 1,196
  • 2
  • 21
  • 46

1 Answers1

1

First of all you need to update the view in fragmnet on onViewCreated. the reason that you cant update other views is the viewpager only shows the current fragment.and the reason for nullpointexception also is that the other view are not loaded into the activity by viewpager.(You may also want to check if the correct layout is being called in the onCreateView method.) If you want to load all of them even if they are out of the screen you can use viewPager.setOffscreenPageLimit(); but this lose the viewpager purpose. so what i suggest is to create call back to communicate with your fragment and send data through callbacks and update your view inside of there fragment. also this make your activity less messy.

Update :

example of using ViewPager with multiple layouts

Document About setOffscreenPageLimit

Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.

This is offered as an optimization. If you know in advance the number of pages you will need to support or have lazy-loading mechanisms in place on your pages, tweaking this setting can have benefits in perceived smoothness of paging animations and interaction. If you have a small number of pages (3-4) that you can keep active all at once, less time will be spent in layout for newly created view subtrees as the user pages back and forth.

You should keep this limit low, especially if your pages have complex layouts. This setting defaults to 1.

juztcode
  • 1,196
  • 2
  • 21
  • 46
Alireza Sharifi
  • 1,127
  • 1
  • 9
  • 18
  • what do you mean by "you can load them all even if they are out of the screen"? Could you please include an example of loading the view and using them? – juztcode Dec 22 '19 at 10:42
  • i just updated my answer check the example and modify to suit your needs – Alireza Sharifi Dec 22 '19 at 10:50
  • invoking the `setOffscreenPageLimit()` didn't quite make the `id`s of the view available, there is still nullpointerexception crashes. – juztcode Dec 23 '19 at 03:06
  • Somehow that layout is not attached to main layout that why cause nullpoint . Maybe you calling it too soon before it get attached . Did you try the example in my answer? That will definitely work – Alireza Sharifi Dec 23 '19 at 03:17
  • yes, I tried that but that was what I had initially done, and how to access views for different pages was not given – juztcode Dec 23 '19 at 05:11
  • your last statement: "somehow that layout is not attached to main layout..." made me check the fragment and you were right, I was applying the wrong layout in the fragment and not using the one I was searching for. Thanks a tonne :-) – juztcode Dec 23 '19 at 05:21