I want to build a dynamic survey with android. Question are created from a server a loaded in my Android app through rest service. Each question has a parameter that indicates the type of the answer. According to the question type, I want a given widget (Edittext, checkboxn...) for input in a listview. Let's asume this is the list of question:
"question": [
{
"name": "fieldA",
"type": "STRING",
"minCharacters": 10,
"maxCharacters": 100
},
{
"name": "fieldB",
"type": "INTEGER",
"min": 10,
"max": 100
},
{
"name": "fieldC",
"type": "BOOLEAN",
"defaultValue": true
}
],
What I have done now is to create different layout for each type of question and call in adapter:
boolean_layout.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="wrap_content"
android:background="#5fb0c9"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/questionLabel"
android:layout_alignParentTop="true"
android:ems="10"
android:layout_weight="1"/>
<CheckBox
android:id="@+id/questionValueCbx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="Oui/Non"/>
</LinearLayout>
string_layout.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="wrap_content"
android:background="#5fb0c9"
android:weightSum="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="@+id/questionLabel"
android:layout_weight="0.8"/>
<EditText
android:id="@+id/questionValue"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:ems="10"
android:inputType="textPersonName" />
</LinearLayout>
....
And I call the appropriate layout in adapter
public View getView(final int i, View view, ViewGroup viewGroup) {
final ViewHolder holder ;
// questions here refers to the list of questions
String questionType = questions.get(i).getQuestionType().trim();
if (view == null || view.getTag() == null) {
holder = new ViewHolder();
switch (questionType){
case "BOOLEAN": {
view = mInflater.inflate(R.layout.boolean_layout, viewGroup,false);
holder.tv_questionLable = (TextView)view.findViewById(R.id.questionLabel);
holder.questionAnswer = (CheckBox)view.findViewById(R.id.questionValueCbx);
}
case "STRING": {
view = mInflater.inflate(R.layout.string_question, viewGroup,false);
holder.tv_questionLable = (TextView)view.findViewById(R.id.questionLabel);
holder.questionAnswer = (EditText)view.findViewById(R.id.questionValue);
}
case "INT": {
view = mInflater.inflate(R.layout.number_question, viewGroup,false);
holder.tv_questionLable = (TextView)view.findViewById(R.id.questionLabel);
holder.questionAnswer = (EditText)view.findViewById(R.id.questionValue);
}
...
}
}
The result does not meets my expectations. It puts Edittext everywhere, even where it is supposed to put checkbox. Help.
If you are inflating the different item into the listview than u need to use this method getItemViewType
of the BaseAdapter
class.
Have a look into my solution i have distinguished the view and managed accordingly
public class YOUR_ADAPTER_CLASS extends BaseAdapter {
private int ITEM_BOOLEAN = 1;
private int ITEM_STRING = 2;
private int ITEM_INT = 3;
@Override
public int getCount() {
return questions.size();
}
@Override
public Object getItem(int position) {
return questions.get(position);
}
@Override
public long getItemId(int position) {
return questions.indexOf(getItem(position));
}
@Override
public int getItemViewType(int position) {
if (questions.get(position).getQuestionType().equalsIgnoreCase("BOOLEAN")) {
return ITEM_BOOLEAN;
} else if (questions.get(position).getQuestionType().equalsIgnoreCase("STRING")) {
return ITEM_STRING;
} else {
return ITEM_INT;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
int listViewItemType = getItemViewType(position);
if (convertView == null) {
if (listViewItemType == ITEM_BOOLEAN) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.boolean_layout, null);
} else if (listViewItemType == ITEM_STRING) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.string_question, null);
} else {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.number_question, null);
}
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (listViewItemType == ITEM_BOOLEAN) {
/**
* GET THE BOOLEAN ITEM AND INFALTE DATA INTO IT
*/
} else if (listViewItemType == ITEM_STRING) {
/**
* GET THE STRING ITEM AND INFALTE DATA INTO IT
*/
} else {
/**
* GET THE INT ITEM AND INFALTE DATA INTO IT
*/
}
return convertView;
}
}
Have a look on my another solution which is in the Recyclview Recyclview with different item inflation
来源:https://stackoverflow.com/questions/51950029/dynamic-form-in-a-listview