0

I have an activity in which some of the TextViews are empty at the beginning and are filled dynamically after data has been received from the server. The problem is that I can't see it on the screen, they are not refreshed! What can the problem be?

For example:

<TextView
android:id="@+id/answer_correctness_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:visibility="visible" />  

and

answerCorrectnessText.setText(R.string.correct_label);
answerCorrectnessText.setTextColor(R.color.correct_answer_color);

The space it occupies remains empty! Thanks.

Ok, here's all the code, hope someone can find the problem: The layout:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_height="fill_parent" android:layout_width="fill_parent">
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="vertical">
    <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:orientation="horizontal"> <!-- android:layout_weight="0.15"> -->
        <TextView android:id="@+id/question_text" android:layout_width="0dip"
            android:layout_height="fill_parent" android:layout_weight="0.9" 
            android:text="empty"/>
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:layout_gravity="right" android:text="@string/score_label"/>
        <TextView android:id="@+id/score_text" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:layout_gravity="right"
            android:layout_weight="0.1" android:paddingLeft="5dip"/>
    </LinearLayout>
    <RadioGroup android:id="@+id/answers_group" android:layout_width="fill_parent"
        android:layout_height="0dip" android:orientation="vertical" 
        android:layout_weight="0.6" android:visibility="invisible">
        <!-- May also be generated dynamically if the number of answers differs for each
             question -->
        <RadioButton android:id="@+id/answerA_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
        <RadioButton android:id="@+id/answerB_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
        <RadioButton android:id="@+id/answerC_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
        <RadioButton android:id="@+id/answerD_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
        <RadioButton android:id="@+id/answerE_button" android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
    </RadioGroup>
    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button android:id="@+id/answer_button" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="@string/answer_label"
            android:visibility="invisible"/>
        <TextView android:id="@+id/answer_correctness_text" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:visibility="invisible"
            android:layout_weight="0.2"/>
        <TextView android:id="@+id/correct_caption_text" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:text="@string/correct_answer_label"
            android:visibility="invisible"/>
        <TextView android:id="@+id/correct_text" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:visibility="invisible"
            android:layout_weight="0.2"/>
        <Button android:id="@+id/next_button" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="@string/next_label"
            android:visibility="invisible"/> 
    </LinearLayout>
    <TextView android:id="@+id/remark_text" android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/>
</LinearLayout>

The code:

package com.lightcone.webdatastreams;

import java.io.*;
import java.net.*;
import java.text.ParseException;
import java.util.*;

import android.app.*;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.*;
import android.widget.*;

public class POSTexample extends Activity {
    private static final String CHAPTERS_DATA_STATE_KEY="chaptersData";
    private static final String QUESTION_STATE_KEY="question";
    private static final String CHAPTER_STATE_KEY="chapter";
private static final String SCORE_STATE_KEY="score";

private static final int CORRECT_ANSWER_SCORE=10;
private static final int DEFAULT_CHAPTER=-1;
private static final int DEFAULT_SCORE=0;
private static final int NO_SUCH_CHAPTER_INDICATOR=-2;

// Set address for the questioner script on the server
public static final String host_url = 
    "http://csep10.phys.utk.edu/cgi-bin/quizforms/course1/questioner2.pl";  // Question script
public static final String TAG = "WEBSTREAM";

private ProgressDialog progDialog;
private int maxBarValue = 200; 
private Map<String,Object> postData;

private TextView questionText;
private TextView scoreText;
private RadioGroup answersGroup;
private RadioButton[] answerRadioButtons;
private Button answerButton;
private TextView answerCorrectnessText;
private TextView correctAnswerCaptionText,correctAnswerText;
private Button nextButton;
private TextView remarkText;

private HashMap<Integer,Integer> chaptersData;
private QuestionData question;
private int chapter=DEFAULT_CHAPTER;
private int score=DEFAULT_SCORE;
private boolean chapterNotExists;

/*private class ChapterData implements Serializable
{
    public int initialQuestionNum;
    public int currentQuestionNum;
}*/

private class QuestionData implements Serializable
{
    private static final long serialVersionUID=6800939332788597765L;

    public int questionNum;
    public String questionText;
    public String[] answers;
    public int correctAnswer;
    public String remark;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState!=null)
    {
        chapter=savedInstanceState.getInt(CHAPTER_STATE_KEY,DEFAULT_CHAPTER);
        score=savedInstanceState.getInt(SCORE_STATE_KEY,DEFAULT_SCORE);
        question=(QuestionData)savedInstanceState.getSerializable(
                QUESTION_STATE_KEY);
        chaptersData=(HashMap<Integer,Integer>)savedInstanceState.
                getSerializable(CHAPTERS_DATA_STATE_KEY);
    }
    if (chaptersData==null) 
        chaptersData=new HashMap<Integer,Integer>();

