Calculadora MVVM

  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable
                name="vm"
                type="com.ktl.mvvm_calculadoraimc.CalculadoraIMCViewModel" />
        </data>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="16dp">
            <EditText
                android:id="@+id/editTextPeso"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:autofillHints=""
                android:hint="@string/digite_seu_peso"
                android:inputType="numberDecimal" />
            <EditText
                android:id="@+id/editTextAltura"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:autofillHints=""
                android:hint="@string/digite_sua_altura"
                android:inputType="numberDecimal" />
            <Button
                android:id="@+id/buttonCalcular"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/calcular" />
            <TextView
                android:id="@+id/textViewResultado"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{vm.tipo}" />
            <TextView
                android:id="@+id/textViewResultadoNumero"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{vm.resultado}" />
        </LinearLayout>
    </layout>
  • CalculadoraIMC.java

    public class CalculadoraIMC {
        public static double calcular(double peso, double altura) {
            return peso / (altura * altura);
        }
        public static String getTipo(double imc) {
            if (imc < 18.5) {
                return "Abaixo do peso";
            } else if (imc <= 24.9) {
                return "Peso normal";
            } else if (imc <= 29.9) {
                return "Sobrepeso";
            } else if (imc <= 34.9) {
                return "Obesidade Grau I";
            } else if (imc <= 39.9) {
                return "Obesidade Grau II";
            } else {
                return "Obesidade Grau III (mórbida)";
            }
        }
    }
  • CalculadoraIMCViewModel.java

    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    public class CalculadoraIMCViewModel extends ViewModel {
        private final MutableLiveData<String> resultado;
        private final MutableLiveData<String> tipo;
        public CalculadoraIMCViewModel() {
            this.tipo = new MutableLiveData<>();
            resultado = new MutableLiveData<>();
        }
        public MutableLiveData<String> getResultado() {
            return resultado;
        }
        public MutableLiveData<String> getTipo() {
            return tipo;
        }
        public void calcular(double peso, double altura) {
            double imc = CalculadoraIMC.calcular(peso, altura);
            resultado.setValue(String.valueOf(imc));
            tipo.setValue(CalculadoraIMC.getTipo(imc));
        }
    }
  • MainActivity.java

    import android.os.Bundle;
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    import androidx.databinding.DataBindingUtil;
    import androidx.lifecycle.ViewModelProvider;
    import com.ktl.mvvm_calculadoraimc.databinding.ActivityMainBinding;
    public class MainActivity extends AppCompatActivity {
        private CalculadoraIMCViewModel vm;
        private ActivityMainBinding binding;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            vm = new ViewModelProvider(this).get(CalculadoraIMCViewModel.class);
            binding.setVm(vm);
            binding.setLifecycleOwner(this);
            binding.buttonCalcular.setOnClickListener(v -> {
                double peso = Double.parseDouble(binding.editTextPeso.getText().toString());
                double altura = Double.parseDouble(binding.editTextAltura.getText().toString());
                vm.calcular(peso, altura);
            });
        }
    }

