• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Change toolbar icon from PageViewer

HGamble

Lurker
My app uses a ViewPager to display quotations about certain topics. Each array of quotations is in a separate class, and the array is passed to the ViewPager from that class. The toolbar is also set in that class. The toolbar has a heart icon which when clicked adds the quotation to a ArrayList in a favourites activity. That part works fine. What I can't figure out is how to change the heart icon so that it is red after the quotation has been added to the favourites list. How can I access the toolbar from inside the PageViewer class?

Here is where I have the list of quotes about love, and where the toolbar is set.

Java:
public class Love extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Get the view from viewpager_main.xml
        setContentView(R.layout.viewpager_main);

        // String arrays with verses and corresponding references
        quotes = new String["quotation 1", "quotation 2"...] {//list of quotations};
       
        // Locate the ViewPager in viewpager_main.xml
        viewPager = (ViewPager) findViewById(R.id.pager);
        // Pass results to ViewPagerAdapter Class
        adapter = new ViewPagerAdapter(Love.this, quotes);
        // Binds the Adapter to the ViewPager
        viewPager.setAdapter(adapter);

Here is the code for my ViewPager. I need to access the Toolbar from here.

Java:
public class ViewPagerAdapter extends PagerAdapter {

    LayoutInflater inflater;

    public ViewPagerAdapter(Context context, String[] quotes) {
        this.context = context;
        this.quotes = quotes;
    }

    public ViewPagerAdapter(){}

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((RelativeLayout) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        // Declare Variables
        TextView textquotes;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View itemView = inflater.inflate(R.layout.viewpager_item, container,
                false);

        // Code to locate the TextView in viewpager_item.xml
        // Code to capture position and set to the TextView
       
        // Add viewpager_item.xml to ViewPager
        ((ViewPager) container).addView(itemView);
       
        // This is my problem:
        if (Favourites.favouritesArrayList.contains(quotes[position])){
            //How can I change the icon in the activity from here?
        })

        return itemView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // Remove viewpager_item.xml from ViewPager
        ((ViewPager) container).removeView((RelativeLayout) object);

    }
}
 
I'd do this by providing a utility method on the main Activity class (Love). Something like this:

Code:
public class Love extends AppCompatActivity {
  ...

  public changeToolbarIconColour() {
    // Code to change icon colour
  }
}

You invoke this method using the 'context' parameter passed into your ViewPagerAdapter class

Code:
public Object instantiateItem(ViewGroup container, int position) {
  ...
 
  if (Favourites.favouritesArrayList.contains(quotes[position])){
            //How can I change the icon in the activity from here?
            context.changeToolbarIconColour();
   })
}

There's information about how to change a toolbar icon here:

https://stackoverflow.com/questions...igation-and-overflow-menu-icons-appcompat-v7#
 
Thanks for the quick reply! I have written a new test method in my love class. But when I try to access that method using context as you explained above, I get the error message "cannot resolve method changeToolbarIconColour()".
Java:
public void changeToolbarIconColour() {
        // Code to change icon colour
        Context context = getApplicationContext();
        Toast toastAdded = Toast.makeText(context, "Colour change test", Toast.LENGTH_LONG);
        toastAdded.show();
    }
 
Use a cast operator

Code:
((Love)context).changeToolbarIconColour();
 
That resolved the error message. Only problem is that the same ViewPagerAdapter is used by more than one class. I have each topic of quotations in a separate class.
 
No problem. This code will only invoke the method if your context is a Love class

Code:
if (context instanceof Love) {
  ((Love)context).changeToolbarIconColour();
}
 
Right. But I have several classes all using the ViewPageAdapter

I have a MainActivity with a ListView of topics. When a topic is selected a new Activity is started Love.java, War.java, Family.java etc. These classes each have an array of quotations. Quotations from any of the classes can be added to the Favourites ArrayList.

The MainActivity has a one toolbar and the classes with the topics have a different toolbar. All of the topic classes use the same ViewPageAdapter. Within that class there is a check to see if the verse is in the Favourites ArrayList, and if it is then I need to change one icon on the toolbar. So I need to access the toolbar of whichever class is currently using the ViewPageAdapter.
 
Thinking... so maybe I just need a switch statement that includes all of the possible contexts. Is there an easier way to access the activity that is currently using the ViewPager?
 
No, you solve this using O-O principles i.e. inheritance. I'd do something like this:

Code:
                                       Activity
                                           |
                                      MyActivity
                                           |
                 ----------------------------------------------
                 |                         |                     |
         LoveActivity                   WarActivity         FamilyActivity

So MyActivity provides a method changeToolbarIconColour() and the child classes override that method, providing their own version of it.

Your Adapter class declares a class variable of type MyActivity. Then simply invoke the method. The correct class method will be called, depending what type of object you passed in to the constructor.


Code:
public class ViewPagerAdapter extends PagerAdapter {
  MyActivity context;

  public ViewPagerAdapter(Context context, String[] quotes) {
        this.context = context;
        this.quotes = quotes;
  }
  ...

  public Object instantiateItem(ViewGroup container, int position) {
    ...
     context.changeToolbarIconColour();
  }
  ...
}
 
Ah, that makes sense about the inheritance. I will change that next.

Currently I am just testing the toolbar with one of the topics. I can change the icon in the toolbar, but I have two problems.
  1. In the ViewPager, the current page, previous page and next page are already built. If I am on page 3 and I change the icon, I don't see the change until I scroll to page 5 (at which point page 3 is destroyed) and then scroll back to page 3.
  2. Once the icon does change colour, it changes for all pages.
Java:
if (Favourites.favouritesArrayList.contains(quotes[position])){
            if (context instanceof Love) {
                ((Love)context).changeToolbarIconColour();
            }
        })

Java:
public void changeToolbarIconColour() {
        // Code to change icon colour
    Drawable myDrawable = getResources().getDrawable(R.drawable.ic_action_favorite_red);
    MenuItem myItem = myToolbar.getMenu().findItem(R.id.action_favorite);
    myItem.setIcon(myDrawable);
    }
 
Back
Top Bottom