This app consists of two fragments, and sub-parts are needed to be constructed which offer the users the degree of control they require in making varying designs of their choice.
Source code of Covid-19 app tracker using android studio.
Step 1: Create a new project and Choose “Bottom navigation activity”
Step 2: app -> manifests -> AndroidManifest.xml – > add user permission :
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.mycovidtracker"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" /> </application> </manifest>
Step 3 : Gradle Scripts -> build.gradle -> add dependencies
implementation 'com.android.volley:volley:1.1.1' implementation "androidx.recyclerview:recyclerview:1.1.0"
Create Home Fragment
public class HomeFragment extends Fragment { private TextView tvTotalConfirmed,tvTotatlDeath,tvTotalRecovered; private ProgressBar progressBar; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_home, container, false); tvTotalConfirmed=root.findViewById(R.id.tvTotalConfirmed); tvTotatlDeath=root.findViewById(R.id.tvTotalDeath); tvTotalRecovered=root.findViewById(R.id.tvTotalRecovered); progressBar=root.findViewById(R.id.progress_circular_home); getData(); return root; } private void getData() { RequestQueue queue= Volley.newRequestQueue(getActivity()); String url="https://corona.lmao.ninja/all"; StringRequest request=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { progressBar.setVisibility(View.GONE); try { JSONObject jsonObject = new JSONObject(response.toString()); tvTotalConfirmed.setText(jsonObject.getString("cases")); tvTotatlDeath.setText(jsonObject.getString("deaths")); tvTotalRecovered.setText(jsonObject.getString("recovered")); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { progressBar.setVisibility(View.GONE); Log.d("Err response: ",error.toString()); } }); queue.add(request); } }
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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:background="@color/colorPrimary" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="wrap_content" android:gravity="center" android:layout_centerInParent="true" android:orientation="vertical" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/poppins_bold" android:textColor="#fff" android:textSize="24dp" android:layout_marginBottom="24dp" android:textAlignment="center" android:text="Coronavirus COVID-19\nGlobal cases" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#fff" android:id="@+id/tvLabelTotalConfirmed" style="@style/LabelFontStyle" android:text="Total confirmed" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/colorTotatlConfirmed" android:id="@+id/tvTotalConfirmed" style="@style/TotalFontStyle" tools:text="164879" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/colorTotatlDeath" android:id="@+id/tvLabelTotalDeath" style="@style/LabelFontStyle" android:text="Total Death" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/colorTotatlDeath" android:id="@+id/tvTotalDeath" style="@style/TotalFontStyle" tools:text="164879" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/colorTotatlRecovered" android:id="@+id/tvLabelTotalRecovered" style="@style/LabelFontStyle" android:text="Total Recovered" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/colorTotatlRecovered" android:id="@+id/tvTotalRecovered" style="@style/TotalFontStyle" tools:text="164879" /> </LinearLayout> <androidx.core.widget.ContentLoadingProgressBar android:layout_centerInParent="true" android:id="@+id/progress_circular_home" android:indeterminate="true" android:indeterminateDrawable="@drawable/progress" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Create Country Fragment
CountryFragment.java
public class CountryFragment extends Fragment { RecyclerView rvCovidCountry; ProgressBar progressBar; ArrayList<CovidCountry> covidCountries; private static final String TAG=CountryFragment.class.getSimpleName(); public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_country, container, false); rvCovidCountry=root.findViewById(R.id.rcCovidCountry); progressBar=root.findViewById(R.id.progress_circular_country); rvCovidCountry.setLayoutManager(new LinearLayoutManager(getActivity())); getDataFromServer(); return root; } private void ShowRecyclerViewAdapter(){ CovidCountryAdapter covidCountryAdapter=new CovidCountryAdapter(covidCountries); rvCovidCountry.setAdapter(covidCountryAdapter); } private void getDataFromServer() { String url="https://corona.lmao.ninja/countries"; covidCountries=new ArrayList<>(); StringRequest request=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { progressBar.setVisibility(View.GONE); if (response!=null){ Log.e(TAG,"onResponse: "+response); } try { JSONArray jsonArray=new JSONArray(response); for (int i=0;i<jsonArray.length();i++){ JSONObject data=jsonArray.getJSONObject(i); covidCountries.add(new CovidCountry(data.getString("country"),data.getString("cases"))); } ShowRecyclerViewAdapter(); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { progressBar.setVisibility(View.GONE); Log.e(TAG,"onResponse: "+error); } }); Volley.newRequestQueue(getActivity()).add(request); } }
CovidCountry.java
The Data class CovidCountry is a custom java class that acts as a structure for holding the information for every item of the RecyclerView
package com.example.mycovidtracker.ui.country; public class CovidCountry { String mCovidCountry,mCases,mTodayCases,mDeaths,mTodayDeaths,mRecovered,mCritical; public CovidCountry(String mCovidCountry, String mCases) { this.mCovidCountry = mCovidCountry; this.mCases = mCases; this.mTodayCases = mTodayCases; this.mDeaths = mDeaths; this.mTodayDeaths = mTodayDeaths; this.mRecovered = mRecovered; this.mCritical = mCritical; } public String getmCovidCountry() { return mCovidCountry; } public String getmCases() { return mCases; } }
CovidCountryAdapter.java
The ViewHolder is a java class that stores the reference to the layout views that have to be dynamically modified during the execution of the program by a list of data obtained from JSon.
The Adapter: The adapter is the main code responsible for RecyclerView. It holds all the important methods dealing with the implementation of RecylcerView. The basic methods for a successful implementation are:
- onCreateViewHolder: which deals with the inflation of the card layout as an item for the RecyclerView.
- onBindViewHolder: which deals with the setting of different data and methods related to clicks on particular items of the RecyclerView.
- getItemCount: which Returns the length of the RecyclerView.
public class CovidCountryAdapter extends RecyclerView.Adapter<CovidCountryAdapter.ViewHolder>{ ArrayList<CovidCountry> covidCountries; public CovidCountryAdapter(ArrayList<CovidCountry> covidCountries) { this.covidCountries = covidCountries; } @NonNull @Override public CovidCountryAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_covid_country,parent,false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull CovidCountryAdapter.ViewHolder holder, int position) { CovidCountry covidCountry=covidCountries.get(position); holder.tvTotalCases.setText(covidCountry.getmCases()); holder.tvCountryName.setText(covidCountry.getmCovidCountry()); } @Override public int getItemCount() { return covidCountries.size(); } public class ViewHolder extends RecyclerView.ViewHolder { TextView tvTotalCases,tvCountryName; public ViewHolder(@NonNull View itemView) { super(itemView); tvTotalCases=itemView.findViewById(R.id.tvTotalCases); tvCountryName=itemView.findViewById(R.id.tvCountryName); } } }
fragment_country.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimary" xmlns:tools="http://schemas.android.com/tools"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rcCovidCountry" tools:listitem="@layout/item_list_covid_country" android:layout_width="match_parent" android:layout_height="wrap_content"/> <androidx.core.widget.ContentLoadingProgressBar android:id="@+id/progress_circular_country" android:layout_centerInParent="true" android:indeterminateDrawable="@drawable/progress" android:indeterminate="true" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
item_list_covid_country.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="8dp" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/tvTotalCases" android:textColor="@color/colorTotatlConfirmed" tools:text="2514785" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/tvCountryName" android:textColor="#fff" android:layout_marginLeft="16dp" tools:text="China" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </RelativeLayout>
Main class :
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); BottomNavigationView navView = findViewById(R.id.nav_view); navView.setItemIconTintList(null); // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); NavigationUI.setupWithNavController(navView, navController); } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="0dp" android:layout_marginEnd="0dp" app:itemTextAppearanceInactive="@style/buttomNavigationView" app:itemTextAppearanceActive="@style/buttomNavigationView" android:background="@color/colorPrimaryDark" android:layout_alignParentBottom="true" app:menu="@menu/bottom_nav_menu" /> <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/nav_view" app:defaultNavHost="true" app:navGraph="@navigation/mobile_navigation" /> </RelativeLayout>
Keep in mind, that the drawable mentioned in the XML layouts have to be added to the drawable folder, and poppins font to the font folder under res of the Android Studio Project.
The Output :