Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Android Build an Interactive Story App (Retired) Finishing the User Interface Ending the Story

Eleni Minadaki
Eleni Minadaki
3,687 Points

Problem with my Second Button

Hi and Happy New Year to everyone! I have finish the interactiveStory app but I have a problem with the Button choice2. When I tap to load the previous page, loads only the 1st page and not the others. Below is my code from StoryActivity.java Thanks for any help! (I am using Android 1.5.1)

import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.eleni.interactivestory.R;
import com.example.eleni.interactivestory.model.Page;
import com.example.eleni.interactivestory.model.Story;

import static android.widget.TextView.*;

public class StoryActivity extends AppCompatActivity {

    public static final String TAG = StoryActivity.class.getSimpleName();


    private Story mStory = new Story();
    private ImageView mImageView;
    private TextView mTextView;
    private Button mChoice1;
    private Button mChoice2;
    private String mName;
    private Page mCurrentPage;
    private Page mPeviousPage;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_story2);


        Intent intent = getIntent();
        mName = intent.getStringExtra(getString(R.string.key_name));

        if(mName == null){
            mName = "Friend";
        }

        Log.d(TAG, mName);

        mImageView = (ImageView)findViewById(R.id.storyImageView);
        mTextView = (TextView)findViewById(R.id.storyTextView);
        mChoice1 = (Button)findViewById(R.id.choiceButton1);
        mChoice2 = (Button)findViewById(R.id.choiceButton2);

        loadPage(0);
    }
    private void loadPage(int choice){
     mCurrentPage = mStory.getPage(choice);


        Drawable drawable  = getResources().getDrawable(mCurrentPage.getImageId());
        mImageView.setImageDrawable(drawable);

        String pageText = mCurrentPage.getText();
        //add the name if placeholder included.
        pageText  = String.format(pageText,mName);
        mTextView.setText(pageText);

        if(mCurrentPage.isFinal()){
            mChoice1.setVisibility(View.INVISIBLE);
            mChoice2.setText("Start From The Begining");
            mChoice2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   finish();
                }
            });

        }else{

        mChoice1.setText(mCurrentPage.getChoice1().getText());
        mChoice2.setText(mCurrentPage.getChoice2().getText());

       mChoice1.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               mCurrentPage.getChoice1().getNextPage();
               int nextPage = mCurrentPage.getChoice1().getNextPage();
               loadPage(nextPage);
           }
       });

        mChoice2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCurrentPage.getChoice2().getPreviousPage();
                int PreviousPage = mCurrentPage.getChoice2().getPreviousPage();
                loadPage(PreviousPage);
            }
        });


    }
}}
Harry James
Harry James
14,780 Points

Hey Eleni!

Happy New Year to you as well! ;)

Could you please provide your Choice and Page classes here as well so that I can take a look at what's going on?


Speak to you soon :)

7 Answers

Harry James
Harry James
14,780 Points

Hey Eleni!

It looks like the issue is being caused because you are trying to getPreviousPage() when mPreviousPage does not have a value (You haven't set this anywhere).

However, it looks like you're taking the course in a slightly different route - which I do not know whether you meant intentionally or not.

In the Treehouse course, we are given two Choices, and each Choice has a next Page which it leads to. These two choices are also the two Buttons, and Each Choice has a text for each Button (mText).

In your code, you have two Choices but your Choice classes also contain a Previous Page, which is not part of the course.


This leaves you two options:

  1. You can follow along with the course as-is, and remove the previous page code.
  2. You can change the course a bit and instead of having two choices, have a singular Choice that has both a previous and next page. Note that "Choice" probably wouldn't be the best name for the class in this instance, since there is actually two choices. You should probably refactor the class to call it "Choices" if you choose this method.

Hopefully this should help you out and get you back on track. I'll also provide you with the code files used in my InteractiveStory project if you require it. You can also download the Project Files at this stage and use this code instead to carry on with the future videos without having to make any amendments yourself (I recommend you try and fix your code yourself first though - it's a good learning experience, and it happens to everyone! Use this as a last-resort if you still can't get things working).

As always, if there's anything you don't quite understand about what I'm saying or if you want more guidance on how to fix the issue without having to re-download the files, give me a shout and let me know which route you want to take. I'll provide some steps to get your code back up to shape :)

Eleni Minadaki
Eleni Minadaki
3,687 Points

Yes,of course. Thanks a lot Harry.

Page.java
public class Page {
    private int mImageId;
    private String mText;
    private Choice mChoice1;
    private Choice mChoice2;
    private Choice mChoice3;
    private boolean mIsFinal = false;

    public Page(int imageId, String text, Choice choice1, Choice choice2){
        mImageId = imageId;
        mText = text;
        mChoice1 = choice1;
        mChoice2 = choice2;


    }