App GsonHttp com MVVM e DataBinding

  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout 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">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="10dp"
            tools:context=".view.MainActivity">
            <Button
                android:id="@+id/btObterDados"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:gravity="center"
                android:text="@string/obter_dados" />
            <ListView
                android:id="@+id/listViewDados"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@android:color/darker_gray"
                android:dividerHeight="1dp" />
        </LinearLayout>
    </layout>
  • item_contato.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable
                name="contato"
                type="com.example.appgsonhttp_01.model.InformacoesContato" />
        </data>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="16dp">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{contato.nome}"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                android:textStyle="bold" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{contato.telefone}"
                android:textSize="14sp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{contato.email}"
                android:textSize="14sp" />
        </LinearLayout>
    </layout>
  • activity_relatorio.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable
                name="viewModel"
                type="com.example.appgsonhttp_01.viewmodel.RelatorioViewModel" />
        </data>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_marginTop="30dp"
            android:padding="16dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text='@{"Nome: " + viewModel.nome_professor}'
                android:textSize="20sp"
                android:textStyle="bold" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text='@{"Email: " + viewModel.email_professor}'
                android:textSize="18sp" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text='@{"Telefone: " + viewModel.telefone_professor}'
                android:textSize="18sp"
                android:layout_marginBottom="12dp" />
        </LinearLayout>
    </layout>
  • Conexao.java

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    public class Conexao {
        public InputStream obterRespostaHTTP(String endURL) {
            HttpURLConnection conexao = null;
            try {
                URL url = new URL(endURL);
                conexao = (HttpURLConnection) url.openConnection();
                conexao.setConnectTimeout(50000);
                conexao.setReadTimeout(50000);
                conexao.setRequestMethod("GET");
                conexao.connect();
                return new BufferedInputStream(conexao.getInputStream());/// n esqueça
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }//
    }
  • Conversao.java

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    public class Conversao {
        public String converter(InputStream inputStream) {
            if(inputStream == null){
                return null;
            }
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader br = new BufferedReader(inputStreamReader);
            StringBuilder stringBuilder = new StringBuilder();
            String conteudo;
            try{
                while((conteudo = br.readLine())!= null){
                    stringBuilder.append(conteudo).append("\n");
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }
    }
  • Adicionais.java

    import javax.annotation.processing.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    @Generated("jsonschema2pojo")
    public class Adicionais {
        @SerializedName("id")
        @Expose
        private Integer id;
        @SerializedName("email")
        @Expose
        private String email;
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
    }
  • Agenda.java

    import javax.annotation.processing.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    @Generated("jsonschema2pojo")
    public class Agenda {
        @SerializedName("id")
        @Expose
        private Integer id;
        @SerializedName("nome")
        @Expose
        private String nome;
        @SerializedName("telefone")
        @Expose
        private String telefone;
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getNome() {
            return nome;
        }
        public void setNome(String nome) {
            this.nome = nome;
        }
        public String getTelefone() {
            return telefone;
        }
        public void setTelefone(String telefone) {
            this.telefone = telefone;
        }
    }
  • InformacoesContato.java

    import java.io.Serializable;
    public class InformacoesContato implements Serializable {
        private int id;
        private String nome, telefone, email;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getNome() {
            return nome;
        }
        public void setNome(String nome) {
            this.nome = nome;
        }
       public String getTelefone() {
            return telefone;
        }
        public void setTelefone(String telefone) {
            this.telefone = telefone;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
    }
  • Professores.java

    import java.util.List;
    import javax.annotation.processing.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    @Generated("jsonschema2pojo")
    public class Professores {
        @SerializedName("agenda")
        @Expose
        private List<Agenda> agenda;
        @SerializedName("adicionais")
        @Expose
        private List<Adicionais> adicionais;
        public List<Agenda> getAgenda() {
            return agenda;
        }
        public void setAgenda(List<Agenda> agenda) {
            this.agenda = agenda;
        }
        public List<Adicionais> getAdicionais() {
            return adicionais;
        }
        public void setAdicionais(List<Adicionais> adicionais) {
            this.adicionais = adicionais;
        }
    }
  • Repositorio.java

    mport android.os.Handler;
    import android.os.Looper;
    import com.example.appgsonhttp_01.util.Conexao;
    import com.example.appgsonhttp_01.util.Conversao;
    import com.google.gson.Gson;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class Repositorio {
        private static final String URL = "digite a URL";
        private ExecutorService executor;
        private Handler mainHandler;
        public Repositorio() {
            this.executor = Executors.newSingleThreadExecutor();
            this.mainHandler = new Handler(Looper.getMainLooper());
        }
        public interface Callback {
            void sucesso(List<InformacoesContato> lista);
            void erro(String mensagem);
        }
        private void sucesso(Callback c, List<InformacoesContato> lista) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    c.sucesso(lista);
                }
            });
        }
        private void erro(Callback c, String mensagem) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    c.erro(mensagem);
                }
            });
        }
        public void obterDados(Callback c) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    //tarefa da thread
                    try {
                        Conexao conexao = new Conexao();
                        InputStream inputStream = conexao.obterRespostaHTTP(URL);
                        Conversao conversao = new Conversao();
                        String jsonString = conversao.converter(inputStream);
                        if (jsonString == null || jsonString.isEmpty()) {
                            erro(c, "Erro - Não existe informações disponíveis");
                            return;
                        }
                        Gson gson = new Gson();
                        Professores professores = gson.fromJson(jsonString, Professores.class);
                        List<InformacoesContato> listaContatos = new ArrayList<>();
                        if (professores != null && professores.getAgenda() != null) {
                            for (Agenda ag : professores.getAgenda()) {
                                InformacoesContato contato = new InformacoesContato();
                                contato.setId(ag.getId());
                                contato.setNome(ag.getNome());
                                contato.setTelefone(ag.getTelefone());
                                if (professores.getAdicionais() != null) {
                                    for (Adicionais ad : professores.getAdicionais()) {
                                        if (ad.getId().equals(ag.getId())) {
                                            contato.setEmail(ad.getEmail());
                                            break;
                                        }
                                    }
                                }
                                listaContatos.add(contato);
                            }
                        }
                        sucesso(c, listaContatos);
                    } catch (Exception e) {
                        e.printStackTrace();
                        erro(c, "Erro - Não foi possível realizar o download" + e.getMessage());
                    }
                }
            });
        }//
    }//class
  • MainViewModel.java

    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    import com.example.appgsonhttp_01.model.InformacoesContato;
    import com.example.appgsonhttp_01.model.Repositorio;
    import java.util.List;
    public class MainViewModel extends ViewModel {
        private final MutableLiveData<List<InformacoesContato>> listaContatos = new MutableLiveData<>();
        private final MutableLiveData<String> mensagemErro = new MutableLiveData<>();
        private final Repositorio repositorio = new Repositorio();
        public LiveData<List<InformacoesContato>> getListaContatos() {
            return listaContatos;
        }
        public LiveData<String> getMensagemErro() {
            return mensagemErro;
        }
        public void carregarDadosDoRepositorio() {
            repositorio.obterDados(new Repositorio.Callback() {
                @Override
                public void sucesso(List<InformacoesContato> lista) {
                    listaContatos.setValue(lista);
                }
                @Override
                public void erro(String mensagem) {
                    mensagemErro.setValue(mensagem);
                }
            });
        }
    }
  • RelatorioViewModel.java

    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    public class RelatorioViewModel extends ViewModel {
        private final MutableLiveData<String> nome_professor = new MutableLiveData<>();
        private final MutableLiveData<String> email_professor = new MutableLiveData<>();
        private final MutableLiveData<String> telefone_professor = new MutableLiveData<>();
        public MutableLiveData<String> getNome_professor() {
            return nome_professor;
        }
        public MutableLiveData<String> getEmail_professor() {
            return email_professor;
        }
        public MutableLiveData<String> getTelefone_professor() {
            return telefone_professor;
        }
        public void pegarInformacoes(String nome_p, String email_p, String telefone_p) {
            this.nome_professor.setValue(nome_p);
            this.email_professor.setValue(email_p);
            this.telefone_professor.setValue(telefone_p);
        }
    }
  • ContatoAdapter.java

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import androidx.databinding.DataBindingUtil;
    import com.example.appgsonhttp_01.R;
    import com.example.appgsonhttp_01.databinding.ItemContatoBinding;
    import com.example.appgsonhttp_01.model.InformacoesContato;
    import java.util.List;
    public class ContatoAdapter extends ArrayAdapter<InformacoesContato> {
        public ContatoAdapter(Context context, List<InformacoesContato> contatos) {
            super(context, 0, contatos);
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ItemContatoBinding binding;
            if (convertView == null) {
                binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()),
                        R.layout.item_contato, parent, false);
                convertView = binding.getRoot();
                convertView.setTag(binding);
            } else {
                binding = (ItemContatoBinding) convertView.getTag();
            }
            InformacoesContato contato = getItem(position);
            if (contato != null) {
                binding.setContato(contato);
                binding.executePendingBindings();
            }
            return convertView;
        }
    }
  • RelatorioActivity.java

    import android.os.Bundle;
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import com.example.appgsonhttp_01.R;
    import com.example.appgsonhttp_01.viewmodel.RelatorioViewModel;
    import com.example.appgsonhttp_01.databinding.ActivityRelatorioBinding;
    import androidx.databinding.DataBindingUtil;
    import androidx.lifecycle.ViewModelProvider;
    public class RelatorioActivity extends AppCompatActivity {
        private ActivityRelatorioBinding binding;
        private RelatorioViewModel viewModel;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_relatorio);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_relatorio);
            binding.setLifecycleOwner(this);
            viewModel = new ViewModelProvider(this).get(RelatorioViewModel.class);
            binding.setViewModel(viewModel);
            String professor_nome = getIntent().getStringExtra("nome");
            String professor_email = getIntent().getStringExtra("email");
            String professor_telefone = getIntent().getStringExtra("telefone");
            viewModel.pegarInformacoes(professor_nome,professor_email,professor_telefone);
        }
    }
  • MainActivity.java

    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.databinding.DataBindingUtil;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProvider;
    import com.example.appgsonhttp_01.viewmodel.MainViewModel;
    import com.example.appgsonhttp_01.R;
    import com.example.appgsonhttp_01.databinding.ActivityMainBinding;
    import com.example.appgsonhttp_01.model.InformacoesContato;
    import java.util.ArrayList;
    import java.util.List
    public class MainActivity extends AppCompatActivity {
        private ActivityMainBinding binding;
        private ContatoAdapter adapter;
        private List<InformacoesContato> lista;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            lista = new ArrayList<>();
            adapter = new ContatoAdapter(this, lista);
            binding.listViewDados.setAdapter(adapter);
            binding.listViewDados.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    InformacoesContato contatoSelecionado = lista.get(position);
                    Intent intent = new Intent(MainActivity.this, RelatorioActivity.class);
                    intent.putExtra("nome", contatoSelecionado.getNome());
                    intent.putExtra("email", contatoSelecionado.getEmail());
                    intent.putExtra("telefone", contatoSelecionado.getTelefone());
                    startActivity(intent);
                }
            });
            binding.btObterDados.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    viewModel.carregarDadosDoRepositorio();
                }
            });
            viewModel.getListaContatos().observe(this, new Observer<List<InformacoesContato>>() {
                @Override
                public void onChanged(List<InformacoesContato> contatos) {
                    lista.clear();
                    lista.addAll(contatos);
                    adapter.notifyDataSetChanged();
                }
            });
        }
    }

