Foggy day
Android(Kotlin) - question example using assets file - 1 본문
This article is question example using assets file.
The purpose of creation is to make a survey Form requires a variety of questions and answers
The used things are Assets File(Json), Viewpager2, RecyclerView, Fragment navigation graph, Gson, ViewBinding, Parcelize, EventBus and so on.
Video
1. package structure
- survey_nav_graph.xml
2. Navigation graph container activity
- ViewPagerQuestionBaseActivity
It is activity for a container of fragments and don't have any code.
class ViewPagerQuestionBaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_pager_question_base)
}
}
- activity_view_pager_question_base.xml
Add FragmentContainerView and some properties.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".viewPager.survey.container.ViewPagerQuestionBaseActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/survey_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/survey_nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. assets file
- survey.json
I made a json assets file with 3 questions.
{
"totalScore": 3,
"list": [
{
"number": 1,
"question": "5 + 5 ?",
"answerList": [
{
"answer": false,
"item": "1. 5"
},
{
"answer": false,
"item": "2. 6"
},
{
"answer": false,
"item": "3. 7"
},
{
"answer": false,
"item": "4. 8"
},
{
"answer": true,
"item": "5. 10"
}
]
},
{
"number": 2,
"question": "4 X 7 ?",
"answerList": [
{
"answer": false,
"item": "1. 11"
},
{
"answer": false,
"item": "2. 17"
},
{
"answer": false,
"item": "3. 15"
},
{
"answer": true,
"item": "4. 28"
},
{
"answer": false,
"item": "5. 27"
}
]
},
{
"number": 3,
"question": "20 / 4 ?",
"answerList": [
{
"answer" : true,
"item" : "1. 5"
},{
"answer" : false,
"item" : "2. 6"
},{
"answer" : false,
"item" : "3. 7"
},{
"answer" : false,
"item" : "4. 8"
},{
"answer" : false,
"item" : "5. 9"
}
]
}
]
}
4. Model (data class, enum class)
- SurveyListModel
This model is the data class for reading 'survey.json' file.
@Parcelize
data class SurveyListModel(
var totalScore: Int,
var type: Int,
var list: ArrayList<List>
) : Parcelable {
@Parcelize
data class List(
var number: Int,
var question: String,
var answerList: ArrayList<AnswerList>
) : Parcelable {
@Parcelize
data class AnswerList(
var answer: Boolean,
var item: String,
) : Parcelable
}
}
-SurveyType
This example have four question list. But I implemented question one.
enum class SurveyType {
QUESTION_ONE,
QUESTION_TWO,
QUESTION_THREE,
QUESTION_FOUR,
}
- SurveyChoiceModel
This model is needed when you click item of question.
data class SurveyChoiceModel(
var questionNumber: Int,
var clickedNumber: Int,
)
5. startFragment
- fragment_survey_start.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".viewPager.survey.start.SurveyStartFragment">
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="Welcome Survey"
android:textColor="@color/black"
android:textSize="40dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:paddingTop="50dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView4">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnSurvey1"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="Survey 1"
android:gravity="center_vertical"
android:padding="0dp"
android:textAllCaps="false"
android:paddingStart="20dp"
android:layout_marginHorizontal="30dp"
android:textStyle="normal"
android:textColor="@color/black"
android:textSize="16dp"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnSurvey2"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="Survey 2"
android:gravity="center_vertical"
android:padding="0dp"
android:textAllCaps="false"
android:paddingStart="20dp"
android:layout_marginHorizontal="30dp"
android:textStyle="normal"
android:textColor="@color/black"
android:textSize="16dp"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnSurvey3"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="Survey 3"
android:gravity="center_vertical"
android:padding="0dp"
android:textAllCaps="false"
android:paddingStart="20dp"
android:layout_marginHorizontal="30dp"
android:textStyle="normal"
android:textColor="@color/black"
android:textSize="16dp"/>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="match_parent"
android:id="@+id/btnSurvey4"
android:layout_height="70dp"
android:text="Survey 4"
android:gravity="center_vertical"
android:padding="0dp"
android:textAllCaps="false"
android:paddingStart="20dp"
android:layout_marginHorizontal="30dp"
android:textStyle="normal"
android:textColor="@color/black"
android:textSize="16dp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
- SurveyStartFragment
If you click question one, you send question type and json file of the selected type to QuestionFragmentSurvey using Bundle, Stream, and Gson.
class SurveyStartFragment : Fragment(), View.OnClickListener {
lateinit var b: FragmentSurveyStartBinding
lateinit var mContext: Context
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
b = FragmentSurveyStartBinding.inflate(layoutInflater)
mContext = requireContext()
setupListener()
return b.root
}
fun setupListener() {
b.btnSurvey1.setOnClickListener(this)
}
override fun onClick(v: View?) {
var surveyType: SurveyType? = null
when (v!!.id) {
R.id.btnSurvey1 -> {
surveyType = SurveyType.QUESTION_ONE
}
}
val bundle = Bundle()
bundle.putString("surveyType", surveyType.toString())
bundle.putParcelable("surveyData", getModel(surveyType!!))
findNavController().navigate(R.id.action_surveyStartFragment_to_surveyQuestionFragment,
bundle)
}
fun getModel(surveyType: SurveyType): SurveyListModel? {
var surveyListModel: SurveyListModel? = null
var jsonFileString: String? = null
when (surveyType) {
SurveyType.QUESTION_ONE -> {
jsonFileString = Common.getJsonDataFromAsset(mContext, "survey.json")
val gson = Gson()
surveyListModel = gson.fromJson(jsonFileString, SurveyListModel::class.java)
}
SurveyType.QUESTION_TWO -> {
}
SurveyType.QUESTION_THREE -> {
}
SurveyType.QUESTION_FOUR -> {
}
}
return surveyListModel
}
}
- Common.getJsonDataFromAsset method
fun getJsonDataFromAsset(context: Context, fileName: String): String? {
val jsonString: String
try {
jsonString = context.assets.open(fileName).bufferedReader().use {
it.readText()
}
} catch (e: Exception) {
Log.d("getJsonDataFromAsset", "getJsonDataFromAsset: $e ")
return null
}
return jsonString
}
'Android' 카테고리의 다른 글
Android - getSupportFragmentManager, getChildFragmentManager (0) | 2021.03.21 |
---|---|
Android(Kotlin) - question example using assets file - 2 (0) | 2021.03.14 |
Android(안드로이드) - EventBus Example (0) | 2021.03.10 |
Android(java) - exoplayer2 (0) | 2021.03.05 |
Android(java) - Activity popup(background dim) (0) | 2021.03.04 |