问题
Im trying to work out the best way to approach the following problem with Android.
I have data coming from a content provider in the form of an array of Question objects. A Question object has some text and an id. Each question has 4 answers, which will be sent back to the rest server in a QuestionResponse object.
Id like the questions to be displayed one at a time in a view (user reads question, selects answer, and then hits "next", which moves to the next question on a new screen) but I need to do this in the same way as a ListView does in terms of registering a content observer (as the questions may change on the server, which in turn updates them in the content provider.) Changes in the data stored in the content provider should update the questions on screen as they happen.
I guess that what i need is something like a SimpleCursorAdaptor, but instead of the view being a listview, i need the view to be a full screen representation of one of the rows that the cursor points to. Ive tried making my own adapter, but im getting a bit stuck as to where to go next. Here is my adapter....
public class QuestionAdapter implements Adapter {
public ArrayList<Question> questions = new ArrayList<Question>();
private Context context ;
public QuestionAdapter(ArrayList<Question> questions, Context context)
{
this.questions.clear();
this.questions.addAll(questions);
this.context = context;
}
public void updateQuestions(ArrayList<Question> questions)
{
questions.clear();
questions.addAll(questions);
}
@Override
public int getCount() {
return questions.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return questions.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return Long.parseLong(questions.get(arg0).get_id());
}
@Override
public int getItemViewType(int arg0) {
// TODO Auto-generated method stub
return IGNORE_ITEM_VIEW_TYPE;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View questionView = inflater.inflate(R.layout.question, parent);
return questionView;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return questions.isEmpty();
}
@Override
public void registerDataSetObserver(DataSetObserver arg0) {
// TODO Auto-generated method stub
}
@Override
public void unregisterDataSetObserver(DataSetObserver arg0) {
// TODO Auto-generated method stub
}
}
And here is my view question.xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/questionText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_weight="0.27"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TableLayout
android:id="@+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ToggleButton
android:id="@+id/passButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Pass"
android:textOff="Pass" />
<ToggleButton
android:id="@+id/advisoryButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Advisory"
android:textOff="Advisory" />
<ToggleButton
android:id="@+id/defectButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Defect"
android:textOff="Defect"/>
<ToggleButton
android:id="@+id/naButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="N/A"
android:textOff="N/A" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Next..." />
</LinearLayout>
回答1:
Here is an educated guess at what might work.
I'm not sure if there are other view's that are easy to bind to like a listview, so I'll try and modify your example to work with a listview. First, If you make the Listview itself fill_parent and make the child item inside the listview Fill_parent, you'll basically end up with a listview that can display one child item only. Then you can try the following:
Alter getCount
I believe getCount(...)
is used to determine how many rows of data should show. Typically, we want this set to the count/size of the ArrayList we're using. In your case, I think you'd want it set to 1 as you only want one question to show at a time.
Create tracker for question
You'll need to create a tracker for which question you are currently on so you know which question to display. For this, you'll need a simple int questionTracker
variable, that you could increment everytime they answer/pass/skip a question.
Modify getView(...) to show the correct Question
In the getView(...) call, you'll need to populate the screen with the correct question, which will be based on your tracker. Something like this
@Override public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View questionView = inflater.inflate(R.layout.question, parent);
//Get the next question
Question currentQuestion = questions.get(questionTracker);
//Fill the fields in the inflated layout with the data from the Question object
TextView questionField = questionView.findViewById(R.id.questionText)
questionField.setText(Question.question);
return questionView;
}
Forcing question to change
The tricky part will be forcing the view to re-draw after you've hit next/pass/answered a qestion. You may be able to manually call getView(...), though I've never done it, so I'm not sure.
来源:https://stackoverflow.com/questions/10483514/android-wizard-type-activity-with-adapter-backed-data