AppHttp com ViewModel

  • activity_main.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:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activity.MainActivity">
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/consolidacao"
            app:layout_constraintBottom_toTopOf="@+id/student_list"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/student_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="63dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="227dp" />
    </androidx.constraintlayout.widget.ConstraintLayout>
  • activity_status.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:id="@+id/status_activity"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activity.StatusActivity">
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/voltar"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.120000005" />
        <TextView
            android:id="@+id/class_average"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@+id/guideline2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button" />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/student_status_list"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginBottom="63dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline2" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="227dp" />
    </androidx.constraintlayout.widget.ConstraintLayout>
  • activity_status_list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:id="@+id/student_status_list_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/student_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/student_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/student_attendance"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/student_grades"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
  • students_list_item.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="wrap_content"
        android:id="@+id/student_list_item">
        <TextView
            android:id="@+id/student_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0"
            tools:layout_editor_absoluteX="102dp" />
        <TextView
            android:id="@+id/student_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/student_name"
            app:layout_constraintVertical_bias="0.0"
            tools:layout_editor_absoluteX="0dp" />
        <TextView
            android:id="@+id/student_grades"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/student_age"
            app:layout_constraintVertical_bias="0.0"
            tools:layout_editor_absoluteX="16dp" />
        <TextView
            android:id="@+id/student_attendance"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/student_grades"
            app:layout_constraintVertical_bias="0.0"
            tools:layout_editor_absoluteX="-27dp" />
    </androidx.constraintlayout.widget.ConstraintLayout>
  • MainActivity.java

    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProvider;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import com.example.atividade3.adapter.StudentListAdapter;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.databinding.ActivityMainBinding;
    import com.example.atividade3.viewmodel.MainViewModel;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity {
        private ActivityMainBinding binding;
        private MainViewModel viewmodel;
        private StudentListAdapter adapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityMainBinding.inflate(getLayoutInflater());
            setContentView(binding.getRoot());
            viewmodel = new ViewModelProvider(this).get(MainViewModel.class);
            adapter = new StudentListAdapter(new ArrayList<>());
            binding.studentList.setLayoutManager(new LinearLayoutManager(this));
            binding.studentList.setAdapter(adapter);
            binding.button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(MainActivity.this, StatusActivity.class);
                    startActivity(intent);
                }
            });
            viewmodel.getStudents().observe(this, new Observer<List<Student>>() {
                @Override
                public void onChanged(List<Student> students) {
                    if (students != null) {
                        adapter.setStudents(students);
                        adapter.notifyDataSetChanged();
                    }
                }
            });
            viewmodel.loadData();
        }
    }
  • StatusActivity.java

    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProvider;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import com.example.atividade3.adapter.StudentStatusListAdapter;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.databinding.ActivityStatusBinding;
    import com.example.atividade3.viewmodel.StatusViewModel;
    import java.util.ArrayList;
    import java.util.List;
    public class StatusActivity extends AppCompatActivity {
        private ActivityStatusBinding binding;
        private StatusViewModel viewmodel;
        private StudentStatusListAdapter adapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityStatusBinding.inflate(getLayoutInflater());
            setContentView(binding.getRoot());
            viewmodel = new ViewModelProvider(this).get(StatusViewModel.class);
            adapter = new StudentStatusListAdapter(new ArrayList<>());
            binding.studentStatusList.setLayoutManager(new LinearLayoutManager(this));
            binding.studentStatusList.setAdapter(adapter);
            binding.button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(StatusActivity.this, MainActivity.class);
                    startActivity(intent);
                }
            });
            viewmodel.getStudents().observe(this, new Observer<List<Student>>() {
                @Override
                public void onChanged(List<Student> students) {
                    if (students != null) {
                        adapter.setStudents(students);
                        adapter.notifyDataSetChanged();
                    }
                }
            });
            viewmodel.getClassAverage().observe(this, new Observer<String>() {
                @Override
                public void onChanged(String s) {
                    if (s != null) {
                        binding.classAverage.setText("Média da turma: " + s);
                    }
                }
            });
            viewmodel.loadData();
        }
    }
  • StudentListAdapter.java

    import android.view.LayoutInflater;
    import android.view.ViewGroup;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.databinding.StudentsListItemBinding;
    import java.util.List;
    public class StudentListAdapter extends RecyclerView.Adapter<StudentListAdapter.StudentViewHolder> {
        private List<Student> students;
        public StudentListAdapter(List<Student> students) {
            this.students = students;
        }
        public List<Student> getStudents() {
            return students;
        }
        public void setStudents(List<Student> students) {
            this.students = students;
        }
        @NonNull
        @Override
        public StudentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            StudentsListItemBinding binding = StudentsListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
            return new StudentViewHolder(binding);
        }
        @Override
        public void onBindViewHolder(@NonNull StudentViewHolder holder, int position) {
            holder.binding.studentName.setText("Nome: " + students.get(position).getName());
            holder.binding.studentAge.setText("Idade: " + students.get(position).getAge().toString());
            holder.binding.studentAttendance.setText("Notas: " + students.get(position).getAttendance().toString());
            holder.binding.studentGrades.setText("Presenças: " + students.get(position).getGrades().toString());
        }
        @Override
        public int getItemCount() {
            return students.size();
        }
        public static class StudentViewHolder extends RecyclerView.ViewHolder {
            StudentsListItemBinding binding;
            public StudentViewHolder(StudentsListItemBinding binding) {
                super(binding.getRoot());
                this.binding = binding;
            }
        }
    }
  • StudentStatusListAdapter.java

    import android.view.LayoutInflater;
    import android.view.ViewGroup;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.databinding.StudentStatusListItemBinding;
    import java.util.List;
    public class StudentStatusListAdapter extends RecyclerView.Adapter<StudentStatusListAdapter.StudentStatusViewHolder> {
        private List<Student> students;
        public StudentStatusListAdapter(List<Student> students) {
            this.students = students;
        }
        public List<Student> getStudents() {
            return students;
        }
        public void setStudents(List<Student> students) {
            this.students = students;
        }
        @NonNull
        @Override
        public StudentStatusListAdapter.StudentStatusViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            StudentStatusListItemBinding binding = StudentStatusListItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
            return new StudentStatusListAdapter.StudentStatusViewHolder(binding);
        }
        @Override
        public void onBindViewHolder(@NonNull StudentStatusListAdapter.StudentStatusViewHolder holder, int position) {
            holder.binding.studentName.setText("Nome: " + students.get(position).getName());
            holder.binding.studentAttendance.setText("Presença: " + String.format("%.2f", students.get(position).calculateAttendancePercentage()));
            holder.binding.studentAge.setText("Nota final: " + String.format("%.2f", students.get(position).calculateAverageGrade()));
            holder.binding.studentGrades.setText("Status: " + students.get(position).isApproved());
        }
        @Override
        public int getItemCount() {
            return students.size();
        }
        public static class StudentStatusViewHolder extends RecyclerView.ViewHolder {
            StudentStatusListItemBinding binding;
            public StudentStatusViewHolder(StudentStatusListItemBinding binding) {
                super(binding.getRoot());
                this.binding = binding;
            }
        }
    }
  • Student.java

    import java.util.ArrayList;
    import java.util.List;
    public class Student {
        private String name;
        private Integer age;
        private List<Double> grades;
        private List<Boolean> attendance;
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
            this.grades = new ArrayList<>();
            this.attendance = new ArrayList<>();
        }
        public Integer getAge() {
            return age;
        }
        public String getName() {
            return name;
        }
        public List<Double> getGrades() {
            return grades;
        }
        public List<Boolean> getAttendance() {
            return attendance;
        }
        public double calculateAverageGrade() {
            double sum = 0.0;
            for (double grade : grades) {
                sum += grade;
            }
            return sum / grades.size();
        }
        public double calculateAttendancePercentage() {
            int presentCount = 0;
            for (boolean present : attendance) {
                if (present) {
                    presentCount++;
                }
            }
            return ((double) presentCount) / attendance.size() * 100;
        }
        public void addGrades(List<Double> grades) {
            this.grades.addAll(grades);
        }
        public void addAttendance(List<Boolean> attendance) {
            this.attendance.addAll(attendance);
        }
        public String isApproved() {
            boolean isApproved = calculateAverageGrade() >= 6.0 && calculateAttendancePercentage() >= 75.0;
            if (isApproved){
                return "Aprovado";
            }else{
                return "Reprovado";
            }
        }
    }
  • Connection.java

    import android.util.Log;
    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    public class Connection {
        public InputStream sendRequest(String endURL) {
            HttpURLConnection connection = null;
            try {
                URL url = new URL(endURL);
                connection = (HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(50000);
                connection.setReadTimeout(50000);
                connection.setRequestMethod("GET");
                connection.connect();
                return new BufferedInputStream(connection.getInputStream());
            } catch (IOException e) {
                Log.e("Connection error", "Error while connecting to the url");
            }
            return null;
        }
    }
  • ResponseDto.java

    import com.google.gson.annotations.SerializedName;
    import java.util.List;
    public class ResponseDto {
        @SerializedName("students")
        public List<StudentDto> students;
    }
  • StudentDto.java

    import com.google.gson.annotations.SerializedName;
    import java.util.List;
    public class StudentDto {
        @SerializedName("nome")
        public String name;
        @SerializedName("idade")
        public int age;
        @SerializedName("notas")
        public List<Double> notes;
        @SerializedName("presenca")
        public List<Boolean> attendance;
    }
  • StudentRepository.java

    import android.os.Handler;
    import android.os.Looper;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.repository.connection.Connection;
    import com.example.atividade3.repository.dto.ResponseDto;
    import com.example.atividade3.repository.dto.StudentDto;
    import com.google.gson.Gson;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class StudentRepository {
        private static StudentRepository instance;
        private List<Student> students;
        private final String API_URL = "digite a URL";
        private ExecutorService executor;
        private Handler mainHandler;
        public StudentRepository() {
            this.executor = Executors.newSingleThreadExecutor();
            this.mainHandler = new Handler(Looper.getMainLooper());
        }
        public static StudentRepository getInstance() {
            if (instance == null) {
                instance = new StudentRepository();
            }
            return instance;
        }
        public interface Callback {
            void onSuccess(List<Student> items);
            void onError(String msg);
        }
        private void success(Callback c, List<Student> students) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    c.onSuccess(students);
                }
            });
        }
        private void error(Callback c, String msg) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    c.onError(msg);
                }
            });
        }
        public void fetchStudents(Callback callback) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Connection connection = new Connection();
                        InputStreamReader reader = new InputStreamReader(connection.sendRequest(API_URL));
                        ResponseDto studentsResponse = new Gson().fromJson(reader, ResponseDto.class);
                        List<Student> students = new ArrayList<>();
                        for (StudentDto studentDto : studentsResponse.students) {
                            Student student = new Student(studentDto.name, studentDto.age);
                            student.addGrades(studentDto.notes);
                            student.addAttendance(studentDto.attendance);
                            students.add(student);
                        }
                        success(callback, students);
                    } catch (Exception e) {
                        error(callback, "Error while fetching students");
                    }
                }
            });
        }
    }
  • MainViewModel.java

    import android.util.Log;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.repository.StudentRepository;
    import java.util.List;
    public class MainViewModel extends ViewModel {
        private MutableLiveData<List<Student>> students;
        private final StudentRepository repository;
        public MainViewModel() {
            this.students = new MutableLiveData<>();
            this.repository = StudentRepository.getInstance();
        }
        public MutableLiveData<List<Student>> getStudents() {
            return students;
        }
        public void loadData() {
            repository.fetchStudents(new StudentRepository.Callback() {
                @Override
                public void onSuccess(List<Student> items) {
                    students.setValue(items);
                }
                @Override
                public void onError(String msg) {
                    Log.e("Error", msg);
                }
            });
        }
    }
  • StatusViewModel.java

    import android.util.Log;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    import com.example.atividade3.data.model.Student;
    import com.example.atividade3.repository.StudentRepository;
    import java.util.List;
    public class StatusViewModel extends ViewModel {
        private MutableLiveData<List<Student>> students;
        private MutableLiveData<String> classAverage;
        private final StudentRepository repository;
        public StatusViewModel() {
            this.repository = StudentRepository.getInstance();
            this.students = new MutableLiveData<>();
            this.classAverage = new MutableLiveData<>();
        }
        public MutableLiveData<List<Student>> getStudents() {
            return students;
        }
        public MutableLiveData<String> getClassAverage() {
            return classAverage;
        }
        private double calculateAverageGrade() {
            double sum = 0.0;
            for (Student s : students.getValue()) {
                sum += s.calculateAverageGrade();
            }
            return sum / students.getValue().size();
        }
        public void loadData() {
            repository.fetchStudents(new StudentRepository.Callback() {
                @Override
                public void onSuccess(List<Student> items) {
                    students.setValue(items);
                    classAverage.setValue(String.format("%.2f", calculateAverageGrade()));
                }
                @Override
                public void onError(String msg) {
                    Log.e("Error", msg);
                }
            });
        }
    }

