0

I want to create an Android App that renders a form based on a question list. The question list is downloaded from a server and available in JSON format. The app should show the answers in a "[key]: [value]" format.

I have successfully bind the question label using RecyclerView, there are 7 question, 6 question is using EditText, but the last question is using RadioButton.

How can I bind the EditText and the RadioButton? Any way to achieve this?

This is the JSON

{
      "version" : "1.0.0",
      "questions" : [{
        "key" : "email",
        "label" : "email",
        "typeField" : "email",
        "validation" : {
          "required" : true
        }
      }, {
        "key" : "password",
        "label" : "Password",
        "typeField" : "password",
        "validation" : {
          "required" : true
        }
      }, {
        "key" : "name",
        "label" : "Name",
        "typeField" : "text",
        "validation" : {
          "required" : true,
          "minLength" : 3
        }
      }, {
        "key" : "pob",
        "label" : "Place of Birth",
        "typeField" : "text",
        "validation" : {
          "required" : true
        }
      }, {
        "key" : "dob",
        "label" : "Date of Birth",
        "typeField" : "date",
        "validation" : {
          "required" : true
        }
      }, {
        "key" : "idCardNo",
        "label" : "ID Card No.",
        "typeField" : "text",
        "validation" : {
          "required" : true,
          "exactLength" : 16
        }
      }, {
        "key" : "maritalStatus",
        "label" : "Marital Status",
        "typeField" : "select",
        "validation" : null,
        "options" : [{
          "label" : "Married",
          "value" : "1"
        }, {
          "label" : "Not Married",
          "value" : "0"
        }]
      }]
    }

and this is my adapter

public class QuestionAdapter extends RecyclerView.Adapter<QuestionAdapter.QuestionViewHolder> {

    private List<Question> questions;
    private int rowLayout;
    private Context context;

    public QuestionAdapter(List<Question> questions, int rowLayout, Context context) {
        this.questions = questions;
        this.rowLayout = rowLayout;
        this.context = context;
    }

    @Override
    public QuestionAdapter.QuestionViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        return new QuestionViewHolder(view);
    }

    @Override
    public void onBindViewHolder(QuestionAdapter.QuestionViewHolder holder, final int position) {

        holder.questionTitle.setText(questions.get(position).getLabel());

    }

    @Override
    public int getItemCount() {
        return questions.size();
    }

    public static class QuestionViewHolder extends RecyclerView.ViewHolder {
        LinearLayout questionLayout;
        TextView questionTitle;
        EditText fieldType;


        public QuestionViewHolder(View itemView) {
            super(itemView);
            questionLayout = (LinearLayout) itemView.findViewById(R.id.questionLayout);
            questionTitle = (TextView) itemView.findViewById(R.id.question);
            fieldType = (EditText) itemView.findViewById(R.id.fieldType);
        }
    }
}

I call the API using retrofit. this is the method that call the API.

private void callListQuestion() {
    ApiQuestions client = Service.createService(ApiQuestions.class);
    Call<QuestionResult> call = client.getListQuestion();
    call.enqueue(new Callback<QuestionResult>() {
        @Override
        public void onResponse(Call<QuestionResult> call, Response<QuestionResult> response) {
            int statusCode = response.code();
            List<Question> questions = response.body().getResults();

            final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.question_recycler_view);
            recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

            recyclerView.setAdapter(new QuestionAdapter(questions, R.layout.list_item_question, getApplicationContext()));
        }

        @Override
        public void onFailure(Call<QuestionResult> call, Throwable t) {
            Log.e(TAG, t.toString());
        }
    });
}

Here my XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/questionLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="72dp"
    android:orientation="horizontal"
    android:padding="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/question"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingRight="16dp"
            android:text="question"
            android:textColor="@color/colorBlack"
            android:textSize="16sp"
            android:textStyle="bold" />


        <EditText
            android:id="@+id/fieldType"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingRight="16dp"
            android:textColor="@color/colorBlack"
            android:textSize="16sp"
            android:textStyle="bold"/>

    </LinearLayout>

</LinearLayout>

2 Answers2

0

To show you how to bind the JSON result onto the EditText we would need to see your XML to know the ID of the EditText but it would be something like

EditText edittext = (EditText) view.findViewById(R.id.myEditText);
Mike Poole
  • 1,958
  • 5
  • 29
  • 41
0

you can check the Data Binding Library. It's a good way to bind classes or values to the views without writing the same code again and again.

Following the Android Developer's guide, you can bind data to the views in XML like:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout>

And the model class corresponding to your JSON string will be:

public class User {
   private final String firstName;
   private final String lastName;
   public User(String firstName, String lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }
   public String getFirstName() {
       return this.firstName;
   }
   public String getLastName() {
       return this.lastName;
   }
}

And the binding part looks like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   User user = new User("Test", "User");
   binding.setUser(user);
}

Also, you can use Gson to create class instances from your JSON string.

Metehan Toksoy
  • 1,885
  • 3
  • 22
  • 39