Как передать ссылку на ViewPager в другой класс?

У меня есть класс CustomView. В этом классе логика такова, что при нажатии на кнопку, происходит переход на следующую страницу ViewPager. Т.е. мне нужно, что бы переход на следующую станицу ViewPager у меня осуществлялся и посредством смахивания вправо (это у меня работает) и посредством нажатия на кнопку. В классе CustomView я получаю ошибку java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.viewpager.widget.ViewPager Activity.getViewPager()' on a null object reference Я не могу понять, как мне правильно сослаться на объект ViewPager, который у меня в классе Activity.

activity class:

public class Activity extends AppCompatActivity {
   private ViewPager viewPager;
    private CustomPagerAdapter customPagerAdapter;

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        customPagerAdapter = new CustomPagerAdapter(this);
        viewPager = findViewById(R.id.viewPager);
        viewPager.setAdapter(customPagerAdapter);
    }

    public ViewPager getViewPager() {
        return viewPager;
    }
}

custom class:

public class CustomView extends LinearLayout {
    private LayoutInflater mInflater;
    private Button button;
    private CustomPagerAdapter customPagerAdapter;
    private ViewPager viewPager;
   Activity activity;
    public CustomView(@NonNull Context context) {
        super(context);

    }

    public CustomView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mInflater = LayoutInflater.from(context);
        View v = mInflater.inflate(R.layout.custom_view, this, true);
        button = v.findViewById(R.id.nextButton);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
               activity.getViewPager().setCurrentItem( 1, true);
               }
        })

Ответы (1 шт):

Автор решения: Sergei Buvaka

Не нужно передавать никаких ссылок. Это очень плохая практика.

Я бы создал внутри вашего CustomView интерфейс вроде такого:

interface PageInterractor {
    
    void setPosition(int position);
}

Этот интерфейс должна реализовать ваша Activity/Fragment. И в этом методе вы будете уже внутри Activity/Fragment переключать страницы вашего пейджера.

Внутри вашей CustomView вы создаете экземпляр этого интерфейса

private PageInterractor interractor;

И сеттер для него

public void setPageInterractor(PageInterractor interractor) {
  
    this.interractor = interractor;
}

И в вашем клик листенере

button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
               interractor.setPosition(1);
               }
        })

В чем проблема в вашем подходе?

Во-первых вы напрямую обращаетесь к активити, а это значит, что вы не сможете переместить эту View куда-то еще, так чтоб не менять код.

Во-вторых вы храните ссылку на ViewPager, а значит ваша View работает ТОЛЬКО с ViewPager-ом, а если вы захотите поменять к примеру на RecyclerView то у вас будут проблемы.

В-третьих ваша View отвечает за то, что отвечать не должна. Вы не сможете ее переиспользовать где-либо еще.

UPD

Если же вам так необходимо передавать экземпляр ViewPager внутрь вашей CustomView то сделать это просто.

public class CustomView extends LinearLayout {

    // other code

    private ViewPager viewPager;

    public void setPager(ViewPager pager) {
        viewPager = pager;
    }

    public CustomView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        // other code

        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
               if(pager == null) {
                   throw new IllegalStateException("Need set ViewPager with method setPager() before use it"
               } else {
                   // do something with pager
               }
        })
    }
}

В активити после того как вы вызвали метод findViewById на вашем педжере вызовете метод

customView.setPager(viewPager);
→ Ссылка