App NavigationDrawer/Http/ViewModel

Como este exemplo usa a template fornecida pelo AndroidStudio, foi disponibilizado apenas as classes JAVA.

  • Student.java

    import java.util.List;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    public class Student{
        @SerializedName("nome")
        @Expose
        private String nome;
        @SerializedName("idade")
        @Expose
        private Integer idade;
        @SerializedName("notas")
        @Expose
        private List<Double> notas;
        @SerializedName("presenca")
        @Expose
        private List<Boolean> presenca;
        public Student(String nome, Integer idade, List<Double> notas, List<Boolean> presenca) {
            this.nome = nome;
            this.idade = idade;
            this.notas = notas;
            this.presenca = presenca;
        }
        public String getNome() {
            return nome;
        }
        public void setNome(String nome) {
            this.nome = nome;
        }
        public Integer getIdade() {
            return idade;
        }
        public void setIdade(Integer idade) {
            this.idade = idade;
        }
        public List<Double> getNotas() {
            return notas;
        }
        public void setNotas(List<Double> notas) {
            this.notas = notas;
        }
        public List<Boolean> getPresenca() {
            return presenca;
        }
        public void setPresenca(List<Boolean> presenca) {
            this.presenca = presenca;
        }
        public String obterStatus() {
            double media = calcularMedia();
            if (media >= 6 && calcularPresenca() >= 75) {
                return "Aprovado";
            } else {
                return "Reprovado";
            }
        }
        public double calcularMedia() {
            double soma = 0;
            for (int i = 0; i < notas.size(); i++) {
                soma += notas.get(i);
            }
            return soma / notas.size();
        }
        public double calcularPresenca() {
            double soma = 0;
            for (int i = 0; i < presenca.size(); i++) {
                if (presenca.get(i)) {
                    soma++;
                }
            }
            return (soma / presenca.size()) * 100;
        }
        public String getNotasFormatadas() {
            if (notas == null || notas.isEmpty()) {
                return "Sem notas";
            }
            StringBuilder sb = new StringBuilder();
            int tamanho = notas.size();
            for (int i = 0; i < tamanho; i++) {
                sb.append(notas.get(i));
                if (i < tamanho - 1) {
                    sb.append(", ");
                }
            }
            return sb.toString();
        }
        public String getPresencaFormatada() {
            if (presenca == null || presenca.isEmpty()) {
                return "Sem registro";
            }
            StringBuilder sb = new StringBuilder();
            int tamanho = presenca.size();
            for (int i = 0; i < tamanho; i++) {
                if (presenca.get(i)) {
                    sb.append("presente");
                } else {
                    sb.append("faltou");
                }
                if (i < tamanho - 1) {
                    sb.append(", ");
                }
            }
            return sb.toString();
        }
    }
  • Turma.java

    import java.util.List;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    public class Turma {
        @SerializedName("students")
        @Expose
        private List<Student> students;
        public List<Student> getStudents() {
            return students;
        }
        public void setStudents(List<Student> students) {
            this.students = students;
        }
    }
  • Repository.java

    import android.util.Log;
    import com.example.tarefa4estudantesnavviewdrawer.pojo.Student;
    import com.example.tarefa4estudantesnavviewdrawer.pojo.Turma;
    import com.example.tarefa4estudantesnavviewdrawer.util.Conexao;
    import com.example.tarefa4estudantesnavviewdrawer.util.Conversao;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    import java.io.InputStream;
    import java.lang.reflect.Type;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class Repository {
        private static final String URL = "digite a URL";
        private ExecutorService executorService;
        public Repository() {
            this.executorService = Executors.newSingleThreadExecutor();
        }
        public interface Callback{
            void sucesso (List<Student> estudantes);
            void erro (String mensagem);
        }
        public void obterDados(Callback c){
            executorService.execute(() -> {
                try {
                    Conexao conexao = new Conexao();
                    InputStream inputStream = conexao.obterRespostaHTTP(URL);
                    Conversao conversao = new Conversao();
                    String jsonString = conversao.converter(inputStream);
                    if (jsonString == null || jsonString.isEmpty()) {
                        c.erro("Resposta vazia");
                        return;
                    }
                    Log.i("JSON", "Recebido " + jsonString);
                    Gson gson = new Gson();
                    Type type = new TypeToken<Turma>(){}.getType();
                    Turma dados = gson.fromJson(jsonString, type);
                    c.sucesso(dados.getStudents());
                } catch (Exception e) {
                    c.erro("Erro ao baixar dados: " + e.getMessage());
                }
            });
        }
        public void shutdown() {
            executorService.shutdown();
        }
    }
  • MainFragment.java

    import android.content.Intent;
    import android.os.Bundle;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.lifecycle.ViewModelProvider;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Toast;
    import com.example.tarefa4estudantesnavviewdrawer.SharedViewModel;
    import com.example.tarefa4estudantesnavviewdrawer.StudentAdapter;
    import com.example.tarefa4estudantesnavviewdrawer.databinding.FragmentMainBinding;
    public class MainFragment extends Fragment {
        private FragmentMainBinding binding;
        private SharedViewModel viewModel;
        private StudentAdapter adapter;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            binding = FragmentMainBinding.inflate(inflater, container, false);
            return binding.getRoot();
        }
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            adapter = new StudentAdapter();
            binding.listView.setLayoutManager(new LinearLayoutManager(requireContext()));
            binding.listView.setAdapter(adapter);
            viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
            viewModel.getEstudantesLiveData().observe(getViewLifecycleOwner(), estudantes -> {
                if (estudantes != null && !estudantes.isEmpty()) {
                    adapter.substituirLista(estudantes);
                }
            });
            viewModel.getMensagem().observe(getViewLifecycleOwner(), mensagem -> {
                Toast.makeText(requireContext(), mensagem, Toast.LENGTH_SHORT).show();
            });
        }
    }
  • MediaFragment.java

    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.lifecycle.ViewModelProvider;
    import com.example.tarefa4estudantesnavviewdrawer.SharedViewModel;
    import com.example.tarefa4estudantesnavviewdrawer.databinding.FragmentMediaBinding;
    public class MediaFragment extends Fragment {
        private FragmentMediaBinding binding;
        private SharedViewModel viewModel;
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            binding = FragmentMediaBinding.inflate(inflater, container, false);
            return binding.getRoot();
        }
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
            viewModel.getMediaTurmaLiveData().observe(getViewLifecycleOwner(), media -> {
                if (media != null) {
                    binding.txtViewMediaTurma.setText(String.format("Média Geral: %.1f", media));
                }
            });
        }
    }
  • ResultoFragment.java

    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.lifecycle.ViewModelProvider;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import com.example.tarefa4estudantesnavviewdrawer.SharedViewModel;
    import com.example.tarefa4estudantesnavviewdrawer.StudentStatusAdapter;
    import com.example.tarefa4estudantesnavviewdrawer.databinding.FragmentResultadoBinding;
    public class ResultadoFragment extends Fragment {
        private FragmentResultadoBinding binding;
        private SharedViewModel viewModel;
        private StudentStatusAdapter adapter;
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            binding = FragmentResultadoBinding.inflate(inflater, container, false);
            return binding.getRoot();
        }
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            adapter = new StudentStatusAdapter();
            binding.listView.setLayoutManager(new LinearLayoutManager(requireContext()));
            binding.listView.setAdapter(adapter);
            viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
            viewModel.getEstudantesLiveData().observe(getViewLifecycleOwner(), estudantes -> {
                if (estudantes != null && !estudantes.isEmpty()) {
                    adapter.substituirLista(estudantes);
                }
            });
        }
    }
  • Conexao.java

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    public class Conexao {
        public InputStream obterRespostaHTTP(String end) {
            HttpURLConnection conexao = null;
            try {
                URL url = new URL(end);
                conexao = (HttpURLConnection) url.openConnection();
                conexao.setConnectTimeout(50000);
                conexao.setReadTimeout(50000);
                conexao.setRequestMethod("GET");
                conexao.connect();
                return new BufferedInputStream(conexao.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
  • Conversao.java

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    public class Conversao {
        public String converter(InputStream inputStream) {
            if (inputStream == null) return null;
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder stringBuilder = new StringBuilder();
            String conteudo;
            try {
                while ((conteudo = bufferedReader.readLine()) != null) {
                    stringBuilder.append(conteudo).append("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }
    }
  • MainActivity.java

    import android.os.Bundle;
    import android.view.View;
    import android.view.Menu;
    import com.google.android.material.snackbar.Snackbar;
    import com.google.android.material.navigation.NavigationView;
    import androidx.navigation.NavController;
    import androidx.navigation.Navigation;
    import androidx.navigation.ui.AppBarConfiguration;
    import androidx.navigation.ui.NavigationUI;
    import androidx.drawerlayout.widget.DrawerLayout;
    import androidx.appcompat.app.AppCompatActivity;
    import com.example.tarefa4estudantesnavviewdrawer.databinding.ActivityMainBinding;
    public class MainActivity extends AppCompatActivity {
        private AppBarConfiguration mAppBarConfiguration;
        private ActivityMainBinding binding;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityMainBinding.inflate(getLayoutInflater());
            setContentView(binding.getRoot());
            setSupportActionBar(binding.appBarMain.toolbar);
            DrawerLayout drawer = binding.drawerLayout;
            NavigationView navigationView = binding.navView;
            // Passing each menu ID as a set of Ids because each
            // menu should be considered as top level destinations.
            mAppBarConfiguration = new AppBarConfiguration.Builder(
                    R.id.nav_main, R.id.nav_resultado, R.id.nav_media)
                    .setOpenableLayout(drawer)
                    .build();
            NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
            NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
            NavigationUI.setupWithNavController(navigationView, navController);
        }
        @Override
        public boolean onSupportNavigateUp() {
            NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
            return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                    || super.onSupportNavigateUp();
        }
    }
  • SharedViewModel.java

    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;
    import com.example.tarefa4estudantesnavviewdrawer.pojo.Student;
    import com.example.tarefa4estudantesnavviewdrawer.repository.Repository;
    import java.util.List;
    public class SharedViewModel extends ViewModel {
        private Repository repository;
        private MutableLiveData<List<Student>> estudantesLiveData;
        private MutableLiveData<String> mensagemLiveData;
        private MutableLiveData<Double> mediaTurmaLiveData;
        public SharedViewModel() {
            this.repository = new Repository();
            this.estudantesLiveData = new MutableLiveData<>();
            this.mensagemLiveData = new MutableLiveData<>();
            this.mediaTurmaLiveData = new MutableLiveData<>();
            carregarDados();
        }
        public LiveData<List<Student>> getEstudantesLiveData() {
            return estudantesLiveData;
        }
        public LiveData<String> getMensagem() {
            return mensagemLiveData;
        }
        public LiveData<Double> getMediaTurmaLiveData() {
            return mediaTurmaLiveData;
        }
        public void carregarDados() {
            if (estudantesLiveData.getValue() != null) {
                return;
            }
            repository.obterDados(new Repository.Callback() {
                @Override
                public void sucesso(List<Student> estudantes) {
                    estudantesLiveData.postValue(estudantes);
                    calcularMediaGeral(estudantes);
                }
                @Override
                public void erro(String mensagem) {
                    mensagemLiveData.postValue(mensagem);
                }
            });
        }
        private void calcularMediaGeral(List<Student> estudantes) {
            if (estudantes == null || estudantes.isEmpty()) {
                mediaTurmaLiveData.postValue(0.0);
                return;
            }
            double somaTodasAsMedias = 0;
            for (Student aluno : estudantes) {
                somaTodasAsMedias += aluno.calcularMedia();
            }
            double mediaFinal = somaTodasAsMedias / estudantes.size();
            mediaTurmaLiveData.postValue(mediaFinal);
        }
        @Override
        protected void onCleared() {
            super.onCleared();
            repository.shutdown();
        }
    }
  • StudentAdapter.java

    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import com.example.tarefa4estudantesnavviewdrawer.pojo.Student;
    import java.util.ArrayList;
    import java.util.List;
    public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.ViewHolder>{
        private final List<Student> estudantes = new ArrayList<>();
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_lista_completa, parent, false);
            return new ViewHolder(view);
        }
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            Student estudante = estudantes.get(position);
            holder.nome.setText(estudante.getNome());
            holder.idade.setText(String.valueOf(estudante.getIdade()));
            holder.notas.setText("Notas: " + estudante.getNotasFormatadas());
            holder.presenca.setText("Presença: " + estudante.getPresencaFormatada());
        }
        @Override
        public int getItemCount() {
            return estudantes.size();
        }
        public void substituirLista(List<Student> estudantesNovo) {
            estudantes.clear();
            if(estudantes!=null){
                estudantes.addAll(estudantesNovo);
            }
            notifyDataSetChanged();
        }
        static class ViewHolder extends RecyclerView.ViewHolder{
            TextView nome;
            TextView idade;
            TextView notas;
            TextView presenca;
            public ViewHolder(@NonNull View itemView) {
                super(itemView);
                nome = itemView.findViewById(R.id.txtViewNome);
                idade = itemView.findViewById(R.id.txtViewIdade);
                notas = itemView.findViewById(R.id.txtViewNotas);
                presenca = itemView.findViewById(R.id.txtViewPresenca);
            }
        }
    }
  • StudentStatusAdapter.java

    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import com.example.tarefa4estudantesnavviewdrawer.pojo.Student;
    import java.util.ArrayList;
    import java.util.List;
    public class StudentStatusAdapter extends RecyclerView.Adapter<StudentStatusAdapter.ViewHolder> {
        private final List<Student> estudantes = new ArrayList<>();
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_lista_status, parent, false);
            return new ViewHolder(view);
        }
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            Student estudante = estudantes.get(position);
            holder.nome.setText(estudante.getNome());
            holder.status.setText(estudante.obterStatus());
        }
        @Override
        public int getItemCount() {
            return estudantes.size();
        }
        public void substituirLista(List<Student> estudantesNovo) {
            estudantes.clear();
            if(estudantes!=null){
                estudantes.addAll(estudantesNovo);
            }
            notifyDataSetChanged();
        }
        static class ViewHolder extends RecyclerView.ViewHolder{
            TextView nome;
            TextView status;
            public ViewHolder(@NonNull View itemView) {
                super(itemView);
                nome = itemView.findViewById(R.id.txtViewNomeStatus);
                status = itemView.findViewById(R.id.txtViewStatus);
            }
        }
    }