从当前位置开始倒序循环数组

3

我对Java和Android都还很陌生,请耐心等待我的问题。我有一个XML布局,其中包含两个按钮。一个按钮上显示着“previous”文本,另一个是“next”。我还有一个类,其中包含一个字符串数组,在单击“next”按钮时以升序循环在textView中。

我想要的是当单击“previous”按钮时,将数组从其当前位置逆向循环。有什么好的建议吗?

问题类

// This file contains questions from QuestionBank
class Question{
    // array of questions
    private String mQuestions [] = {
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
    // method returns number of questions
    int getLength(){
        return mQuestions.length;
    }

    // method returns question from array textQuestions[] based on array index
    String getQuestion(int a) {
        return mQuestions[a];
    }
}

Main Activity.java

     public class MainActivityextends AppCompatActivity {
                private QuestionLibraryBeginner mQuestionLibrary = new QuestionLibraryBeginner();
                private int mQuestionNumber = 1; // current question number
            //initialising navigation buttons
                private Button mPrevious;
                private Button mNext;
            private TextView mQuestionText;
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_beginner_review);
                    mPrevious = (Button) findViewById(R.id.previous);
                    mNext = (Button) findViewById(R.id.next);
  mQuestionText = (TextView) findViewById(R.id.txtQuestion);
                    // receive the current question number from last activity by Intent


        Intent intent = getIntent();
             currentQuestionNumber = intent.getIntExtra("quizNumber", 0); // receiving the number of questions the user has attempted from previous activity
                    mNext.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
    // checking against total number of questions the user has attempted instead of total number of questions from Question Class
    if (mQuestionNumber < currentQuestionNumber) {
             updateQuestion();
                        }
                    });
                    mPrevious.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
            // i want it to loop backwards from here
                        }
                    });

            // logic to update question from array
                private void updateQuestion() {
                    if (mQuestionNumber < mQuestionLibrary.getLength()) {
                        mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
                        mQuestionNumber++;
                    }
                }

            }

你尝试过使用大于条件和递减运算符吗? - Vivek Mishra
是的,但我也需要我的数组中的字符串在我的textView中向后循环。 - Bennykeys
5个回答

0
我建议这样做:
1)将updateQuestion方法重命名为nextQuestion 2)创建一个方法来减少mQuestionNumber,如下所示:
private void prevQuestion(){
    if(mQuestionNumber > 0){
    mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
    mQuestionNumber--;}
}

@Bennykeys 由于原始代码中的 "updateQuestion" 在显示项目后会递增 mQuestionNumber,因此我决定做同样的事情,因为我不确定这是否是预期的方式(第一次单击按钮时显示旧值,下一次单击将显示递减的值)。对我而言,在更新 TextView 之前递增/递减 int 变量会更有用。 - Jesper
在将逻辑放置在“mPrevious”按钮后,单击“mNext”按钮时没有任何反应。为什么会这样? - Bennykeys
@Bennykeys 因为你试图在一个地方做太多的事情,需要解耦,看看我的简洁解决方案,并阅读一些关于面向对象编程原则的内容。 - fxrbfg
@BennyKeys 只要我不看到您具体所做的事情,就无法确定为什么它不起作用。但我认为 fxrbfg 是正确的。解耦是最干净的解决方案。 - Jesper
糟糕,这是我在展示代码时提交的一个错误。 - Bennykeys
显示剩余2条评论

0
我会更改以下方法:
从update question中删除mQuestionNummer++;
您可以直接在NextButton的onClickMethode中增加mQuestions。
因此,您可以通过在previous Button的onClick中减少mQuestion--来简单地实现您的解决方案。
代码将如下所示:
public class MainActivityextends AppCompatActivity {
    private QuestionLibraryBeginner mQuestionLibrary = new 
    QuestionLibraryBeginner();
    private int mQuestionNumber = 1; // current question number
    //initialising navigation buttons
    private Button mPrevious;
    private Button mNext;
    private TextView mQuestionText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_beginner_review);
        mPrevious = (Button) findViewById(R.id.previous);
        mNext = (Button) findViewById(R.id.next);
        // receive the current question number from last activity by Intent
        Intent intent = getIntent();
        mNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            if (mQuestionNumber < mQuestionLibrary.getLength()) {
                mQuestionNumber++;
                updateQuestion();
            }
        });
        mPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // i want it to loop backwards from here
                            if(mQuestionNumber > 0){
                                mQuestionNumber--;
                                updateQuestion();
                            }
                            else
                                {}//don't do anything to prevent IndexOutOfBounds
            }
    });

    // logic to update question from array
    private void updateQuestion() {
        if (mQuestionNumber < mQuestionLibrary.getLength()) {
            mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
        }
    }

}