    setContentView(R.layout.postexample);
    questionText=(TextView)findViewById(R.id.question_text);
    scoreText=(TextView)findViewById(R.id.score_text);
    if (TextUtils.isEmpty(scoreText.getText()))
        scoreText.setText(String.valueOf(score));
    answersGroup=(RadioGroup)findViewById(R.id.answers_group);
    answersGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() 
    {
        @Override public void onCheckedChanged(RadioGroup group,int checkedId) 
        { if (!answerButton.isEnabled()) answerButton.setEnabled(true); }
    });
    /*The assumption is that there's a constant number of possible answers 
     *for each question, but the radio buttons could also be generated 
     *dynamically for each question*/
    answerRadioButtons=new RadioButton[5];
    answerRadioButtons[0]=(RadioButton)findViewById(R.id.answerA_button);
    answerRadioButtons[1]=(RadioButton)findViewById(R.id.answerB_button);
    answerRadioButtons[2]=(RadioButton)findViewById(R.id.answerC_button);
    answerRadioButtons[3]=(RadioButton)findViewById(R.id.answerD_button);
    answerRadioButtons[4]=(RadioButton)findViewById(R.id.answerE_button);
    answerButton=(Button)findViewById(R.id.answer_button);
    answerButton.setOnClickListener(new View.OnClickListener() 
    {   
        @Override public void onClick(View v) 
        {
            int checkedRadioButtonID=answersGroup.getCheckedRadioButtonId();
            String resourceName=getResources().getResourceName(
                    checkedRadioButtonID);
            char answerLetter=resourceName.charAt(resourceName.indexOf('_')-1);
            int userAnswer=answerLetter-'A';
            answerButton.setEnabled(false);
            if (question.correctAnswer==userAnswer)
            {
                score+=CORRECT_ANSWER_SCORE;
                scoreText.setText(String.valueOf(score));
                answerCorrectnessText.setText(R.string.correct_label);
                answerCorrectnessText.setTextColor(R.color.correct_answer_color);
                remarkText.setText(question.remark);
                remarkText.setVisibility(View.VISIBLE);
            }
            else
            {
                score+=CORRECT_ANSWER_SCORE;
                scoreText.setText(String.valueOf(score));
                answerCorrectnessText.setText(R.string.wrong_label);
                answerCorrectnessText.setTextColor(R.color.wrong_answer_color);
            }
            setAnswerComponentsState(false);
        }
    });
    answerCorrectnessText=(TextView)findViewById(R.id.answer_correctness_text);
    correctAnswerCaptionText=(TextView)findViewById(R.id.correct_caption_text);
    correctAnswerText=(TextView)findViewById(R.id.correct_text);
    nextButton=(Button)findViewById(R.id.next_button);
    nextButton.setOnClickListener(new View.OnClickListener() 
    {
        @Override public void onClick(View v) 
        {
            if (chaptersData.get(chapter)==question.questionNum+1)
                questionText.setText(R.string.no_more_questions_text);
            else new BackgroundLoad().execute(host_url);
        }
    });
    remarkText=(TextView)findViewById(R.id.remark_text);

    if (chapter==DEFAULT_CHAPTER)
    {
        Dialog chapterDialog=createChapterDialog();
        chapterDialog.show();
    }
}

@Override public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater inflater=getMenuInflater();
    inflater.inflate(R.menu.options_menu,menu);
    return true;
}

@Override public boolean onOptionsItemSelected(MenuItem item)
{
    switch (item.getItemId())
    {
        case R.id.change_chapter_item:
            Dialog chapterDialog=createChapterDialog();
            chapterDialog.show();
            return true;
        case R.id.reset_score_item:
            resetData();
            return true;
        default: return super.onOptionsItemSelected(item);
    }
}

