In this Part 1,
we get the basic concept of the reactive programming.
If you interested in learning via using youtube video subscribe my youtube channel and improve your knowledge .
Step 1. Create an Activity with any name like MainActivity
Look like this.
[darktheft/AppTest
An android app using kotlin and java . Contribute to darktheft/AppTest development by creating an account on GitHub.github.com](https://github.com/darktheft/AppTest/blob/master/app/src/main/res/layout/activity_main.xml "github.com/darktheft/AppTest/blob/master/ap..")
[CodingWithDarktheft
CodingWithDarktheft Live is my attempt to teach basics and those coding techniques to people in short time which took…youtube.com](https://www.youtube.com/channel/UCdbUomS4yFXN9D3_ZLtJJUg "youtube.com/channel/UCdbUomS4yFXN9D3_ZLtJJUg")
Step 2 . Java Code
Under the MainActivity.java we will write code like this
package com.videozone.customui.activity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.tabs.TabLayout;
import com.videozone.customui.R;
import com.videozone.customui.adapter.AnswerSheetAdapter;
import com.videozone.customui.adapter.QuestionFragmentAdapter;
import com.videozone.customui.common.Common;
import com.videozone.customui.common.model.CurrentQuestion;
import com.videozone.customui.db.DataBaseHelper;
import com.videozone.customui.fragments.QuestionFragment;
import com.videozone.customui.interfac.IQuestion;
import com.videozone.customui.model.ActionEvents;
import com.videozone.customui.model.HomeWatcher;
import com.videozone.customui.model.OnHomePressedListener;
import com.videozone.customui.model.Question;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import static com.videozone.customui.fragments.QuestionFragment.rb1;
import static com.videozone.customui.fragments.QuestionFragment.rb2;
import static com.videozone.customui.fragments.QuestionFragment.rb3;
import static com.videozone.customui.fragments.QuestionFragment.rb4;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, IQuestion {
TextView dataInsert,countDown,txtQuestion,qustionCount,txtScore,previousQues,nextQues,submit;
public static ViewPager viewPager;
public static TabLayout tabLayout;
int questionCounterTotal;
int questionCounter;
int score;
int ans =0;
private static final String *KEY\_SCORE* \= "keyScore";
public static final String *USER\_ANS* \= "userans";
public static final String *CURRECTANS* \= "currectans";
private boolean answered = false;
private Question currentQuestion;
public static List<Question> *questionList*;
DataBaseHelper db;
int questionIndex = -1;
private static final String *KEY\_MILLIS\_LEFT* \= "keyMillisLeft";
private static final long *COUNTDOWN\_IN\_MILLIS* \= 180000;
private long timeLeftInMillis;
private CountDownTimer countDownTimer;
public static ArrayList<QuestionFragment> *questionFragmentsList* \= new ArrayList<>();
int time\_lay = Common.*TOTAL\_TIME*;
boolean isAnsweredModeView = false;
RecyclerView answer\_sheet\_view;
private String TAG ="MainActivity.java";
int\[\] tabIcon ={R.drawable.*ep3*};
QuestionFragmentAdapter adapter;
AnswerSheetAdapter answerSheetAdapter;
AlertDialog.Builder builderAlert;
private static final String *KIOSK\_PACKAGE* \= "com.example.kiosk";
private static final String *PLAYER\_PACKAGE* \= "com.example.player";
private static final String\[\] *APP\_PACKAGES* \= {*KIOSK\_PACKAGE*, *PLAYER\_PACKAGE*};
Question question;
@RequiresApi(api = Build.VERSION\_CODES.*M*)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.*activity\_main*);
//init();
/\* Context context = getContext();
DevicePolicyManager dpm =
(DevicePolicyManager) context.getSystemService(Context.DEVICE\_POLICY\_SERVICE);
ComponentName adminName = getComponentName(context);
dpm.setLockTaskPackages(adminName, APP\_PACKAGES);
// Set an option to turn on lock task mode when starting the activity.
ActivityOptions options = ActivityOptions.makeBasic();
options.setLockTaskEnabled(true);
// Start our kiosk app's main activity with our lock task mode option.
PackageManager packageManager = context.getPackageManager();
Intent launchIntent = packageManager.getLaunchIntentForPackage(KIOSK_PACKAGE);
if (launchIntent != null) {
context.startActivity(launchIntent, options.toBundle());
}*/
/\* ActionEvents innerReceiver = new ActionEvents();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION\_CLOSE\_SYSTEM\_DIALOGS);
registerReceiver(innerReceiver, intentFilter);
*/
if (savedInstanceState == null){
init();
//showQuestions();
startCountdown();
getTotalTime();
}else {
timeLeftInMillis = savedInstanceState.getLong(*KEY\_MILLIS\_LEFT*);
score = savedInstanceState.getInt(*KEY\_SCORE*);
}
}
// here will start countdown
private void startCountdown() {
// statement of countdown timer ..
timeLeftInMillis = *COUNTDOWN\_IN\_MILLIS*;
countDownTimer = new CountDownTimer(timeLeftInMillis,1000) {
@Override
public void onTick(long millisUntilFinished) {
// intilize value of milliisUntilFinished
timeLeftInMillis = millisUntilFinished;
updateCountdown();
}
@Override
public void onFinish() {
timeLeftInMillis = 0;
}
}.start();
}
// here is will be update countdown timer
private void updateCountdown() {
int minutes = (int) (timeLeftInMillis / 1000) / 60;
int seconds = (int) (timeLeftInMillis / 1000) % 60;
String timeFormate = String.*format*(Locale.*getDefault*(),"%02d:%02d",minutes,seconds);
countDown.setText(timeFormate);
if (timeLeftInMillis < 10000){
countDown.setTextColor(Color.*RED*);
}else {
countDown.setTextColor(Color.*GREEN*);
}
}
private void init() {
// here is window alert show initilized
builderAlert = new AlertDialog.Builder(this);
db = new DataBaseHelper(this);
answer\_sheet\_view = findViewById(R.id.*answer\_sheet*);
answer\_sheet\_view.setHasFixedSize(true);
if (Common.*questionList*.size() >5)
answer\_sheet\_view.setLayoutManager(new GridLayoutManager(this,Common.*questionList*.size()));
answerSheetAdapter = new AnswerSheetAdapter(this,Common.*anserSheetList*);
answer\_sheet\_view.setAdapter(answerSheetAdapter);
dataInsert = findViewById(R.id.*data\_insert*);
countDown = findViewById(R.id.*txt\_countdown*);
previousQues = findViewById(R.id.*txt\_previous\_ques*);
nextQues = findViewById(R.id.*txt\_next\_ques*);
submit = findViewById(R.id.*txt\_submit*);
submit.setOnClickListener(this);
//insertData();
*tabLayout* \= findViewById(R.id.*slidingTab*);
*viewPager* \= findViewById(R.id.*viewPager*);
dataInsert.setOnClickListener(this);
*tabLayout*.setOnClickListener(this);
previousQues.setOnClickListener(this);
nextQues.setOnClickListener(this);
*questionList* \=db.getAlldata();
//Log.e(TAG, "init: message"+questionList.size());
questionCounterTotal =*questionList*.size();
// Here is the number of question will be return
//stateProgressBar.setMaxStateNumber(StateProgressBar.StateNumber.valueOf(questionCounterTotal));
getFragmentList();
adapter = new QuestionFragmentAdapter(getSupportFragmentManager(),
this,*questionFragmentsList*);
*viewPager*.setAdapter(adapter);
*tabLayout*.setupWithViewPager(*viewPager*);
//tabLayout.setPadding(0,0,0,0);
*viewPager*.setOnClickListener(this);
//tabLayout.getTabAt(1).setIcon(tabIcon\[0\]);
if (*tabLayout*.getTabCount() == 0){
TabLayout.Tab tab = *tabLayout*.getTabAt(0);
assert tab != null;
tab.setCustomView(null);
//tab.setCustomView(adapter.getPageTitle(i).charAt(i));
tab.setCustomView(adapter.getSelectedTabView(0));
}else {
for (int i = 0; i < *tabLayout*.getTabCount(); i++) {
TabLayout.Tab tab = *tabLayout*.getTabAt(i);
assert tab != null;
tab.setCustomView(null);
//tab.setCustomView(adapter.getPageTitle(i).charAt(i));
tab.setCustomView(adapter.getTabView(i));
}
}
/\* viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int SCROLLING\_RIGHT =0;
int SCROLLING\_LEFT =1;
int SCROLLING\_UNDETERMINATED =2;
int currentScrollingDirection =2;
private void setScrollingDirection(float positionoffset){
if ((1-positionoffset) >= 0.5)
this.currentScrollingDirection=SCROLLING\_RIGHT;
else if ((1-positionoffset) <= 0.5)
this.currentScrollingDirection=SCROLLING\_LEFT;
}
private boolean isScrolldirectionUnderminated(){
return currentScrollingDirection == SCROLLING\_UNDETERMINATED;
}
private boolean isScrollingRight(){
return currentScrollingDirection==SCROLLING\_RIGHT;
}
private boolean isScrollingLeft(){
return currentScrollingDirection ==SCROLLING\_LEFT;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (isScrolldirectionUnderminated())
setScrollingDirection(positionOffset);
}
@Override
public void onPageSelected(int i) {
QuestionFragment questionFragment;
int position = 0;
if (i>0){
if (isScrollingRight()){
questionFragment =Common.fragmentList.get(i-1);
position = i-1;
}else if (isScrollingLeft()){
questionFragment =Common.fragmentList.get(i+1);
position = i+1;
}else{
questionFragment = Common.fragmentList.get(position);
}
}else {
questionFragment = Common.fragmentList.get(0);
position = 0;
}
// here is showing answer
CurrentQuestion question\_state = questionFragment.getSelectedAnswer();
Common.anserSheetList.set(position,question\_state);
answerSheetAdapter.notifyDataSetChanged();
countCorrectAnswer();
dataInsert.setText(new StringBuilder(String.format("%d",Common.right\_answer\_count))
.append("/")
.append(String.format("%d",Common.questionList.size())).toString());
if (question\_state.getType() == Common.ANSWER\_TYPE.NO\_ANSWER)
{
questionFragment.showAnswer();
questionFragment.disaleAnswer();
}
}
@Override
public void onPageScrollStateChanged(int state) {
if (state==viewPager.SCROLL\_STATE\_IDLE)
this.currentScrollingDirection = SCROLLING\_UNDETERMINATED;
}
});
*/
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Toast.makeText(MainActivity.this, ""+questionList.size(), Toast.LENGTH\_SHORT).show();
}
@Override
public void onPageSelected(int position) {
*tabLayout*.setTabGravity(TabLayout.*GRAVITY\_CENTER*);
highLightCurrentTab(position);
//getSelectedAnswer();
//countCorrectAnswer();
/\*dataInsert.setText(new StringBuilder(String.format("%d",Common.right\_answer\_count))
.append("/")
.append(String.format("%d",Common.questionList.size())).toString());
*/
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
// This one for alert Dialog show ..
private void countCorrectAnswer() {
/\* Common.right\_answer\_count = Common.wrong\_answer\_count = 0;
for (CurrentQuestion item:Common.anserSheetList)
if (item.getType() == Common.ANSWER\_TYPE.RIGHT\_ANSWER)
Common.right\_answer\_count++;
else if (item.getType() == Common.ANSWER\_TYPE.WRONG\_ANSWER)
Common.wrong\_answer\_count++;
*/
//rightAns = wrongAns = 0;
Common.*right\_answer\_count* \= Common.*wrong\_answer\_count* \= 0;
for (CurrentQuestion item : Common.*anserSheetList*){
if (item.getType() == Common.ANSWER\_TYPE.*RIGHT\_ANSWER*)
Common.*right\_answer\_count*++;
else if (item.getType() == Common.ANSWER\_TYPE.*WRONG\_ANSWER*)
Common.*wrong\_answer\_count*++;
}
}
private void highLightCurrentTab(int position) {
// answered = false;
TabLayout.Tab tab = *tabLayout*.getTabAt(position);
assert tab != null;
tab.setCustomView(null);
tab.setCustomView(adapter.getSelectedTabView(position));
//tab.setCustomView(adapter.check(position));
/\*tab.setCustomView(adapter.getPageTitle(position).charAt(position));\*/
// if (answered){
// TabLayout.Tab tab1 = tabLayout.getTabAt(position);
// assert tab1 != null;
// tab1.setCustomView(null);
// tab1.setCustomView(adapter.getAnsweredTabView(position));
//
//
// answered = true;
// }
// else {
// TabLayout.Tab tab1 = tabLayout.getTabAt(position);
// assert tab1 != null;
// tab1.setCustomView(null);
// tab1.setCustomView(adapter.getSelectedTabView(position));
// answered = false;
// }
//getView(position);
/\*for (int j =0;j<position;j++){
View view = LayoutInflater.from(this).inflate(R.layout.fragment\_question, null);
RadioButton rb1, rb2, rb3, rb4;
rb1 = view.findViewById(R.id.rdio\_btn1);
rb2 = view.findViewById(R.id.rdio\_btn2);
rb3 = view.findViewById(R.id.rdio\_btn3);
rb4 = view.findViewById(R.id.rdio\_btn4);
if (rb1.isChecked() || rb2.isChecked() || rb3.isChecked() || rb4.isChecked()) {
Log.e(TAG, "highLightCurrentTab radio: "+rb1);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab1 = tabLayout.getTabAt(i);
assert tab1 != null;
tab1.setCustomView(null);
//tab.setCustomView(adapter.getPageTitle(i).charAt(i));
tab1.setCustomView(adapter.getAnsweredTabView(i));
}
}
}\*/
}
/* public View getView( int position) {
//super.onCreate(savedInstanceState);
View view;
view = LayoutInflater.from(this).inflate(R.layout.fragment\_question,null);
RadioButton rb1, rb2, rb3, rb4;
rb1 = view.findViewById(R.id.rdio\_btn1);
rb2 = view.findViewById(R.id.rdio\_btn2);
rb3 = view.findViewById(R.id.rdio\_btn3);
rb4 = view.findViewById(R.id.rdio\_btn4);
//Log.e(TAG, "getView: "+position );
\*/
/* if (!answered){
if (rb1.isChecked() || rb2.isChecked() || rb3.isChecked() || rb4.isChecked()){
Toast.makeText(this, "answered", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "notanswered", Toast.LENGTH_SHORT).show();
}
}else
Toast.makeText(this, "error", Toast.LENGTH\_SHORT).show();
*/
/*
return view;
}
*/
private void getFragmentList() {
for (int i =0;i<*questionList*.size(); i++){
// Log.e(TAG, "getFragmentList: "+questionList.size());
Bundle bundle = new Bundle();
bundle.putInt("index",i);
QuestionFragment fragment = new QuestionFragment();
//tabLayout.setBackground(ContextCompat.getDrawable(this,R.drawable.btn\_shape));
fragment.setArguments(bundle);
*questionFragmentsList*.add(fragment);
}
}
private void getCurrentTab() {
Toast.*makeText*(this, ""+*questionList*.size(), Toast.*LENGTH\_SHORT*).show();
for (int i = 0 ; i<*questionList*.size();i++){
// tabLayout.getTabAt(i).setIcon(R.drawable.tab\_bg\_selected);
}
}
@Override
public void onClick(View v) {
if (v==dataInsert){
//insertData();
//getTotalTime();
}else if (v==*tabLayout*){
getCurrentTab();
}else if (v==*viewPager*){
// event will be on click viewPager
}else if (v==previousQues){
// will be previous question
getPreviousQues();
}else if (v==nextQues){
// will be next question
getNextQues();
}else if (v==submit){
submitQues();
}
}
private void submitQues() {
Intent intent = new Intent(this,ResultActivity.class);
startActivity(intent);
}
// This one for when user back button pressed ..
@Override
public void onBackPressed() {
//super.onBackPressed();
builderAlert.setMessage("Do you want to close quiz")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//finish();
Toast.*makeText*(MainActivity.this, "Successfully",
Toast.*LENGTH\_SHORT*)
.show();
Log.*e*("Test", "onClick: after back " );
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alert = builderAlert.create();
alert.setTitle("Cancel quiz");
alert.show();
}
// getNext question
private void getNextQues() {
// will be jump on next tab
if (questionCounter < questionCounterTotal){
currentQuestion = *questionList*.get(questionCounter);
answered = true;
questionCounter++;
if (questionCounter < *questionList*.size()) {
//Toast.makeText(this, "done", Toast.LENGTH\_SHORT).show();
*tabLayout*.getTabAt(questionCounter).select();
} else if (questionCounter == *questionList*.size()){
// questionCounter-- for previous question can visit victim / user
// questionCounter--;
//startActivity(new Intent(this,ResultActivity.class));
}
}
}
@Override
protected void onUserLeaveHint() {
//super.onUserLeaveHint();
super.onUserLeaveHint();
System.*out*.println("HOMEEEEEEEEE");
showDialog("Home");
}
// when we home button pressed
void showDialog(String the\_key){
//timeLeftInMillis = COUNTDOWN\_IN\_MILLIS;
countDownTimer = new CountDownTimer(5000,1000) {
@Override
public void onTick(long millisUntilFinished) {
// intilize value of milliisUntilFinished
timeLeftInMillis = millisUntilFinished;
updateCountdownForSubmit();
}
private void updateCountdownForSubmit() {
int minutes = (int) (timeLeftInMillis / 1000) / 60;
int seconds = (int) (timeLeftInMillis / 1000) % 60;
String timeFormate = String.*format*(Locale.*getDefault*(),"%02d:%02d",minutes,seconds);
String cound = timeFormate;
if (timeLeftInMillis<1000){
Intent intent = new Intent(MainActivity.this,ResultActivity.class);
startActivity(intent);
}
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Your test will be submitted within 3 sec "+cound+"" + " button. Would you like to exit the app?")
.setCancelable(true)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
finish();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.setTitle("CoderzHeaven.");
alert.show();
}
@Override
public void onFinish() {
timeLeftInMillis = 0;
}
}.start();
}
// get previous question
private void getPreviousQues() {
if (questionCounter < questionCounterTotal){
currentQuestion = *questionList*.get(questionCounter);
answered = false;
questionCounter--;
if (questionCounter < *questionList*.size()) {
if (questionCounter == -1) {
Log.*e*(TAG, "getPreviousQues: " + questionCounter);
questionCounter++;
*tabLayout*.getTabAt(questionCounter).select();
}else
*tabLayout*.getTabAt(questionCounter).select();
}
}
}
// get Total time
private void getTotalTime() {
long totalTime = *COUNTDOWN\_IN\_MILLIS* / 60000;
dataInsert.setText("Total Time :"+(int) totalTime+" min");
}
private void insertData() {
for (int i =0 ;i<=5;i++) {
boolean isInserted = db.insert(i, "In the following question , You have need to solve the questions and give answer ", "abb", "bcc", "jan", "abc", "bcc");
if (isInserted == true) {
Toast.*makeText*(this, "insert", Toast.*LENGTH\_SHORT*).show();
} else {
Toast.*makeText*(this, "error", Toast.*LENGTH\_SHORT*).show();
//startActivity(new Intent(this,Test2Activity.class));
}
}
}
@Override
public CurrentQuestion getSelectedAnswer() {
//return null;
CurrentQuestion currentQuestion = new CurrentQuestion(questionIndex,Common.ANSWER\_TYPE.*NOT\_ANSWER*);// default
StringBuilder result = new StringBuilder();
if (Common.*selected\_values*.size() > 1){
// for split view ,
// split answer to array
Object\[\] arrayAnswer = Common.*selected\_values*.toArray();
for (int i = 0; i<arrayAnswer.length; i++)
if (i<arrayAnswer.length -1)
result.append(new StringBuilder(((String)arrayAnswer\[i\]).substring(0,1)).append(","));
else
result.append(new StringBuilder((String)arrayAnswer\[i\]).substring(0,1));
}
else if (Common.*selected\_values*.size()==1){
Object\[\] arrayAnswer = Common.*selected\_values*.toArray();
result.append((String)arrayAnswer\[0\]).substring(0,1);
}
if (question != null){
if (!TextUtils.*isEmpty*(result)){
if (result.toString().equals(question.getDataAnswer())){
currentQuestion.setType(Common.ANSWER\_TYPE.*RIGHT\_ANSWER*);
Common.*right\_answer\_count*++;
Common.*arrayListRight*.add(Common.*right\_answer\_count*+1);
Log.*e*(TAG, "getSelectedAnswer right: "+Common.*arrayListRight*.size());
//Common.arrayList.add(Common.right\_answer\_count+1);
}
else{
currentQuestion.setType(Common.ANSWER\_TYPE.*WRONG\_ANSWER*);
Common.*arrayListWrongAns*.add(Common.*wrong\_answer\_count*++);
Log.*e*(TAG, "getSelectedAnswer: wrong "+Common.*arrayListWrongAns*.size());
}
}
else
currentQuestion.setType(Common.ANSWER\_TYPE.*NOT\_ANSWER*);
}
else {
Toast.*makeText*(getApplicationContext(), "can't get question", Toast.*LENGTH\_SHORT*).show();
currentQuestion.setType(Common.ANSWER\_TYPE.*NOT\_ANSWER*);
}
Common.*selected\_values*.clear();
return currentQuestion;
}
@Override
public void showAnswer() {
}
@Override
public void disaleAnswer() {
}
@Override
public void resetQuestion() {
}
}
Source code is here
[darktheft/AppTest
An android app using kotlin and java . Contribute to darktheft/AppTest development by creating an account on GitHub.github.com](https://github.com/darktheft/AppTest/blob/master/app/src/main/java/com/videozone/customui/activity/MainActivity.java "github.com/darktheft/AppTest/blob/master/ap..")
Step 3. Create a adapter like this
Create a method in any java file
Step 4 . create a fragment with any name
fragment_question.xml
QuestionFragment.java
application ui/ux