谢谢你的回复。不过根据我更新后的代码,现在我是检查用户尝试的问题数而不是数组长度。你的逻辑在这种情况下不起作用。 - Bennykeys

0

这是一个解决边界问题的方案

mNext.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(final View view) {
        showNextQuestion();
    }
});
mPrevious.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(final View view) {
        showPreviousQuestion();
    }
});

private void showNextQuestion() {
    showQuestion(1);
}

private void showPreviousQuestion() {
    showQuestion(-1);
}

private void showQuestion(int increment) {
    int newQuestionNumber = mQuestionNumber + increment;
    if (newQuestionNumber >= 0 && newQuestionNumber < mQuestionLibrary.getLength()) {
        mQuestionNumber = newQuestionNumber;
        mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
    }
}

0

只需添加一个flag来指定移动即可完成,

mNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateQuestion(true); 
        });
mPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateQuestion(false);
            }
        });

而这个方法看起来会像这样:

private void updateQuestion(boolean forward) {
        if(forward && mQuestionNumber < mQuestionLibrary.getLength())
            mQuestionNumber++
        else if (mQuestionNumber>1)
            mQuestionNumber--;
        mQuestionText.setText(mQuestionLibrary.getQuestion(mQuestionNumber));
}

当我到达最后一个项目时,为什么使用您的代码会出现ArrayIndexOutOfBoundException异常? - Bennykeys

0
你需要将应用程序的逻辑与视图逻辑分离,不要混淆它们。只需使Question类能够提供前一个和后一个问题即可。此外,根据面向对象编程原则(SOLID、GRASP),从类中获取信息并在外部做出决策是错误的,应该让类自己完成工作。面向对象编程是关于告诉类去做事情,而不是代替它们工作。
class Questions {
    private int index = 0;

    private String[] mQuestions;

    //better to don't hardcode and provide questions in constructor
    public Question(String[] questions) {
        this.questions = questions;

    }

    //we don't need this method
    int getLength(){
        return mQuestions.length;
    }


    //provide human readable information about current position in question list
    // when you want to provide this information to user introduce label field in activity
    public String currentPosition() {
        int questionPosition = index + 1;
        int questionsLength = mQuestions.length;
        return String.format("current question number is %d from %d" , questionPosition, questionsLength);
    }


    //return next question when available, if next not available returns last question from array
    public String next() {
        int lastIndex = mQuestions.length - 1;
        if(index < lastIndex) {
            index++;
        }
        return mQuestions[index];
    }

    //return current question
    public String current() {
        return mQuestions[index];
    }

    //return previous question when available, if previous not available returns first question from array
    public String previous() {
        int firstIndex = 0;
        if(index > firstIndex) {
            index--;
        }
        return mQuestions[index];

    }

}

如何在Activity中使用它:

public class MainActivity extends AppCompatActivity {
    //better to don't hardcode here, but provide this class from
    //constructor of MainActivity just like questions array provide 
    // to constructor in Questions class
    private Questions questions = new Questions(new String[]{"q1","q2"});
    private Button mPrevious;
    private Button mNext;
    private TextView mQuestionText;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_beginner_review);
        mPrevious = (Button) findViewById(R.id.previous);
        mNext = (Button) findViewById(R.id.next);
        Intent intent = getIntent();

        //when create Activity populate question field with first question
        mQuestionText.setText(questions.current());

        mNext.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mQuestionText.setText(questions.next());
            }
        });


        mPrevious.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mQuestionText.setText(questions.previous());
            }
        });
    }
}

顺便说一下,您可以进一步改进此代码,以引入观察者模式,Activity是视图,Questions是模型。


谢谢您的建议。我会尝试的。不过,我有一个重要的问题。 - Bennykeys
如果我检查用户尝试的问题总数而不是从我的QuestionClass中获取数组长度,会怎样呢? - Bennykeys
如果您查看我上面更新的代码,您会发现我传递了用户在之前活动中尝试的问题数量,这意味着问题将限制为尝试的总问题数。 - Bennykeys
如果我按照你的建议解耦我的逻辑,那么这会如何影响你的逻辑呢?因为我无法从模型类中获取Intent。 - Bennykeys
@Bennykeys,您需要将状态保留在Questions类中,而不是在Activity、Intent等中,并通过捆绑包在各个Activity之间传递它。 - fxrbfg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接