    public boolean isFinal() {

        return mIsFinal;
    }

    public void setIsFinal(boolean isFinal) {

        mIsFinal = isFinal;
    }

    public Choice getChoice3() {
        return mChoice3;
    }

    public void setChoice3(Choice choice3) {
        mChoice3 = choice3;
    }

    public Page(int imageId, String text){
        mImageId = imageId;
        mText = text;
        mChoice1 = null;
        mChoice2 = null;
        mChoice3 = null;
        mIsFinal = true;
    }

    public int getImageId() {
        return mImageId;
    }

    public void setImageId(int imageId) {
        mImageId = imageId;
    }

    public String getText() {
        return mText;
    }

    public void setText(String text) {
        mText = text;
    }

    public Choice getChoice1() {
        return mChoice1;
    }

    public void setChoice1(Choice choice1) {
        mChoice1 = choice1;
    }

    public Choice getChoice2() {
        return mChoice2;
    }

    public void setChoice2(Choice choice2) {
        mChoice2 = choice2;
      }
    }
Choice.java
public class Choice {
    private String mText;
    private int mNextPage;
    private int mPreviousPage;

    public Choice(String text, int nextPage){
        mText = text;
        mNextPage = nextPage;
       // mPreviousPage = previousPage;

    }

    public String getText() {

        return mText;
    }

    public void setText(String text) {

        mText = text;
    }

    public int getNextPage() {

        return mNextPage;
    }
    public void setNextPage(int nextPage){
        mNextPage = nextPage;
    }

    public int getPreviousPage() {
        return mPreviousPage;
    }

    public void setPreviousPage(int previousPage) {
        mPreviousPage = previousPage;
    }
}
Eleni Minadaki
Eleni Minadaki
3,687 Points

Hello Harry, truly thank you for your very detailed answer. Is very helpful for me, a newbie. I download the files you upload. I am sorry but is something I didn't understand. What should I do to have the ability the 2nd Button loads previous pages? I Follow the lessons, but now I am trying to make a simple app based on InteractiveStory lessons for practice.The only thing I need to change from the lesson is this: The 1st button loads each time a next page as it is now, but how can it loads the previous?What should I write? Thanks again.

Harry James
Harry James
14,780 Points

Hey Eleni!

I think a visual representation will show what happens in the two scenarios better. I've created one and provided it below for you:


Let me know if this explains what's going on a bit better! :)

Eleni Minadaki
Eleni Minadaki
3,687 Points

That looks amazing!!!! I will study it and I 'll let you know. Thanks so much!

Eleni Minadaki
Eleni Minadaki
3,687 Points

Hi again Harry! The diagram you sent me was very helpful to understund thinks I didn't. I need to choose the option2. Still be little confused to where and what should I write for to have the ability to see previous page each time the button has tapped. That moment, my 1st button change properly pages and the 2nd goes only 1 time back. Need to make 2nd button change in sequence previous pages. Thanks again! Below is my code after correct:

StoryActivity.java
  public static final String TAG = StoryActivity.class.getSimpleName();


    private Story mStory = new Story();
    private ImageView mImageView;
    private TextView mTextView;
    private Button mChoice1;
    private Button mChoice2;
    private String mName;
    private Page mCurrentPage;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_story2);


        Intent intent = getIntent();
       // mName = intent.getStringExtra(getString(R.string.key_name));

        if(mName == null){
            mName = "Friend";
        }

        Log.d(TAG, mName);

        mImageView = (ImageView)findViewById(R.id.storyImageView);
        mTextView = (TextView)findViewById(R.id.storyTextView);
        mChoice1 = (Button)findViewById(R.id.choiceButton1);
        mChoice2 = (Button)findViewById(R.id.choiceButton2);

        loadPage(0);
    }
    private void loadPage(int choice){
     mCurrentPage = mStory.getPage(choice);


        Drawable drawable  = getResources().getDrawable(mCurrentPage.getImageId());
        mImageView.setImageDrawable(drawable);

        String pageText = mCurrentPage.getText();
        //add the name if placeholder included.
       // pageText  = String.format(pageText,mName);
        mTextView.setText(pageText);

        if(mCurrentPage.isFinal()){
            mChoice1.setVisibility(View.INVISIBLE);
            mChoice2.setText("Start From The Begining");
            mChoice2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   finish();
                }
            });

        }else{

        mChoice1.setText(mCurrentPage.getChoice1().getText());
        mChoice2.setText(mCurrentPage.getChoice2().getText());

       mChoice1.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               mCurrentPage.getChoice1().getNextPage();
               int nextPage = mCurrentPage.getChoice1().getNextPage();
               loadPage(nextPage);
           }
       });

        mChoice2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCurrentPage.getChoice2().getNextPage();
                int nextPage = mCurrentPage.getChoice2().getNextPage();
                loadPage(nextPage);
            }
        });


    }
}}
Page.java
public class Page {
    private int mImageId;
    private String mText;
    private Choice mChoice1;
    private Choice mChoice2;
    private boolean mIsFinal = false;

