javaandroidandroid-viewpagerandroid-pageradapter

Android - Can't update textview within View Pager Adapter


I have a counter view which should update as user touch minus and plus buttons.

I'm trying to update counter within ViewPager's adapter instantiateItem method, but it doesn't make any effect.

I can update it's value only in instantiateItem. Is there any way to setText() outside of instantiateItem? Sorry for dumb question, i'm a newbie in Android.

public class OrderVPAdapter extends PagerAdapter implements View.OnClickListener {

    private ArrayList<SomeItem> list;
    private Context context;

    public TextView counterView;
    View view;

    // I skipped some code for better understanding

    int counter = 0;

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        LayoutInflater layoutInflater = LayoutInflater.from(context);

        view = layoutInflater.inflate(R.layout.vp_item, container, false);

        counterView = view.findViewById(R.id.counter);

        Button plus, minus;
        plus = view.findViewById(R.id.btn_plus);
        plus.setOnClickListener(this);

        minus = view.findViewById(R.id.btn_minus);
        minus.setOnClickListener(this);

        container.addView(view, 0);

        return view;
    }

    @Override
    public void onClick(View view) {
        if(view.getId() == R.id.btn_plus) {
            counter++;
        }
        else {
            if(counter > 0)
                counter--;
        }
        counterView.setText(counter);
    }

Solution

  • It's a good question for beginners Ian, check my comments for each change I have made:

    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.viewpager.widget.PagerAdapter;
    
    public class OrderVPPageAdapter extends PagerAdapter {
    
        // 10 counters, one for each page
        int[] counter = new int[10];
    
        @Override
        public int getCount() {
            return 10;
        }
    
        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
            return o == view;
        }
    
        @NonNull
        @Override
        public Object instantiateItem(final ViewGroup container, int position) {
            LayoutInflater layoutInflater = LayoutInflater.from(container.getContext());
            View view = layoutInflater.inflate(R.layout.vp_item, container, false);
    
            // counterView needs to be local variable so it can serve as          
            // reference for each page when updated inside buttons' OnClickListener
            TextView counterView = view.findViewById(R.id.counter);
            Button plus = view.findViewById(R.id.btn_plus);
            Button minus = view.findViewById(R.id.btn_minus);
    
            // Set up counter value every time as this method will be 
            // called and update UI whenever you swipe between pages
            counterView.setText(String.valueOf(counter[position]));
    
            plus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // Update specific page counter in array position
                    counter[position]++;
                    counterView.setText(String.valueOf(counter[position]));
                }
            });
    
            minus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (counter[position] > 0)
                        counter[position]--;
                    counterView.setText(String.valueOf(counter[position]));
                }
            });
    
            container.addView(view);
    
            return view;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, @NonNull Object object) {
            container.removeView((View) object);
        }
    }