private Dialog createChapterDialog()
{
    AlertDialog.Builder dialogBuilder=new AlertDialog.Builder(this);
    dialogBuilder.setTitle(null);
    LayoutInflater inflater=getLayoutInflater();
    /*ViewGroup container=(ViewGroup)chapterDialog.findViewById(android.
            R.id.custom);
    inflater.inflate(R.layout.change_chapter,container);*/
    View dialogView=inflater.inflate(R.layout.change_chapter,null);
    dialogBuilder.setView(dialogView);
    final EditText chapterEdit=(EditText)dialogView.findViewById(
            R.id.chapter_edit);
    if (chapter!=DEFAULT_CHAPTER) 
        chapterEdit.setText(String.valueOf(chapter));
    else chapterEdit.setText("1");
    final AlertDialog chapterDialog=dialogBuilder.create();
    Button okButton=(Button)dialogView.findViewById(R.id.chapter_ok_button);

    /*dialogBuilder.setPositiveButton(android.R.string.ok,new DialogInterface.
            OnClickListener()*/
    okButton.setOnClickListener(new View.OnClickListener()
    {   
        //@Override public void onClick(DialogInterface dialog,int which)
        @Override public void onClick(View view)
        { 
            chapterDialog.dismiss();
            int newChapter=Integer.parseInt(chapterEdit.getText().toString());
            if (chapter!=newChapter)
            {
                Log.i(TAG,"Here!!!");
                chapter=newChapter;
                chapterNotExists=false;
                if (postData==null) postData=new HashMap<String,Object>();
                postData.put("chapter",chapter);
                new BackgroundLoad().execute(host_url);
            }
        }
    });

    /*//The button does not exist even though we used setPositiveButton!?
    ViewGroup.LayoutParams layoutParams=chapterDialog.getButton(AlertDialog.
            BUTTON_POSITIVE).getLayoutParams();
    layoutParams.width=ViewGroup.LayoutParams.WRAP_CONTENT;*/
    return chapterDialog; 
}

private void resetData()
{
    score=0;
    scoreText.setText(String.valueOf(score));
    chaptersData.clear();
    if (question!=null) chaptersData.put(chapter,question.questionNum);
}

@Override protected void onSaveInstanceState(Bundle outState)
{
    super.onSaveInstanceState(outState);
    if (chapter!=DEFAULT_CHAPTER) outState.putInt(CHAPTER_STATE_KEY,chapter);
    if (score!=DEFAULT_SCORE) outState.putInt(SCORE_STATE_KEY,score);
    if (question!=null) 
        outState.putSerializable(QUESTION_STATE_KEY,question);
    if (chaptersData!=null) 
        outState.putSerializable(CHAPTERS_DATA_STATE_KEY,chaptersData);
}

// Implement query by POST method and return the response as a string.

private QuestionData doPOST(String host_url, Map<String,Object> data){ 
    QuestionData question=null;
    //Compose the request body
    StringBuilder requestBodyBuilder=new StringBuilder();
    for (String parameterName:data.keySet())
    {
        requestBodyBuilder.append(parameterName);
        requestBodyBuilder.append('=');
        requestBodyBuilder.append(data.get(parameterName));
        requestBodyBuilder.append('&');
    }
    requestBodyBuilder.deleteCharAt(requestBodyBuilder.length()-1);
    String requestBody=requestBodyBuilder.toString();

    //Connect and retrieve data
    URL url=null;
    HttpURLConnection httpConnection=null;
    BufferedWriter requestStream=null;
    BufferedReader responseStream=null;
    try
    {
        //Send request
        url=new URL(host_url);
        URLConnection connection=url.openConnection();
        if (!(connection instanceof HttpURLConnection))
            throw new IOException("Invalid HTTP connection: " + host_url);
        httpConnection=(HttpURLConnection)connection;
        httpConnection.setDoOutput(true);
        httpConnection.setFixedLengthStreamingMode(requestBody.length());
        requestStream=new BufferedWriter(new OutputStreamWriter(httpConnection.
                getOutputStream()));
        requestStream.write(requestBody);
        requestStream.close();

        // Extract the response status and the headers 
        int responseStatus = httpConnection.getResponseCode();
        Map<String,List<String>> headers=httpConnection.getHeaderFields();
        Log.i(TAG, "\nPOST response and headers:" );
        Log.i(TAG, "\nResponse="+headers.get(null));
        Log.i(TAG, "Response code = "+responseStatus);
        Iterator<String> headerNamesIterator=headers.keySet().iterator();
        /*Skip the first header, which is actually not a header but the 
         *status line of the response*/ 
        headerNamesIterator.next();
        while (headerNamesIterator.hasNext())
        {
            String headerName=headerNamesIterator.next();
        //for (String headerName:headers.keySet())
            for (String headerValue:headers.get(headerName))
                Log.i(TAG, "header="+headerName+" value="+headerValue);
        }

        //Get response body
        if (responseStatus==HttpURLConnection.HTTP_OK)
        {
            responseStream=new BufferedReader(new InputStreamReader(
                    httpConnection.getInputStream()));
            question=buildQuestionData(responseStream);
        }
    } 
    catch (IOException ioException)
    {
        Log.e(TAG,"Error occurred while trying to retrieve data from the " +
                "server!",ioException);
    }
    catch (ParseException parseException)
    {
        Log.e(TAG,"Error occurred while parsing the response received " +
                "from the server!",parseException);
        if (parseException.getErrorOffset()==NO_SUCH_CHAPTER_INDICATOR)
            chapterNotExists=true;
    }
    finally
    {
        if (requestStream!=null)
        {
            //The closing may occur twice if the stream was closed previously
            try { requestStream.close(); } 
            catch (IOException ioException) { }
        }
        if (responseStream!=null)
        {
            try { responseStream.close(); }
            catch (IOException ioException) { }
        }
        if (httpConnection!=null) httpConnection.disconnect();
    }
    return question;
}