    public Page(int imageId, String text, Choice choice1, Choice choice2){
        mImageId = imageId;
        mText = text;
        mChoice1 = choice1;
        mChoice2 = choice2;


    }
    public Page(int imageId, String text){
        mImageId = imageId;
        mText = text;
        mChoice1 = null;
        mChoice2 = null;
        mIsFinal = true;
    }



    public int getImageId() {
        return mImageId;
    }

    public void setImageId(int imageId) {
        mImageId = imageId;
    }

    public String getText() {
        return mText;
    }

    public void setText(String text) {
        mText = text;
    }

    public Choice getChoice1() {
        return mChoice1;
    }

    public void setChoice1(Choice choice1) {
        mChoice1 = choice1;
    }

    public Choice getChoice2() {
        return mChoice2;
    }

    public void setChoice2(Choice choice2) {
        mChoice2 = choice2;
    }

        public boolean isFinal() {

            return mIsFinal;
        }

        public void setIsFinal(boolean isFinal) {

            mIsFinal = isFinal;
        }
      }
Choice.java
public class Choice {
    private String mText;
    private int mNextPage;


    public Choice(String text, int nextPage) {
        mText = text;
        mNextPage = nextPage;

    }

    public String getText() {

        return mText;
    }

    public void setText(String text) {

        mText = text;
    }

    public int getNextPage() {

        return mNextPage;
    }

    public void setNextPage(int nextPage) {
        mNextPage = nextPage;
    }

}
Harry James
Harry James
14,780 Points

Hey Eleni!

Just posting this to let you know that I will put a new answer up in the next couple days (Sunday at the latest) - I'm currently busy preparing for an interview :)

Eleni Minadaki
Eleni Minadaki
3,687 Points

Hi Harry! Thanks a lot that you let me know. Don't worry, when ever you have time. You have already help me a lot! Good luck with the interview!

Harry James
Harry James
14,780 Points

Hey again Eleni,

Thanks a lot :)

I've gone ahead and updated the project to suit your scenario. You can view all of the changes on GitHub here.

You can feel free to use this code by forking my project into Android Studio. Ben has an awesome workshop that shows how to do this if you're interested.

Alternatively, you can look at the changes I have made in each file and make them changes manually yourself. Here's a quick summary of what I've done in the Refactored to use Previous/Next rather than Choice1 and Choice2... commit:

  • Refactored Choice.java as Choices.java.
  • New member variables in Choices.java: mPreviousPage and mNextPage, both are private integers.
  • Removed mText member variable. Added mText1 and mText2 member variables, both are private Strings.
  • Choices() constructor change - parameters are: int PreviousPage, String text1, int nextPage, String text2.
  • Inside constructor, all member variables are set.

  • Updated Page.java.

  • Changes to allow refactoring.

  • Removed references to mChoice1 and mChoice2. Instead, using mChoices from the Choices class.

  • Updated Story.java

  • Class utilizes new Choices class and constructor.

  • Updated StoryActivity.java and activity_story.xml

  • Changes to allow refactoring. Using getNextPage() and getPreviousPage() from getChoices().

  • Refactored mChoice and choiceButton as previousButton and nextButton.


A few other changes were also made in the Using previous/next pages commit if you would like each page to link to the hierarchical previous/next pages (Current page - 1 and Current page + 1).

  • Updated Choices.java so that no longer do we need to hard-code the previous and next pages. Instead, just specify the current page and the program will calculate the previous and next pages.

  • Updated Page.java to allow implementation.

  • Added member variable mPageId optionally.

  • Optional first constructor change.

  • Optional second constructor change.

  • Page() second constructor change - Refactored mIsFinal as mIsSingle.

  • Generated getters/setters for mPageId optionally.

  • Updated Story.java to follow new implementation.

  • This code could probably be refactored, there's a lot of repetition here.

  • Updated StoryActivity.java to allow implementation.

  • Refactored isFinal() as isSingle()

  • Added if statement to only getChoices() when the page is not a single page. Single pages do not have choices and so this would throw an Exception.


Hope it helps and if there's anything else, give me a shout :)

Eleni Minadaki
Eleni Minadaki
3,687 Points

Hi Harry! It couldn't be better! I wrote the code manually not copy - paste, from Github and it was very very helpful for me. Thanks a lot for your very important help and for the time to spend to answer me.