private QuestionData buildQuestionData(BufferedReader responseStream) 
        throws IOException,ParseException
{
    //final String errorMessage="Invalid question data retrieved from server: ";
    String line=retrieveLine(responseStream);
    if (line.startsWith("<font"))
    {
        throw new ParseException("Chapter " + chapter + " does not exist! " +
                "No question was received.",NO_SUCH_CHAPTER_INDICATOR);
    }
    QuestionData question=new QuestionData();
    question.questionNum=extractIntParameter(line,"qnum",false);        
    line=retrieveLine(responseStream);
    question.questionText=extractStringParameter(line,"question",false);
    /*The assumption here is that there's a constant number of possible 
     *answers for each question, but it could also be dynamic*/
    question.answers=new String[5];
    int letterInt=(int)'A';
    for (int counter=0;counter<question.answers.length;counter++)
    {
        line=retrieveLine(responseStream);
        question.answers[counter]=extractStringParameter(line,"answer" + 
                (char)letterInt,false);
        letterInt++;
    }
    //Chapter number
    line=retrieveLine(responseStream);
    int receivedChapter=extractIntParameter(line,"chapter",false);
    if (chapter!=receivedChapter)
    {
        throw new ParseException("The chapter number of the question " +
                "received from the server (" + receivedChapter + 
                " is not equal to the chapter number requested (" + 
                chapter + ")!",-1);
    }
    //Correct answer
    line=retrieveLine(responseStream);
    String correctAnswerStr=extractStringParameter(line,"coran",false);
    if (correctAnswerStr.length()>1)
    {
        throw new ParseException("The correct answer must be one " + 
                "letter only!",-1);
    }
    char correctAnswer=correctAnswerStr.charAt(0);
    char lastValidLetter=(char)((int)'A'+question.answers.length);
    if ((correctAnswer<'A')||(correctAnswer>lastValidLetter))
    {
        throw new ParseException("The correct answer must be between A and " +
                lastValidLetter + "! It's actually equal to " + correctAnswer,-1); 
    }
    question.correctAnswer=correctAnswer-'A';
    //Remark
    line=retrieveLine(responseStream);
    question.remark=extractStringParameter(line,"amp",false);
    return question;
}

private String retrieveLine(BufferedReader responseStream) throws 
        IOException,ParseException
{
    String line=responseStream.readLine();
    if (line==null) throw new ParseException("Unexpected end of data!",-1);
    else return line;
}

private String extractDataParameter(String data,String parameterName) 
        throws ParseException
{
    int separator=data.indexOf('=');
    if (separator==-1)
    {
        throw new ParseException("Invalid data! Parameter value could " + 
                "not be found: " + data,-1);
    }
    if (!data.substring(0,separator).equals(parameterName))
        throw new ParseException("Missing parameter: " + parameterName,-1);
    return data.substring(separator+1); 
}

private int extractIntParameter(String data,String parameterName,boolean 
        isNegativeAllowed) throws ParseException 
{
    String parameterValueStr=extractDataParameter(data,parameterName);
    int parameterValue=-1; boolean isValidNumber=true;
    try { parameterValue=Integer.parseInt(parameterValueStr); }
    catch (NumberFormatException numberException) { isValidNumber=false; }
    if ((isValidNumber)&&(!isNegativeAllowed)&&(parameterValue<0)) 
        isValidNumber=false;
    if (!isValidNumber)
        throw new ParseException("Parameter " + parameterName + " is invalid!" +
                "Either it's non-numeric, or is a negative number and only " + 
                "positive numbers are allowed: " + parameterValueStr,-1);
    return parameterValue;
}

private String extractStringParameter(String data,String parameterName,
        boolean isEmptyAllowed) throws ParseException 
{
    String parameterValue=extractDataParameter(data,parameterName).trim();
    if ((!isEmptyAllowed)&&(parameterValue.equals("")))
    {
        throw new ParseException("Parameter " + parameterName + " is an " + 
                "empty string!",-1);
    }
    return parameterValue;
}

private void handleResultQuestionData(QuestionData question)
{
    if (question!=null)
    {
        this.question=question;
        if (!chaptersData.containsKey(chapter))
            chaptersData.put(chapter,question.questionNum);
        questionText.setText(question.questionText);
        for (int index=0;index<question.answers.length;index++)
            answerRadioButtons[index].setText(question.answers[index]);
        answersGroup.clearCheck();
        answersGroup.setVisibility(View.VISIBLE);
        answerButton.setVisibility(View.VISIBLE);
        answerButton.setEnabled(false);
        setAnswerComponentsState(true);
        remarkText.setVisibility(View.INVISIBLE);
    }
    else
    {
        AlertDialog.Builder dialogBuilder=new AlertDialog.Builder(this);
        if (chapterNotExists)
        {
            dialogBuilder.setMessage(R.string.chapter_not_exists_text);
            dialogBuilder.setPositiveButton(android.R.string.ok,
                    new DialogInterface.OnClickListener() 
            {   
                @Override public void onClick(DialogInterface dialog,int which) 
                { dialog.dismiss(); }
            });
        }
        else
        {
            dialogBuilder.setMessage(R.string.question_not_retrieved_text);
            DialogInterface.OnClickListener listener=new DialogInterface.
                    OnClickListener() 
            {
                @Override public void onClick(DialogInterface dialog,int which) 
                {
                    dialog.dismiss();
                    switch (which)
                    {
                        case Dialog.BUTTON_POSITIVE: 
                            new BackgroundLoad().execute(host_url);
                            break;
                        case Dialog.BUTTON_NEGATIVE: finish(); break;
                    }
                }
            };
            dialogBuilder.setPositiveButton(R.string.try_again_label,listener);
            dialogBuilder.setNegativeButton(R.string.exit_label,listener);
        } //end else (if chapterNotExists)
        dialogBuilder.show();
    } //end else (if question!=null)
}

private void setAnswerComponentsState(boolean beforeAnswer)
{
    int visibility=(beforeAnswer?View.INVISIBLE:View.VISIBLE);
    answerCorrectnessText.setVisibility(visibility);
    correctAnswerCaptionText.setVisibility(visibility);
    correctAnswerText.setVisibility(visibility);
    nextButton.setVisibility(visibility);
}

// Method to create a progress bar dialog of either spinner or horizontal type
@Override
protected Dialog onCreateDialog(int id) {
    switch(id) {
    case 0:                      // Spinner
        progDialog = new ProgressDialog(this);
        progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progDialog.setMessage("Loading...");
        return progDialog;
    case 1:                      // Horizontal
        progDialog = new ProgressDialog(this);
        progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progDialog.setMax(maxBarValue);
        progDialog.setMessage("Loading...:");
        return progDialog;
    default:
    return null;
    }
}

// Use AsyncTask to perform the web download on a background thread.  The three
// argument types inside the < > are a type for the input parameters (Strings in this case), 
// a type for any published progress during the background task (Void in this case,  because
// we aren't going to publish progress since the task should be very short), and a type
// for the object returned from the background task (in this case it is type String).

private class BackgroundLoad extends AsyncTask <String, Void, QuestionData>{

    // Executes the task on a background thread
    @Override
    protected QuestionData doInBackground(String... params) {

        // The notation String... params means that the input parameters are an array of
        // strings.  In new BackgroundLoad().execute(host_url) above we are
        // passing just one argument, so params[0] will correspond to host_url. 

        return doPOST(params[0], postData);

    }

    // Executes before the thread run by doInBackground
    protected void onPreExecute () {
         // Call method to create a progress dialog defined by onCreateDialog()
        showDialog(0);
    }

    // Executes after the thread run by doInBackground has returned. The variable s
    // passed is the string value returned by doInBackground.

    @Override
    protected void onPostExecute(QuestionData question){
        // Stop the progress dialog
        dismissDialog(0);   
        // Process the response
        handleResultQuestionData(question);
    }   
}

}
4

3 回答 3

1

Try setting text color using

answerCorrectnessText.setTextColor(getResources().getColor(R.color.correct_answer_color));

于 2012-05-04T08:35:32.903 回答
0

Have you tried to call answerCorrectnessText.invalidate() after setText and setTextColor ?

于 2012-05-04T07:48:02.430 回答
0

Try android:text="" in your textview. It should work

于 2012-05-04T07:52:01.270 回答