diff --git a/app/build.gradle b/app/build.gradle index 59c4418..a9f0d49 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { targetSdkVersion 28 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -16,21 +16,64 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.android.support:support-v4:28.0.0' - testImplementation 'junit:junit:4.12' - implementation 'de.hdodenhof:circleimageview:3.0.0' + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.material:material:1.0.0' + + // Dependecias Archutecture components + // Room database + implementation "androidx.room:room-runtime:2.1.0" + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + annotationProcessor "androidx.room:room-compiler:2.1.0" + implementation "androidx.room:room-rxjava2:2.1.0" + + // ViewModel and LiveData + implementation "androidx.lifecycle:lifecycle-extensions:2.0.0" + implementation "androidx.lifecycle:lifecycle-common-java8:2.0.0" + implementation "androidx.lifecycle:lifecycle-reactivestreams:2.0.0" + + /*############################ Gson: Json Converter ##########################*/ + implementation "com.google.code.gson:gson:2.8.5" - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' - implementation 'com.android.support:design:28.0.0' - implementation 'com.android.support:recyclerview-v7:28.0.0' - implementation 'com.android.support:cardview-v7:28.0.0' + /*########################### ReactiveX ######################################*/ + implementation "io.reactivex.rxjava2:rxandroid:2.0.2" + implementation "io.reactivex.rxjava2:rxjava:2.1.9" + /*############################################################################*/ + /*############################ Retrofit ######################################*/ + implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0" + implementation "com.squareup.retrofit2:retrofit:2.4.0" + implementation "com.squareup.okhttp3:logging-interceptor:3.4.1" + // Facebook Sthetho + implementation "com.facebook.stetho:stetho:1.5.0" + implementation "com.facebook.stetho:stetho-okhttp3:1.5.0" + implementation "com.squareup.retrofit2:converter-gson:2.4.0" + /*############################################################################*/ + implementation 'com.squareup.picasso:picasso:2.71828' + + /*############################# REDES SOCIAIS ##################################*/ + implementation 'com.google.android.gms:play-services-auth:17.0.0' + implementation 'com.facebook.android:facebook-android-sdk:[5,6)' + + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'de.hdodenhof:circleimageview:3.0.0' + + /*########################### FIRE BASE ################################*/ + implementation 'com.google.firebase:firebase-core:17.0.1' + implementation 'com.google.firebase:firebase-auth:18.1.0' + implementation 'com.google.firebase:firebase-database:18.0.0' } +apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin + diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..f5ba2b2 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,48 @@ +{ + "project_info": { + "project_number": "981079449550", + "firebase_url": "https://dhnews-4c852.firebaseio.com", + "project_id": "dhnews-4c852", + "storage_bucket": "dhnews-4c852.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:981079449550:android:653cf61d23a7be21", + "android_client_info": { + "package_name": "br.com.dhnews" + } + }, + "oauth_client": [ + { + "client_id": "981079449550-4e5fo4k6lfn85iv2faqhqv431fvdd0hc.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "br.com.dhnews", + "certificate_hash": "1b0640848fe97a8b39b4f28bdf31cbcd1ecd2cdf" + } + }, + { + "client_id": "981079449550-4v0clknv22gpjt5b1roiltht80magor3.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyC-IVM1cWS9Tnou_UbeqNnlFW4Kf9dQWTU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "981079449550-4v0clknv22gpjt5b1roiltht80magor3.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/src/androidTest/java/br/com/dhnews/ExampleInstrumentedTest.java b/app/src/androidTest/java/br/com/dhnews/ExampleInstrumentedTest.java index f32b42e..6e87e99 100644 --- a/app/src/androidTest/java/br/com/dhnews/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/br/com/dhnews/ExampleInstrumentedTest.java @@ -1,8 +1,8 @@ package br.com.dhnews; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3b10362..1f3d913 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,9 @@ + + + - - - + + + + + @@ -30,7 +35,7 @@ android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" /> - + \ No newline at end of file diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000..2342b49 Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ diff --git a/app/src/main/java/br/com/dhnews/adapters/NoticiasAdapter.java b/app/src/main/java/br/com/dhnews/adapters/NoticiasAdapter.java deleted file mode 100644 index 145fae3..0000000 --- a/app/src/main/java/br/com/dhnews/adapters/NoticiasAdapter.java +++ /dev/null @@ -1,125 +0,0 @@ -package br.com.dhnews.adapters; - -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import java.util.List; - -import br.com.dhnews.interfaces.RecyclerViewClickListener; -import br.com.dhnews.R; -import br.com.dhnews.model.Noticias; -import br.com.dhnews.model.Usuario; - - -public class NoticiasAdapter extends RecyclerView.Adapter { - - private List listaNoticias; - private RecyclerViewClickListener listener; - private Usuario usuario; - - - public NoticiasAdapter(List listaNoticias, RecyclerViewClickListener listener) { - this.listaNoticias = listaNoticias; - this.listener = listener; - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { - - View view = LayoutInflater.from(viewGroup.getContext()).inflate - (R.layout.layout_lista_item_noticias, viewGroup, false); - - return new ViewHolder(view); - } - - - @Override - public void onBindViewHolder(@NonNull NoticiasAdapter.ViewHolder viewHolder, final int position) { - - final Noticias noticias = listaNoticias.get(position); - viewHolder.setaNoticiasNaTela(noticias); - - //Click na imagem da noticia para chamar o detalhe da noticia - viewHolder.imagemNoticias.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onClick(noticias); - } - }); - - //Click no titulo da noticia para chamar o detalhe da noticia - viewHolder.tituloNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onClick(noticias); - } - }); - - //Click na descrição da noticia para chamar o detalhe da noticia - viewHolder.descricaoNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onClick(noticias); - } - }); - - viewHolder.imagemBookMarkListaNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - Usuario usuarioLocal = new Usuario(); - - if (usuario == null) { - usuarioLocal.setEmailUsuario("teste"); - } - - listener.onClick(usuarioLocal); - } - }); - } - - @Override - public int getItemCount() { - return listaNoticias.size(); - } - - - public class ViewHolder extends RecyclerView.ViewHolder { - TextView tituloNoticia; - TextView descricaoNoticia; - TextView horaNoticia; - TextView assuntoNoticia; - ImageView imagemNoticias; - ImageView imagemBookMarkListaNoticia; - - public ViewHolder(@NonNull View itemView) { - super(itemView); - - tituloNoticia = itemView.findViewById(R.id.txtTitulo); - descricaoNoticia = itemView.findViewById(R.id.txtDescricao); - horaNoticia = itemView.findViewById(R.id.txtHora); - assuntoNoticia = itemView.findViewById(R.id.txtAssunto); - imagemNoticias = itemView.findViewById(R.id.iconeNoticia); - imagemBookMarkListaNoticia = itemView.findViewById(R.id.imagemBookMarkListaNoticia); - } - - - //Atribui o as views os valores da variável contato - public void setaNoticiasNaTela(Noticias noticias) { - - tituloNoticia.setText(noticias.getTituloNoticia()); - descricaoNoticia.setText(noticias.getDescricaoNoticia()); - horaNoticia.setText(noticias.getHoraNoticia()); - assuntoNoticia.setText(noticias.getAssuntoNoticia()); - imagemNoticias.setImageDrawable(ContextCompat.getDrawable( - imagemNoticias.getContext(), noticias.getImagemNoticias())); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/adapters/RecyclerViewLerDepoisAdapter.java b/app/src/main/java/br/com/dhnews/adapters/RecyclerViewLerDepoisAdapter.java new file mode 100644 index 0000000..6de40bc --- /dev/null +++ b/app/src/main/java/br/com/dhnews/adapters/RecyclerViewLerDepoisAdapter.java @@ -0,0 +1,125 @@ +package br.com.dhnews.adapters; + +import android.app.Activity; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.app.ActivityOptionsCompat; +import androidx.recyclerview.widget.RecyclerView; + +import com.squareup.picasso.Picasso; + +import java.util.List; + +import br.com.dhnews.R; +import br.com.dhnews.interfaces.FavoriteItemClick; +import br.com.dhnews.interfaces.RecyclerViewClickListener; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.model.noticias.Noticias; +import br.com.dhnews.model.noticias.Source; +import br.com.dhnews.view.lerdepois.DetalheLerDepoisActivity; +import br.com.dhnews.view.noticias.DetalheNoticiaActivity; + +import static br.com.dhnews.util.AppUtil.formatarData; + +public class RecyclerViewLerDepoisAdapter extends RecyclerView.Adapter { + private List
listaNoticias; + + + public RecyclerViewLerDepoisAdapter(List
listaNoticias) { + this.listaNoticias = listaNoticias; + + } + + @NonNull + @Override + public RecyclerViewLerDepoisAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate + (R.layout.item_ler_depois, parent, false); + + return new ViewHolder(view); + + } + + @Override + public void onBindViewHolder(@NonNull RecyclerViewLerDepoisAdapter.ViewHolder viewHolder, int position) { + Article result = listaNoticias.get(position); + viewHolder.bind(result); + + viewHolder.itemView.setOnClickListener(v -> { + String transitionName = "image_" + position; + Intent intent = new Intent(viewHolder.itemView.getContext(), + DetalheLerDepoisActivity.class); + intent.putExtra("NOTICIAS", result); + intent.putExtra("transitionName", transitionName); + + viewHolder.imagemNoticias.setTransitionName(transitionName); + + ActivityOptionsCompat options = ActivityOptionsCompat. + makeSceneTransitionAnimation((Activity) viewHolder.itemView.getContext(), + viewHolder.imagemNoticias, transitionName); + + viewHolder.itemView.getContext().startActivity(intent, options.toBundle()); + }); + } + + @Override + public int getItemCount() { + return listaNoticias.size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + private TextView tituloNoticia; + private TextView descricaoNoticia; + private TextView horaNoticia; + private TextView categoriaNoticia; + private ImageView imagemNoticias; + private ImageView imagemBookMarkListaNoticia; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + tituloNoticia = itemView.findViewById(R.id.txtTitulo); + descricaoNoticia = itemView.findViewById(R.id.txtDescricao); + horaNoticia = itemView.findViewById(R.id.txtHora); + categoriaNoticia = itemView.findViewById(R.id.txtFonte); + imagemNoticias = itemView.findViewById(R.id.iconeNoticia); + imagemBookMarkListaNoticia = itemView.findViewById(R.id.imagemBookMarkListaNoticia); + } + + public void bind(Article result) { + + + // Source autor = result.getSource(); + // categoriaNoticia.setText(autor.getName()); + tituloNoticia.setText(result.getTitle()); + horaNoticia.setText(formatarData(result.getPublishedAt())); + descricaoNoticia.setText(result.getDescription()); + + if (result.getUrlToImage() != null) { + + Picasso.get().setIndicatorsEnabled(true); + Picasso.get() + .load(result.getUrlToImage()) + .error(R.mipmap.ic_launcher) + .placeholder(R.drawable.progress_animation) + .into(imagemNoticias); + } + } + } + + public void update(List
resultList) { + this.listaNoticias = resultList; + notifyDataSetChanged(); + + } + + public void clear() { + this.listaNoticias.clear(); + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/br/com/dhnews/adapters/RecyclerViewNoticiasAdapter.java b/app/src/main/java/br/com/dhnews/adapters/RecyclerViewNoticiasAdapter.java new file mode 100644 index 0000000..bb8b0b7 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/adapters/RecyclerViewNoticiasAdapter.java @@ -0,0 +1,136 @@ +package br.com.dhnews.adapters; + +import android.app.Activity; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.app.ActivityOptionsCompat; +import androidx.recyclerview.widget.RecyclerView; + +import com.squareup.picasso.Picasso; + +import java.util.List; + +import br.com.dhnews.R; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.model.noticias.Source; +import br.com.dhnews.view.noticias.DetalheNoticiaActivity; + +import static br.com.dhnews.util.AppUtil.formatarData; + + +public class RecyclerViewNoticiasAdapter extends RecyclerView.Adapter { + + private List
listaNoticias; + + + public RecyclerViewNoticiasAdapter(List
listaNoticias) { + this.listaNoticias = listaNoticias; + } + + @Override + public long getItemId(int position) { + return position; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { + View view = LayoutInflater.from(viewGroup.getContext()).inflate + (R.layout.layout_lista_item_noticias, viewGroup, false); + + return new ViewHolder(view); + } + + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) { + Article result = listaNoticias.get(position); + viewHolder.bind(result); + + viewHolder.itemView.setOnClickListener(v -> { + String transitionName = "image_" + position; + Intent intent = new Intent(viewHolder.itemView.getContext(), + DetalheNoticiaActivity.class); + intent.putExtra("NOTICIAS", result); + intent.putExtra("transitionName", transitionName); + + viewHolder.imagemNoticias.setTransitionName(transitionName); + + ActivityOptionsCompat options = ActivityOptionsCompat. + makeSceneTransitionAnimation((Activity) viewHolder.itemView.getContext(), + viewHolder.imagemNoticias, transitionName); + + viewHolder.itemView.getContext().startActivity(intent, options.toBundle()); + }); + + } + + @Override + public int getItemCount() { + return listaNoticias.size(); + } + { + } + + + class ViewHolder extends RecyclerView.ViewHolder { + + private TextView tituloNoticia; + private TextView descricaoNoticia; + private TextView horaNoticia; + private TextView categoriaNoticia; + private ImageView imagemNoticias; + private ImageView imagemBookMarkListaNoticia; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + tituloNoticia = itemView.findViewById(R.id.txtTitulo); + descricaoNoticia = itemView.findViewById(R.id.txtDescricao); + horaNoticia = itemView.findViewById(R.id.txtHora); + categoriaNoticia = itemView.findViewById(R.id.txtFonte); + imagemNoticias = itemView.findViewById(R.id.iconeNoticia); + imagemBookMarkListaNoticia = itemView.findViewById(R.id.imagemBookMarkListaNoticia); + } + + public void bind(Article result) { + + + Source autor = result.getSource(); + categoriaNoticia.setText(autor.getName()); + tituloNoticia.setText(result.getTitle()); + horaNoticia.setText(formatarData(result.getPublishedAt())); + descricaoNoticia.setText(result.getDescription()); + + if (result.getUrlToImage() != null) { + + Picasso.get().setIndicatorsEnabled(true); + Picasso.get() + .load(result.getUrlToImage()) + .error(R.mipmap.ic_launcher) + .placeholder(R.drawable.progress_animation) + .into(imagemNoticias); + } + } + } + public void update(List
resultList) { + for (Article item: resultList) { + if(!this.listaNoticias.contains(item)){ + this.listaNoticias.add(item); + } + } + + notifyDataSetChanged(); + + } + + public void clear(){ + this.listaNoticias.clear(); + notifyDataSetChanged(); + } + } diff --git a/app/src/main/java/br/com/dhnews/database/Converters.java b/app/src/main/java/br/com/dhnews/database/Converters.java new file mode 100644 index 0000000..d6bdb1b --- /dev/null +++ b/app/src/main/java/br/com/dhnews/database/Converters.java @@ -0,0 +1,38 @@ +package br.com.dhnews.database; + +import androidx.room.TypeConverter; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; + +import br.com.dhnews.model.noticias.Source; + +public class Converters { + @TypeConverter + public Source fromSource(String value) { + Type listType = (Type) new TypeToken() { + }.getType(); + return new Gson().fromJson(value, listType); + } + + @TypeConverter + public String fromSource(Source list) { + Gson gson = new Gson(); + return gson.toJson(list); + } + + @TypeConverter + public Object fromObject(String value) { + Type listType = (Type) new TypeToken() { + }.getType(); + return new Gson().fromJson(value, listType); + } + + @TypeConverter + public String fromObject(Object list) { + Gson gson = new Gson(); + return gson.toJson(list); + } +} diff --git a/app/src/main/java/br/com/dhnews/database/Database.java b/app/src/main/java/br/com/dhnews/database/Database.java new file mode 100644 index 0000000..b1de481 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/database/Database.java @@ -0,0 +1,32 @@ +package br.com.dhnews.database; + +import android.content.Context; + +import androidx.room.Room; +import androidx.room.RoomDatabase; +import androidx.room.TypeConverters; + +import br.com.dhnews.model.noticias.Article; + +@androidx.room.Database(entities = {Article.class}, version = 1, exportSchema = false) +@TypeConverters(Converters.class) // Adicionamos os conversores +public abstract class Database extends RoomDatabase { + + // Criamos o DAO que será retornado + public abstract NoticiasDAO resultsDAO(); + + private static volatile Database INSTANCE; + + public static Database getDatabase(final Context context) { + if (INSTANCE == null) { + synchronized (Database.class) { + if (INSTANCE == null) { + INSTANCE = Room.databaseBuilder(context.getApplicationContext(), + Database.class, "dhnews_db") + .build(); + } + } + } + return INSTANCE; + } +} diff --git a/app/src/main/java/br/com/dhnews/database/NoticiasDAO.java b/app/src/main/java/br/com/dhnews/database/NoticiasDAO.java new file mode 100644 index 0000000..8065ca5 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/database/NoticiasDAO.java @@ -0,0 +1,35 @@ +package br.com.dhnews.database; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; +import androidx.room.Update; + +import java.util.List; + +import br.com.dhnews.model.noticias.Article; +import io.reactivex.Flowable; + +@Dao +public interface NoticiasDAO { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(Article article); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(List
article); + + @Update + void update(Article article); + + @Delete + void delete(Article article); + + @Query("Delete from article") + void deleteAll(); + + @Query("Select * from article limit 30") + Flowable> getAll(); // Aqui retornamos um Flowable que é o observavel para o ROOM DATABASE +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/detalhenoticia/DetalheNoticiaActivity.java b/app/src/main/java/br/com/dhnews/detalhenoticia/DetalheNoticiaActivity.java deleted file mode 100644 index 790b714..0000000 --- a/app/src/main/java/br/com/dhnews/detalhenoticia/DetalheNoticiaActivity.java +++ /dev/null @@ -1,149 +0,0 @@ -package br.com.dhnews.detalhenoticia; - -import android.content.Intent; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import br.com.dhnews.model.Noticias; -import br.com.dhnews.view.MainActivy; -import br.com.dhnews.R; - -public class DetalheNoticiaActivity extends AppCompatActivity { - - //Declaracao de atributos - private TextView textViewTituloDetalheNoticia; - private TextView textViewSubTituloDetalheNoticia; - private TextView textViewHorarioDetalheNoticia; - private TextView textViewAssuntoDetalheNoticia; - private TextView textViewConteudoDetalheNoticia; - private ImageView imageViewBackDetalheNoticia; - private ImageView imageViewShareDetalheNoticia; - private ImageView imageViewBookMarkDetalheNoticia; - private ImageView imageViewFotoDetalheNoticia; - private Noticias noticias; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_detalhe_noticia); - - //Metodo para inicializar as Views - initViews(); - - //Valido se veio algum dado na intent - if (getIntent() != null && getIntent().getExtras() != null) { - Noticias noticias = getIntent().getParcelableExtra("NOTICIAS"); - - if (noticias != null) { - - retornaDetalheListaNoticias(noticias); - - //Metodo para voltar para a tela com a Lista de noticias - chamaListaNoticia(); - - //Metodo para acessar os aplicativos de compartilhamento de dados - compartilharNoticia(); - - - //Metodo para chamar a tela de LoginFragment para cadastrar da opcao ler noticia depois - cadastraLerDepois(); - } - } - } - - private void initViews() { - textViewTituloDetalheNoticia = findViewById(R.id.textViewTituloNoticiaDetalhe); - textViewSubTituloDetalheNoticia = findViewById(R.id.textViewSubTituloNoticiaDetalhe); - textViewHorarioDetalheNoticia = findViewById(R.id.textViewHorarioNoticiaDetalhe); - textViewAssuntoDetalheNoticia = findViewById(R.id.textViewAssuntoNoticiaDetalhe); - textViewConteudoDetalheNoticia = findViewById(R.id.textViewConteudoNoticiaDetalhe); - imageViewBackDetalheNoticia = findViewById(R.id.imagemBackNoticiaDetalhe); - imageViewShareDetalheNoticia = findViewById(R.id.imagemShareNoticiaDetalhe); - imageViewBookMarkDetalheNoticia = findViewById(R.id.imagemBookMarkNoticiaDetalhe); - imageViewFotoDetalheNoticia = findViewById(R.id.imagemNoticiaDetalhe); - } - - private void retornaDetalheListaNoticias(Noticias noticias) { - - textViewTituloDetalheNoticia.setText(noticias.getTituloNoticia()); - - textViewSubTituloDetalheNoticia.setText(noticias.getDescricaoNoticia()); - - textViewHorarioDetalheNoticia.setText(noticias.getHoraNoticia()); - - textViewAssuntoDetalheNoticia.setText(noticias.getAssuntoNoticia()); - - textViewConteudoDetalheNoticia.setText(noticias.getDescricaoNoticia()); - - imageViewFotoDetalheNoticia.setImageResource(noticias.getImagemNoticias()); - - } - - - private void chamaListaNoticia() { - imageViewBackDetalheNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - //Chama a tela com a Lista de Noticias - - //Chama a Main Activity que verifica qual opcao do Menu Principal foi acionado para - //chamar a tela/fragmento correspondente - Intent intentListaNoticias = new Intent( - DetalheNoticiaActivity.this, MainActivy.class); - - //Chama o fragmento da tela de Noticias(atraves de um flag 'Tela' com valor - //'Noticia') para retornar para a lista de noticias - intentListaNoticias.putExtra("TELA", "NOTICIA"); - - startActivity(intentListaNoticias); - } - }); - } - - private void compartilharNoticia() { - imageViewShareDetalheNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - //Acao de envio na intencao de chamar outra Actitivity - Intent intentCompartilhar = new Intent(Intent.ACTION_SEND); - - //Envia texto no compartilhamento - intentCompartilhar.putExtra(Intent.EXTRA_TEXT, "Compartilhando noticias"); - - //tipo de compartilhamento - intentCompartilhar.setType("text/plain"); - - //Mostra os aplicativos disponiveis para compartilhamento de dados - Intent intentChooser = Intent.createChooser( - intentCompartilhar, "Compartilhar via:"); - - //Start na Activity de compartilhamento - startActivity(intentChooser); - } - }); - } - - private void cadastraLerDepois() { - imageViewBookMarkDetalheNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - //Chama a Main Activity que verifica qual opcao do Menu Principal foi acionado para - //chamar a tela/fragmento correspondente - Intent intentLerDepois = new Intent( - DetalheNoticiaActivity.this, MainActivy.class); - - //Chama o fragmento da tela de LoginFragment(atraves de um flag 'Tela' com valor 'LoginFragment') - //para cadastrar o ler noticia depois - intentLerDepois.putExtra("TELA", "LOGIN"); - - startActivity(intentLerDepois); - } - }); - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/home/HomeFragment.java b/app/src/main/java/br/com/dhnews/home/HomeFragment.java deleted file mode 100644 index 1fe1d57..0000000 --- a/app/src/main/java/br/com/dhnews/home/HomeFragment.java +++ /dev/null @@ -1,106 +0,0 @@ -package br.com.dhnews.home; - - -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import java.util.ArrayList; -import java.util.List; - -import br.com.dhnews.interfaces.RecyclerViewClickListener; -import br.com.dhnews.R; -import br.com.dhnews.adapters.NoticiasAdapter; -import br.com.dhnews.detalhenoticia.DetalheNoticiaActivity; -import br.com.dhnews.model.Noticias; -import br.com.dhnews.model.Usuario; -import br.com.dhnews.view.MainActivy; - - -/** - * A simple {@link Fragment} subclass. - */ -public class HomeFragment extends Fragment implements RecyclerViewClickListener { - - public HomeFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.fragment_home, container, false); - - // Add findViewById para recycler - RecyclerView recyclerViewNoticias = view.findViewById(R.id.listaNoticiasRecyclerView); - - // Configurar recyclerview e adapater - NoticiasAdapter adapter = new NoticiasAdapter(getNoticias(), this); - - recyclerViewNoticias.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerViewNoticias.setAdapter(adapter); - - return view; - } - - private List getNoticias() { - - List noticias = new ArrayList<>(); - - noticias.add(new Noticias("Vaga no Supremo", - "Bolsonaro nega que tenha feito 'acordo' para indicar Moro ao STF.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias01)); - - noticias.add(new Noticias("Investigação no RJ", - "'Querem me atingir', diz Bolsonaro sobre quebra do sigilo de Flávio.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias02)); - - noticias.add(new Noticias("Educação", - "Presidente do Inep pede demissão após menos de 1 mês no cargo.", - "Há 2 horas — ", "Educação", R.drawable.imagenoticia03)); - - noticias.add(new Noticias("Economia", - "Dólar fecha a R$ 4,03 e bolsa atinge menor pontuação do ano.", - "Há 5 horas — ", "Economia", R.drawable.imagenoticia04)); - - noticias.add(new Noticias("Vaga no Supremo", - "Bolsonaro nega que tenha feito 'acordo' para indicar Moro ao STF.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias01)); - - noticias.add(new Noticias("Educação", - "Presidente do Inep pede demissão após menos de 1 mês no cargo.", - "Há 2 horas — ", "Educação", R.drawable.imagenoticia03)); - - return noticias; - } - - @Override - public void onClick(Noticias noticias) { - - Intent intent = new Intent(getContext(), DetalheNoticiaActivity.class); - - intent.putExtra("NOTICIAS", noticias); - - startActivity(intent); - - } - - @Override - public void onClick(Usuario usuario) { - - Intent intentLogin = new Intent(getContext(), MainActivy.class); - - intentLogin.putExtra("TELA", "LOGIN"); - - startActivity(intentLogin); - - } - -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/interfaces/FavoriteItemClick.java b/app/src/main/java/br/com/dhnews/interfaces/FavoriteItemClick.java new file mode 100644 index 0000000..867a253 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/interfaces/FavoriteItemClick.java @@ -0,0 +1,7 @@ +package br.com.dhnews.interfaces; + +import br.com.dhnews.model.noticias.Article; + +public interface FavoriteItemClick { + void removeFavoriteClickListener(Article result); +} diff --git a/app/src/main/java/br/com/dhnews/interfaces/RecyclerViewClickListener.java b/app/src/main/java/br/com/dhnews/interfaces/RecyclerViewClickListener.java index 25bde6b..c3e9af6 100644 --- a/app/src/main/java/br/com/dhnews/interfaces/RecyclerViewClickListener.java +++ b/app/src/main/java/br/com/dhnews/interfaces/RecyclerViewClickListener.java @@ -1,11 +1,11 @@ package br.com.dhnews.interfaces; -import br.com.dhnews.model.Noticias; +import br.com.dhnews.model.noticias.Article; import br.com.dhnews.model.Usuario; public interface RecyclerViewClickListener { - void onClick(Noticias noticias); + void onClick(Article article); void onClick(Usuario usuario); } \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/lerdepois/adapters/RecyclerViewLerDepoisAdapter.java b/app/src/main/java/br/com/dhnews/lerdepois/adapters/RecyclerViewLerDepoisAdapter.java deleted file mode 100644 index 4a2afe6..0000000 --- a/app/src/main/java/br/com/dhnews/lerdepois/adapters/RecyclerViewLerDepoisAdapter.java +++ /dev/null @@ -1,163 +0,0 @@ -package br.com.dhnews.lerdepois.adapters; - -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -import java.util.List; - -import br.com.dhnews.R; -import br.com.dhnews.interfaces.RecyclerViewClickListener; -import br.com.dhnews.lerdepois.views.LerDepoisFragment; -import br.com.dhnews.model.Noticias; - -public class RecyclerViewLerDepoisAdapter extends RecyclerView.Adapter< - RecyclerViewLerDepoisAdapter.ViewHolder> { - - private List listaNoticias; - private RecyclerViewClickListener listener; - - public ImageButton btnMarkButton; - - public RecyclerViewLerDepoisAdapter(List listaNoticias, - RecyclerViewClickListener listener) { - this.listaNoticias = listaNoticias; - this.listener = listener; - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { - - View itemView = LayoutInflater.from(viewGroup.getContext()).inflate( - R.layout.recyclerview_ler_depois_adapter, viewGroup, false); - - ViewHolder viewHolder = new ViewHolder(itemView); - - return viewHolder; - } - - @Override - public void onBindViewHolder(@NonNull RecyclerViewLerDepoisAdapter.ViewHolder viewHolder, final int position) { - - final Noticias noticias = listaNoticias.get(position); - viewHolder.setConteudoNaTela(noticias); - - /* - viewHolder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - listener.onClick(noticias); - - } - }); - */ - - //Click na imagem da noticia para chamar o detalhe da noticia - viewHolder.imagemNoticias.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onClick(noticias); - } - }); - - //Click no titulo da noticia para chamar o detalhe da noticia - viewHolder.tituloNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onClick(noticias); - } - }); - - //Click na descrição da noticia para chamar o detalhe da noticia - viewHolder.descricaoNoticia.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - listener.onClick(noticias); - } - }); - - viewHolder.markRemove.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - - //caixa de dialogo - AlertDialog.Builder alertDialog = new AlertDialog.Builder(v.getContext()); - alertDialog.setTitle("Remover Notícia?"); - alertDialog.setMessage(""); - alertDialog.setCancelable(false); - - alertDialog.setNegativeButton("MANTER", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - - } - }); - - alertDialog.setPositiveButton("REMOVER", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - //remove de fato a noticia da pposiçao selecionada - removeItem(position); - - } - }); - - AlertDialog alertDialog1 = alertDialog.create(); - alertDialog1.show(); - } - }); - } - - - @Override - public int getItemCount() { - return listaNoticias.size(); - } - - public void removeItem(int position) { - listaNoticias.remove(position); - notifyItemRemoved(position); - } - - public class ViewHolder extends RecyclerView.ViewHolder { - TextView tituloNoticia; - TextView descricaoNoticia; - TextView horaNoticia; - TextView assuntoNoticia; - ImageView imagemNoticias; - ImageButton markRemove; - - public ViewHolder(@NonNull View itemView) { - super(itemView); - - btnMarkButton = itemView.findViewById(R.id.btnBookMarkLerDepois); - imagemNoticias = itemView.findViewById(R.id.circleImageViewNoticia); - tituloNoticia = itemView.findViewById(R.id.tituloNoticia); - descricaoNoticia = itemView.findViewById(R.id.conteudoNoticia); - assuntoNoticia = itemView.findViewById(R.id.assuntoNoticia); - horaNoticia = itemView.findViewById(R.id.horarioNoticia); - markRemove = itemView.findViewById(R.id.btnBookMarkLerDepois); - - } - - public void setConteudoNaTela(Noticias noticias) { - - imagemNoticias.setImageDrawable(ContextCompat.getDrawable( - imagemNoticias.getContext(), noticias.getImagemNoticias())); - tituloNoticia.setText(noticias.getTituloNoticia()); - descricaoNoticia.setText(noticias.getDescricaoNoticia()); - assuntoNoticia.setText(noticias.getAssuntoNoticia()); - horaNoticia.setText(noticias.getHoraNoticia()); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/lerdepois/views/LerDepoisFragment.java b/app/src/main/java/br/com/dhnews/lerdepois/views/LerDepoisFragment.java deleted file mode 100644 index 0a467ab..0000000 --- a/app/src/main/java/br/com/dhnews/lerdepois/views/LerDepoisFragment.java +++ /dev/null @@ -1,105 +0,0 @@ -package br.com.dhnews.lerdepois.views; - - -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; - -import java.util.ArrayList; -import java.util.List; - -import br.com.dhnews.R; -import br.com.dhnews.interfaces.RecyclerViewClickListener; -import br.com.dhnews.lerdepois.adapters.RecyclerViewLerDepoisAdapter; -import br.com.dhnews.lerdepois.detalhe.DetalheLerDepoisActivity; -import br.com.dhnews.model.Noticias; -import br.com.dhnews.model.Usuario; - -/** - * A simple {@link Fragment} subclass. - */ -public class LerDepoisFragment extends Fragment implements RecyclerViewClickListener { - - private ImageButton btnRemoverNoticia; - RecyclerViewLerDepoisAdapter adapter; - - public LerDepoisFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.fragment_ler_depois, container, false); - - // Add findViewById para recycler - RecyclerView recyclerViewNoticias = view.findViewById(R.id.recyclerViewMark); - - // Configurar recyclerview e adapater - adapter = new RecyclerViewLerDepoisAdapter(getNoticias(), this); - - recyclerViewNoticias.setLayoutManager(new LinearLayoutManager(getContext())); - - recyclerViewNoticias.setAdapter(adapter); - - btnRemoverNoticia = view.findViewById(R.id.btnBookMarkLerDepois); - - return view; - } - - //Recebe lista - private List getNoticias() { - - List noticias = new ArrayList<>(); - - noticias.add(new Noticias("Vaga no Supremo", - "Bolsonaro nega que tenha feito 'acordo' para indicar Moro ao STF.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias01)); - - noticias.add(new Noticias("Investigação no RJ", - "'Querem me atingir', diz Bolsonaro sobre quebra do sigilo de Flávio.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias02)); - - noticias.add(new Noticias("Educação", - "Presidente do Inep pede demissão após menos de 1 mês no cargo.", - "Há 2 horas — ", "Educação", R.drawable.imagenoticia03)); - - noticias.add(new Noticias("Economia", - "Dólar fecha a R$ 4,03 e bolsa atinge menor pontuação do ano.", - "Há 5 horas — ", "Economia", R.drawable.imagenoticia04)); - - noticias.add(new Noticias("Vaga no Supremo", - "Bolsonaro nega que tenha feito 'acordo' para indicar Moro ao STF.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias01)); - - noticias.add(new Noticias("Educação", - "Presidente do Inep pede demissão após menos de 1 mês no cargo.", - "Há 2 horas — ", "Educação", R.drawable.imagenoticia03)); - - return noticias; - } - - @Override - public void onClick(Noticias noticias) { - - Intent intent = new Intent(getContext(), DetalheLerDepoisActivity.class); - - intent.putExtra("NOTICIAS", noticias); - - startActivity(intent); - - } - - @Override - public void onClick(Usuario usuario) { - - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/login/LoginFragment.java b/app/src/main/java/br/com/dhnews/login/LoginFragment.java deleted file mode 100644 index 2b5f841..0000000 --- a/app/src/main/java/br/com/dhnews/login/LoginFragment.java +++ /dev/null @@ -1,108 +0,0 @@ -package br.com.dhnews.login; - - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.design.widget.TextInputLayout; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; - -import br.com.dhnews.view.MainActivy; -import br.com.dhnews.noticias.NoticiasFragment; -import br.com.dhnews.R; -import br.com.dhnews.cadastro.CadastroFragment; -import br.com.dhnews.usuario.view.UsuarioActivity; - -import static android.content.Context.MODE_PRIVATE; - -/** - * A simple {@link Fragment} subclass. - */ -public class LoginFragment extends Fragment { - - public LoginFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_login, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - Button btnFacebook = view.findViewById(R.id.btnFacebook); - Button btnGoogle = view.findViewById(R.id.btnGoogle); - Button btnCadastra = view.findViewById(R.id.btnCadastrar); - Button btnLogin = view.findViewById(R.id.btnLogin); - - //Declaracao de atributos para validacao do preenchimento de dados da Tela de LoginFragment - final TextInputLayout textInputLayoutLogEmail = view.findViewById( - R.id.textInputLayoutEmail); - - final TextInputLayout textInputLayoutLogPassword = view.findViewById( - R.id.textInputLayoutPassword); - final SharedPreferences preferences = getContext().getSharedPreferences("APP", Context.MODE_PRIVATE); - textInputLayoutLogEmail.getEditText().setText(preferences.getString("EMAIL", "")); - textInputLayoutLogPassword.getEditText().setText(preferences.getString("SENHA", "")); - - - btnLogin.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - //Valida o prenchimento dos dados da Tela de LoginFragment - String emailLog = textInputLayoutLogEmail.getEditText().getText().toString(); - String senhaLog = textInputLayoutLogPassword.getEditText().getText().toString(); - - //Inicializa o set Error - textInputLayoutLogEmail.setError(""); - textInputLayoutLogPassword.setError(""); - - if (emailLog.isEmpty()) { - textInputLayoutLogEmail.setError("Informe seu e-mail"); - return; - } - - if (senhaLog.isEmpty()) { - textInputLayoutLogPassword.setError("Informe sua senha"); - return; - } - - if (!(emailLog.isEmpty()) && !(senhaLog.isEmpty())) { - - SharedPreferences preferences = getActivity().getPreferences(MODE_PRIVATE); - preferences.edit().putString("EMAIL", emailLog).commit(); - preferences.edit().putString("SENHA", senhaLog).commit(); - //se preenchido automaticamente, vai pra tela usuario - Intent intent = new Intent(getContext(), UsuarioActivity.class); - startActivity(intent); - - ((MainActivy) getActivity()).replaceFragment(new NoticiasFragment()); - - } - } - }); - - btnCadastra.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - ((MainActivy) getActivity()).replaceFragment(new CadastroFragment()); - } - }); - - - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/model/Noticias.java b/app/src/main/java/br/com/dhnews/model/Noticias.java deleted file mode 100644 index 7287e6e..0000000 --- a/app/src/main/java/br/com/dhnews/model/Noticias.java +++ /dev/null @@ -1,99 +0,0 @@ -package br.com.dhnews.model; - -import android.os.Parcel; -import android.os.Parcelable; - -public class Noticias implements Parcelable { - - private String tituloNoticia; - private String descricaoNoticia; - private String horaNoticia; - private String assuntoNoticia; - private int imagemNoticias; - - public Noticias() { - } - - public Noticias(String tituloNoticia, String descricaoNoticia, String horaNoticia, - String assuntoNoticia, int imagemNoticias) { - this.tituloNoticia = tituloNoticia; - this.descricaoNoticia = descricaoNoticia; - this.horaNoticia = horaNoticia; - this.assuntoNoticia = assuntoNoticia; - this.imagemNoticias = imagemNoticias; - } - - protected Noticias(Parcel in) { - tituloNoticia = in.readString(); - descricaoNoticia = in.readString(); - horaNoticia = in.readString(); - assuntoNoticia = in.readString(); - imagemNoticias = in.readInt(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Noticias createFromParcel(Parcel in) { - return new Noticias(in); - } - - @Override - public Noticias[] newArray(int size) { - return new Noticias[size]; - } - }; - - public String getTituloNoticia() { - return tituloNoticia; - } - - public void setTituloNoticia(String tituloNoticia) { - this.tituloNoticia = tituloNoticia; - } - - public String getDescricaoNoticia() { - return descricaoNoticia; - } - - public void setDescricaoNoticia(String descricaoNoticia) { - this.descricaoNoticia = descricaoNoticia; - } - - public String getHoraNoticia() { - return horaNoticia; - } - - public void setHoraNoticia(String horaNoticia) { - this.horaNoticia = horaNoticia; - } - - public String getAssuntoNoticia() { - return assuntoNoticia; - } - - public void setAssuntoNoticia(String assuntoNoticia) { - this.assuntoNoticia = assuntoNoticia; - } - - public int getImagemNoticias() { - return imagemNoticias; - } - - public void setImagemNoticias(int imagemNoticias) { - this.imagemNoticias = imagemNoticias; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(tituloNoticia); - dest.writeString(descricaoNoticia); - dest.writeString(horaNoticia); - dest.writeString(assuntoNoticia); - dest.writeInt(imagemNoticias); - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/model/noticias/Article.java b/app/src/main/java/br/com/dhnews/model/noticias/Article.java new file mode 100644 index 0000000..317a4e3 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/model/noticias/Article.java @@ -0,0 +1,145 @@ + +package br.com.dhnews.model.noticias; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +import com.google.gson.annotations.Expose; + +@Entity(tableName = "article") +public class Article implements Parcelable { + + @PrimaryKey(autoGenerate = true) + private long key; + + @Expose + private Object author; + @Expose + private String content; + @Expose + private String description; + @Expose + private String publishedAt; + @Expose + private Source source; + @Expose + private String title; + @Expose + private String url; + @Expose + private String urlToImage; + + public Article() { + } + + protected Article(Parcel in) { + content = in.readString(); + description = in.readString(); + publishedAt = in.readString(); + title = in.readString(); + url = in.readString(); + urlToImage = in.readString(); + } + + public static final Creator
CREATOR = new Creator
() { + @Override + public Article createFromParcel(Parcel in) { + return new Article(in); + } + + @Override + public Article[] newArray(int size) { + return new Article[size]; + } + }; + + public long getKey() { + return key; + } + + public void setKey(long key) { + this.key = key; + } + + public Object getAuthor() { + return author; + } + + public void setAuthor(Object author) { + this.author = author; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPublishedAt() { + return publishedAt; + } + + public void setPublishedAt(String publishedAt) { + this.publishedAt = publishedAt; + } + + public Source getSource() { + return source; + } + + public void setSource(Source source) { + this.source = source; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getUrlToImage() { + return urlToImage; + } + + public void setUrlToImage(String urlToImage) { + this.urlToImage = urlToImage; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(content); + dest.writeString(description); + dest.writeString(publishedAt); + dest.writeString(title); + dest.writeString(url); + dest.writeString(urlToImage); + } +} diff --git a/app/src/main/java/br/com/dhnews/model/noticias/Noticias.java b/app/src/main/java/br/com/dhnews/model/noticias/Noticias.java new file mode 100644 index 0000000..531da98 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/model/noticias/Noticias.java @@ -0,0 +1,43 @@ + +package br.com.dhnews.model.noticias; + +import androidx.room.Entity; + +import com.google.gson.annotations.Expose; + +import java.util.List; + +public class Noticias { + + @Expose + private List
articles; + @Expose + private String status; + @Expose + private Long totalResults; + + public List
getArticles() { + return articles; + } + + public void setArticles(List
articles) { + this.articles = articles; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Long getTotalResults() { + return totalResults; + } + + public void setTotalResults(Long totalResults) { + this.totalResults = totalResults; + } + +} diff --git a/app/src/main/java/br/com/dhnews/model/noticias/Source.java b/app/src/main/java/br/com/dhnews/model/noticias/Source.java new file mode 100644 index 0000000..6eda76a --- /dev/null +++ b/app/src/main/java/br/com/dhnews/model/noticias/Source.java @@ -0,0 +1,30 @@ + +package br.com.dhnews.model.noticias; + +import com.google.gson.annotations.Expose; + + +public class Source { + + @Expose + private Object id; + @Expose + private String name; + + public Object getId() { + return id; + } + + public void setId(Object id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/app/src/main/java/br/com/dhnews/network/API.java b/app/src/main/java/br/com/dhnews/network/API.java new file mode 100644 index 0000000..8d0bb94 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/network/API.java @@ -0,0 +1,29 @@ +package br.com.dhnews.network; + +import br.com.dhnews.model.noticias.Noticias; +import io.reactivex.Observable; +import io.reactivex.Single; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface API { + + @GET("top-headlines") + Single getNoticias(@Query("country") String country, + @Query("apikey") String apikey + // @Query("title") String title + ); + + @GET("everything") + Observable buscaNoticia(@Query("q") String item, + @Query("pageSize") int limite, + @Query("language") String country, + @Query("apikey") String apikey); + @GET("top-headlines") + Single getNoticias(@Query("category") String categoria, + @Query("pageSize") int limite, + @Query("language") String country, + @Query("apikey") String apikey); + + +} diff --git a/app/src/main/java/br/com/dhnews/network/ApiService.java b/app/src/main/java/br/com/dhnews/network/ApiService.java new file mode 100644 index 0000000..2951a45 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/network/ApiService.java @@ -0,0 +1,58 @@ +package br.com.dhnews.network; + + +import com.facebook.stetho.okhttp3.StethoInterceptor; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +public class ApiService { + + // Url da api + + private static final String BASE_URL = "https://newsapi.org/v2/"; + public static final String PUBLIC_KEY = "47bee8f305194e94973f8881bf183b87"; + + + // Instancia que criaremos do retrofit + private static Retrofit retrofit; + + private static Retrofit getRetrofit() { + + if (retrofit == null) { + + // configurações da conexão + OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); + httpClient.readTimeout(30, TimeUnit.SECONDS); + httpClient.connectTimeout(30, TimeUnit.SECONDS); + httpClient.writeTimeout(30, TimeUnit.SECONDS); + + + HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); + httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + httpClient.addInterceptor(httpLoggingInterceptor); + httpClient.addNetworkInterceptor(new StethoInterceptor()); + + // Inicializamos o retrofit + retrofit = new Retrofit.Builder() + .baseUrl(BASE_URL) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .client(httpClient.build()) + .build(); + } + + return retrofit; + } + + // Retornamos a instancia da API criada com o retrofit + public static API getApiService() { + return getRetrofit().create(API.class); + } + +} diff --git a/app/src/main/java/br/com/dhnews/noticias/NoticiasFragment.java b/app/src/main/java/br/com/dhnews/noticias/NoticiasFragment.java deleted file mode 100644 index 65ea88c..0000000 --- a/app/src/main/java/br/com/dhnews/noticias/NoticiasFragment.java +++ /dev/null @@ -1,104 +0,0 @@ -package br.com.dhnews.noticias; - - -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import java.util.ArrayList; -import java.util.List; - -import br.com.dhnews.interfaces.RecyclerViewClickListener; -import br.com.dhnews.R; -import br.com.dhnews.adapters.NoticiasAdapter; -import br.com.dhnews.detalhenoticia.DetalheNoticiaActivity; -import br.com.dhnews.model.Noticias; -import br.com.dhnews.model.Usuario; -import br.com.dhnews.view.MainActivy; - -/** - * A simple {@link Fragment} subclass. - */ -public class NoticiasFragment extends Fragment implements RecyclerViewClickListener { - - public NoticiasFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.fragment_noticias, container, false); - - // Add findViewById para recycler - RecyclerView recyclerViewNoticias = view.findViewById(R.id.listaNoticiasRecyclerView); - - // Configurar recyclerview e adapater - NoticiasAdapter adapter = new NoticiasAdapter(getNoticias(), this); - - recyclerViewNoticias.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerViewNoticias.setAdapter(adapter); - - return view; - } - - private List getNoticias() { - - List noticias = new ArrayList<>(); - - noticias.add(new Noticias("Vaga no Supremo", - "Bolsonaro nega que tenha feito 'acordo' para indicar Moro ao STF.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias01)); - - noticias.add(new Noticias("Investigação no RJ", - "'Querem me atingir', diz Bolsonaro sobre quebra do sigilo de Flávio.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias02)); - - noticias.add(new Noticias("Educação", - "Presidente do Inep pede demissão após menos de 1 mês no cargo.", - "Há 2 horas — ", "Educação", R.drawable.imagenoticia03)); - - noticias.add(new Noticias("Economia", - "Dólar fecha a R$ 4,03 e bolsa atinge menor pontuação do ano.", - "Há 5 horas — ", "Economia", R.drawable.imagenoticia04)); - - noticias.add(new Noticias("Vaga no Supremo", - "Bolsonaro nega que tenha feito 'acordo' para indicar Moro ao STF.", - "Há 2 horas — ", "Política", R.drawable.imagenoticias01)); - - noticias.add(new Noticias("Educação", - "Presidente do Inep pede demissão após menos de 1 mês no cargo.", - "Há 2 horas — ", "Educação", R.drawable.imagenoticia03)); - - return noticias; - } - - @Override - public void onClick(Noticias noticias) { - - Intent intent = new Intent(getContext(), DetalheNoticiaActivity.class); - - intent.putExtra("NOTICIAS", noticias); - - startActivity(intent); - - } - - @Override - public void onClick(Usuario usuario) { - - Intent intentLogin = new Intent(getContext(), MainActivy.class); - - intentLogin.putExtra("TELA", "LOGIN"); - - startActivity(intentLogin); - - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/pesquisa/PesquisaFragment.java b/app/src/main/java/br/com/dhnews/pesquisa/PesquisaFragment.java deleted file mode 100644 index 42b0a7d..0000000 --- a/app/src/main/java/br/com/dhnews/pesquisa/PesquisaFragment.java +++ /dev/null @@ -1,59 +0,0 @@ -package br.com.dhnews.pesquisa; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.support.v7.widget.SearchView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ListView; - -import br.com.dhnews.R; - -public class PesquisaFragment extends Fragment { - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - - return inflater.inflate(R.layout.fragment_pesquisa, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - SearchView searchView = view.findViewById(R.id.pesquisa); - ListView listView = view.findViewById(R.id.list); - - String[] arrayList = new String[]{"Esporte", "Politica", "Cinema", "Tecnologia"}; - final ArrayAdapter adapter; - - - adapter = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, arrayList); - - listView.setAdapter(adapter); - - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } - - @Override - public boolean onQueryTextChange(String newQuery) { - - adapter.getFilter().filter(newQuery); - - return false; - } - }); - - - } -} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/repository/NoticiasRepository.java b/app/src/main/java/br/com/dhnews/repository/NoticiasRepository.java new file mode 100644 index 0000000..603d843 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/repository/NoticiasRepository.java @@ -0,0 +1,46 @@ +package br.com.dhnews.repository; + +import android.content.Context; + +import java.util.List; + +import br.com.dhnews.database.Database; +import br.com.dhnews.database.NoticiasDAO; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.model.noticias.Noticias; +import br.com.dhnews.network.ApiService; +import io.reactivex.Flowable; +import io.reactivex.Observable; +import io.reactivex.Single; + +import static br.com.dhnews.network.ApiService.PUBLIC_KEY; + + +public class NoticiasRepository { + + // Pega os dados da base de dados + public Flowable> getLocalResults(Context context) { + Database room = Database.getDatabase(context); + NoticiasDAO resultsDao = room.resultsDAO(); + return resultsDao.getAll(); + } + + // Insere uma lista reults na base de dados + public void insertItems(Context context, List
items) { + Database room = Database.getDatabase(context); + NoticiasDAO resultsDao = room.resultsDAO(); + resultsDao.insert(items); + } + + public Single getNoticias() { + return ApiService.getApiService().getNoticias("BR", PUBLIC_KEY); + + } + + public Observable searchItems(String item, int limite) { + return ApiService.getApiService().buscaNoticia(item, 10,"pt", PUBLIC_KEY); + } + public Observable getNoticiasFavoritas(String categoria, int limite) { + return ApiService.getApiService().buscaNoticia(categoria, 2,"pt", PUBLIC_KEY); + } +} diff --git a/app/src/main/java/br/com/dhnews/util/AppUtil.java b/app/src/main/java/br/com/dhnews/util/AppUtil.java new file mode 100644 index 0000000..b153463 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/util/AppUtil.java @@ -0,0 +1,51 @@ +package br.com.dhnews.util; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.view.inputmethod.InputMethodManager; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import static androidx.core.content.ContextCompat.getSystemService; + +public class AppUtil { + + // Verifica se temos conexão com internet + public static boolean isNetworkConnected(Context context) { + ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo; + + if (connectivityManager != null) { + networkInfo = connectivityManager.getActiveNetworkInfo(); + return networkInfo != null && networkInfo.isConnected() && + (networkInfo.getType() == ConnectivityManager.TYPE_WIFI + || networkInfo.getType() == ConnectivityManager.TYPE_MOBILE); + } + return false; + } + //formata data de formato : yyyy-MM-dd'T'HH:mm:ss.SSSX + public static String formatarData(String data){ + String resultado = ""; + + try { + SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.getDefault()); + SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy", Locale.getDefault()); + Date date = formatDate.parse(data); + resultado = format.format(date); + + } catch (ParseException e) { + e.printStackTrace(); + } + + + return resultado; + } + + + + +} diff --git a/app/src/main/java/br/com/dhnews/view/MainActivy.java b/app/src/main/java/br/com/dhnews/view/MainActivity.java similarity index 67% rename from app/src/main/java/br/com/dhnews/view/MainActivy.java rename to app/src/main/java/br/com/dhnews/view/MainActivity.java index 5f4a600..28e0db0 100644 --- a/app/src/main/java/br/com/dhnews/view/MainActivy.java +++ b/app/src/main/java/br/com/dhnews/view/MainActivity.java @@ -1,22 +1,22 @@ package br.com.dhnews.view; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.design.widget.BottomNavigationView; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; -import android.support.v7.app.AppCompatActivity; +import androidx.annotation.NonNull; +import com.google.android.material.bottomnavigation.BottomNavigationView; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.appcompat.app.AppCompatActivity; import android.view.MenuItem; -import br.com.dhnews.login.LoginFragment; -import br.com.dhnews.noticias.NoticiasFragment; -import br.com.dhnews.pesquisa.PesquisaFragment; import br.com.dhnews.R; -import br.com.dhnews.home.HomeFragment; -import br.com.dhnews.lerdepois.views.LerDepoisFragment; +import br.com.dhnews.view.autenticacao.LoginFragment; +import br.com.dhnews.view.home.HomeFragment; +import br.com.dhnews.view.lerdepois.LerDepoisFragment; +import br.com.dhnews.view.noticias.NoticiasFragment; +import br.com.dhnews.view.pesquisa.PesquisaFragment; -public class MainActivy extends AppCompatActivity { +public class MainActivity extends AppCompatActivity { private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @@ -31,9 +31,11 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { return true; case R.id.navigation_user: replaceFragment(new LoginFragment()); + getSupportFragmentManager().isDestroyed(); return true; case R.id.navigation_home: replaceFragment(new HomeFragment()); + getSupportFragmentManager().isDestroyed(); return true; case R.id.navigation_public: replaceFragment(new NoticiasFragment()); @@ -50,7 +52,7 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_home_activy); + setContentView(R.layout.activity_home); BottomNavigationView navigation = findViewById(R.id.navigation); navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); @@ -60,13 +62,17 @@ protected void onCreate(Bundle savedInstanceState) { //Valida a flag e o fragmento que precisa ser exibido if (tela != null && tela.equals("LOGIN")) { + navigation.setSelectedItemId(R.id.navigation_user); replaceFragment(new LoginFragment()); } else if (tela != null && tela.equals("NOTICIA")) { + navigation.setSelectedItemId(R.id.navigation_public); replaceFragment(new NoticiasFragment()); } else if (tela != null && tela.equals("LERDEPOIS")) { + navigation.setSelectedItemId(R.id.navigation_mark); replaceFragment(new LerDepoisFragment()); } else { - replaceFragment(new HomeFragment()); + replaceFragment(new NoticiasFragment()); + navigation.setSelectedItemId(R.id.navigation_public); } } diff --git a/app/src/main/java/br/com/dhnews/cadastro/CadastroFragment.java b/app/src/main/java/br/com/dhnews/view/autenticacao/CadastroFragment.java similarity index 55% rename from app/src/main/java/br/com/dhnews/cadastro/CadastroFragment.java rename to app/src/main/java/br/com/dhnews/view/autenticacao/CadastroFragment.java index d628b84..1b3ad36 100644 --- a/app/src/main/java/br/com/dhnews/cadastro/CadastroFragment.java +++ b/app/src/main/java/br/com/dhnews/view/autenticacao/CadastroFragment.java @@ -1,26 +1,35 @@ -package br.com.dhnews.cadastro; +package br.com.dhnews.view.autenticacao; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.design.widget.TextInputLayout; -import android.support.v4.app.Fragment; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.textfield.TextInputLayout; +import androidx.fragment.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.auth.UserProfileChangeRequest; -import br.com.dhnews.view.MainActivy; import br.com.dhnews.R; -import br.com.dhnews.home.HomeFragment; +import br.com.dhnews.view.MainActivity; +import br.com.dhnews.view.noticias.NoticiasFragment; /** * A simple {@link Fragment} subclass. */ public class CadastroFragment extends Fragment { + private FirebaseAuth mAuth; public CadastroFragment() { // Required empty public constructor @@ -32,6 +41,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment + mAuth = FirebaseAuth.getInstance(); return inflater.inflate(R.layout.fragment_cadastro, container, false); } @@ -93,10 +103,35 @@ public void onClick(View v) { if (!(nomeCadastro.isEmpty()) && !(emailCadastro.isEmpty()) && !(senhaCadastro.isEmpty())) { - ((MainActivy) getActivity()).replaceFragment(new HomeFragment()); + mAuth.createUserWithEmailAndPassword(emailCadastro, senhaCadastro) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); + UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder() + .setDisplayName(nomeCadastro) + .build(); + user.updateProfile(profileUpdates) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + ((MainActivity) getActivity()).replaceFragment(new NoticiasFragment()); + } + } + }); + } else { + Toast.makeText(((MainActivity) getActivity()).getApplicationContext(), + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); + } + } + }); + } } }); } + } \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/view/autenticacao/LoginActivity.java b/app/src/main/java/br/com/dhnews/view/autenticacao/LoginActivity.java new file mode 100644 index 0000000..5825fe5 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/autenticacao/LoginActivity.java @@ -0,0 +1,97 @@ +package br.com.dhnews.view.autenticacao; + +import androidx.appcompat.app.AppCompatActivity; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import com.google.android.gms.auth.api.signin.GoogleSignIn; +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; +import com.google.android.gms.auth.api.signin.GoogleSignInClient; +import com.google.android.gms.auth.api.signin.GoogleSignInOptions; +import com.google.android.gms.common.SignInButton; +import com.google.android.gms.common.api.ApiException; +import com.google.android.gms.tasks.Task; + +import br.com.dhnews.R; + +public class LoginActivity extends AppCompatActivity { + + private static final String TAG = "AndroidClarified"; + private SignInButton googleSignInButton; + private GoogleSignInClient googleSignInClient; + + @SuppressLint("WrongViewCast") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + + onStart(); + + + googleSignInButton = findViewById(R.id.btnLoginGoogle); + GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) + .requestEmail() + .build(); + + googleSignInClient = GoogleSignIn.getClient(this, gso); + googleSignInButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent signInIntent = googleSignInClient.getSignInIntent(); + startActivityForResult(signInIntent, 101); + } + }); + + + } + + @Override + public void onStart() { + super.onStart(); + GoogleSignInAccount alreadyloggedAccount = GoogleSignIn.getLastSignedInAccount(this); + if (alreadyloggedAccount != null) { + Toast.makeText(this, "Você já está logado", Toast.LENGTH_SHORT).show(); + onLoggedIn(alreadyloggedAccount); + } else { + Log.d(TAG, "Not logged in"); + } + } + + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK) + switch (requestCode) { + case 101: + try { + // The Task returned from this call is always completed, no need to attach + // a listener. + Task task = GoogleSignIn.getSignedInAccountFromIntent(data); + GoogleSignInAccount account = task.getResult(ApiException.class); + onLoggedIn(account); + } catch (ApiException e) { + // The ApiException status code indicates the detailed failure reason. + Toast.makeText(getApplicationContext(),"Deu merda", Toast.LENGTH_SHORT).show(); + + } + break; + } + } + + private void onLoggedIn(GoogleSignInAccount googleSignInAccount) { + Intent intent = new Intent(this, UsuarioFragment.class); + // intent.putExtra(UsuarioFragment.GOOGLE_ACCOUNT, googleSignInAccount); + + startActivity(intent); + finish(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/view/autenticacao/LoginFragment.java b/app/src/main/java/br/com/dhnews/view/autenticacao/LoginFragment.java new file mode 100644 index 0000000..0119c15 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/autenticacao/LoginFragment.java @@ -0,0 +1,189 @@ +package br.com.dhnews.view.autenticacao; + + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.gms.auth.api.Auth; +import com.google.android.gms.auth.api.signin.GoogleSignIn; +import com.google.android.gms.auth.api.signin.GoogleSignInAccount; +import com.google.android.gms.auth.api.signin.GoogleSignInClient; +import com.google.android.gms.auth.api.signin.GoogleSignInOptions; +import com.google.android.gms.auth.api.signin.GoogleSignInResult; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.android.material.textfield.TextInputLayout; +import com.google.firebase.auth.AuthCredential; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.auth.GoogleAuthProvider; + +import androidx.fragment.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.Toast; + +import br.com.dhnews.R; +import br.com.dhnews.view.MainActivity; + +import static android.content.Context.MODE_PRIVATE; + +/** + * A simple {@link Fragment} subclass. + */ +public class LoginFragment extends Fragment { + private FirebaseAuth mAuth; + GoogleSignInClient mGoogleApiClient; + private static final int RC_SIGN_IN = 9001; + public LoginFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + mAuth = FirebaseAuth.getInstance(); + if(verificaUserLogado()){ + ((MainActivity) getActivity()).replaceFragment(new UsuarioFragment()); + } + GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) + .requestIdToken(getString(R.string.default_web_client_id)) + .requestEmail() + .build(); + + mGoogleApiClient = GoogleSignIn.getClient(getActivity(), gso); + mAuth = FirebaseAuth.getInstance(); + + return inflater.inflate(R.layout.fragment_login, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Button btnGoogle = view.findViewById(R.id.btnGoogle); + Button btnCadastra = view.findViewById(R.id.btnCadastrar); + Button btnLogin = view.findViewById(R.id.btnLogin); + + //Declaracao de atributos para validacao do preenchimento de dados da Tela de LoginFragment + final TextInputLayout textInputLayoutLogEmail = view.findViewById( + R.id.textInputLayoutEmail); + + final TextInputLayout textInputLayoutLogPassword = view.findViewById( + R.id.textInputLayoutPassword); + final SharedPreferences preferences = getContext().getSharedPreferences("APP", Context.MODE_PRIVATE); + textInputLayoutLogEmail.getEditText().setText(preferences.getString("EMAIL", "")); + textInputLayoutLogPassword.getEditText().setText(preferences.getString("SENHA", "")); + + + btnLogin.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + //Valida o prenchimento dos dados da Tela de LoginFragment + String emailLog = textInputLayoutLogEmail.getEditText().getText().toString(); + String senhaLog = textInputLayoutLogPassword.getEditText().getText().toString(); + + //Inicializa o set Error + textInputLayoutLogEmail.setError(""); + textInputLayoutLogPassword.setError(""); + + if (emailLog.isEmpty()) { + textInputLayoutLogEmail.setError("Informe seu e-mail"); + return; + } + + if (senhaLog.isEmpty()) { + textInputLayoutLogPassword.setError("Informe sua senha"); + return; + } + + if (!(emailLog.isEmpty()) && !(senhaLog.isEmpty())) { + + SharedPreferences preferences = getActivity().getPreferences(MODE_PRIVATE); + preferences.edit().putString("EMAIL", emailLog).commit(); + preferences.edit().putString("SENHA", senhaLog).commit(); + //se preenchido automaticamente, vai pra tela usuario +// Intent intent = new Intent(getContext(), UsuarioActivity.class); +// startActivity(intent); + mAuth.signInWithEmailAndPassword(emailLog, senhaLog) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + ((MainActivity) getActivity()).replaceFragment(new UsuarioFragment()); + + } else { + Toast.makeText( ((MainActivity) getActivity()).getApplicationContext(), + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); + } + } + }); + + + } + } + }); + + btnCadastra.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + ((MainActivity) getActivity()).replaceFragment(new CadastroFragment()); + } + }); + + btnGoogle.setOnClickListener(v->signIn()); + + + } + + private boolean verificaUserLogado(){ + FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); + + return user != null; + } + private void signIn() { +// Intent signInIntent = mGoogleApiClient.getSignInIntent(); +// (signInIntent, RC_SIGN_IN); + } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode==RC_SIGN_IN){ + GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); + if(result.isSuccess()){ + GoogleSignInAccount account = result.getSignInAccount(); + authWithGoogle(account); + } + } + } + private void authWithGoogle(GoogleSignInAccount account) { + AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(),null); + mAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(task.isSuccessful()){ + ((MainActivity) getActivity()).replaceFragment(new UsuarioFragment()); + } + else{ + Toast.makeText(getContext(),"Auth Error",Toast.LENGTH_SHORT).show(); + } + } + }); + } + + + public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { + Toast.makeText(getContext(),"Falha na conexão",Toast.LENGTH_SHORT).show(); + } +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/usuario/view/UsuarioActivity.java b/app/src/main/java/br/com/dhnews/view/autenticacao/UsuarioActivity.java similarity index 90% rename from app/src/main/java/br/com/dhnews/usuario/view/UsuarioActivity.java rename to app/src/main/java/br/com/dhnews/view/autenticacao/UsuarioActivity.java index c9aa5a3..03466d6 100644 --- a/app/src/main/java/br/com/dhnews/usuario/view/UsuarioActivity.java +++ b/app/src/main/java/br/com/dhnews/view/autenticacao/UsuarioActivity.java @@ -1,18 +1,18 @@ -package br.com.dhnews.usuario.view; +package br.com.dhnews.view.autenticacao; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; -import br.com.dhnews.view.MainActivy; import br.com.dhnews.R; +import br.com.dhnews.view.MainActivity; public class UsuarioActivity extends AppCompatActivity { @@ -53,7 +53,7 @@ public void onClick(View v) { public void initViews() { circleImage = findViewById(R.id.circleImageView); checkCulinaria = findViewById(R.id.checkCulinaria); - btnDesconectarConta = findViewById(R.id.btnDesconectarConta); + btnDesconectarConta = findViewById(R.id.textViewDesconectarConta); btnBackUser = findViewById(R.id.imagemBackUser); } @@ -75,7 +75,7 @@ public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) { //Ao clicar em Desconectar, vai para Home(main activity) - Intent intent = new Intent(UsuarioActivity.this, MainActivy.class); + Intent intent = new Intent(UsuarioActivity.this, MainActivity.class); startActivity(intent); } @@ -85,7 +85,7 @@ public void onClick(DialogInterface dialog, int which) { } public void botaoVoltar() { - Intent intent = new Intent(UsuarioActivity.this, MainActivy.class); + Intent intent = new Intent(UsuarioActivity.this, MainActivity.class); startActivity(intent); } diff --git a/app/src/main/java/br/com/dhnews/view/autenticacao/UsuarioFragment.java b/app/src/main/java/br/com/dhnews/view/autenticacao/UsuarioFragment.java new file mode 100644 index 0000000..95d50dc --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/autenticacao/UsuarioFragment.java @@ -0,0 +1,155 @@ +package br.com.dhnews.view.autenticacao; + + +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.fragment.app.Fragment; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import br.com.dhnews.R; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.view.MainActivity; +import de.hdodenhof.circleimageview.CircleImageView; + +/** + * A simple {@link Fragment} subclass. + */ +public class UsuarioFragment extends Fragment { + CircleImageView circleImageViewUser; + TextView nomeCompletoText; + TextView btnLogout; + Button btnInteresse; + CheckBox checkCiencia; + CheckBox checkTec; + CheckBox checkEsporte; + CheckBox checkEntre; + CheckBox checkSaude; + CheckBox checkNegocios; + private DatabaseReference mDatabase; + + + private FirebaseAuth mAuth; + + public UsuarioFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + mAuth = FirebaseAuth.getInstance(); + + View view = inflater.inflate(R.layout.fragment_usuario, container, false); + + circleImageViewUser = view.findViewById(R.id.circleImageViewUser); + nomeCompletoText = view.findViewById(R.id.nomeCompletoText); + btnLogout = view.findViewById(R.id.btnDesconectarConta); + btnInteresse = view.findViewById(R.id.btnInteresse); + checkCiencia = view.findViewById(R.id.checkCiencia); + checkTec = view.findViewById(R.id.checkTec); + checkEsporte = view.findViewById(R.id.checkEsporte); + checkEntre = view.findViewById(R.id.checkEntre); + checkSaude = view.findViewById(R.id.checkSaude); + checkNegocios = view.findViewById(R.id.checkNegocios); + mAuth = FirebaseAuth.getInstance(); + + + + FirebaseUser user = mAuth.getCurrentUser(); + + if (user != null) { + nomeCompletoText.setText(user.getDisplayName()); + mDatabase = FirebaseDatabase.getInstance().getReference().child("noticias").child(user.getUid()).child("favoritos"); + ValueEventListener articletListener = new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + // Get Post object and use the values to update the UI + List
noticias = new ArrayList<>(); + for(DataSnapshot templateSnapshot : dataSnapshot.getChildren()) { + + // I've tried a million different things here, but all result in the error + // This is the error line + String item = templateSnapshot.getValue(String.class); + if(item.equals("science")) + checkCiencia.setChecked(true); + if(item.equals("technology")) + checkTec.setChecked(true); + if(item.equals("sports")) + checkEsporte.setChecked(true); + if(item.equals("entertainment")) + checkEntre.setChecked(true); + if(item.equals("health")) + checkSaude.setChecked(true); + if(item.equals("business")) + checkNegocios.setChecked(true); + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + // Getting Post failed, log a message + Log.w("ERRO", "loadPost:onCancelled", databaseError.toException()); + // ... + } + }; + mDatabase.addValueEventListener(articletListener); + + + } + + btnLogout.setOnClickListener(v -> { + mAuth.signOut(); + ((MainActivity) getActivity()).replaceFragment(new LoginFragment()); + }); + btnInteresse.setOnClickListener(v -> cadastraInteresses()); + return view; + } + + private void cadastraInteresses() { + FirebaseUser user = mAuth.getCurrentUser(); + List favoritos = new ArrayList<>(); + if(checkCiencia.isChecked()) + favoritos.add("science"); + if(checkTec.isChecked()) + favoritos.add("technology"); + if(checkEsporte.isChecked()) + favoritos.add("sports"); + if(checkEntre.isChecked()) + favoritos.add("entertainment"); + if(checkSaude.isChecked()) + favoritos.add("health"); + if(checkNegocios.isChecked()) + favoritos.add("business"); + + DatabaseReference mfavoritos = FirebaseDatabase.getInstance().getReference() + .child("noticias") + .child(user.getUid()) + .child("favoritos"); + mfavoritos.setValue(favoritos); + Toast.makeText(getContext(), "Adicionado com sucesso!", Toast.LENGTH_SHORT).show(); + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/view/home/HomeFragment.java b/app/src/main/java/br/com/dhnews/view/home/HomeFragment.java new file mode 100644 index 0000000..af1a361 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/home/HomeFragment.java @@ -0,0 +1,146 @@ +package br.com.dhnews.view.home; + + +import android.content.Intent; +import android.os.Bundle; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; +import java.util.List; + +import br.com.dhnews.adapters.RecyclerViewLerDepoisAdapter; +import br.com.dhnews.interfaces.RecyclerViewClickListener; +import br.com.dhnews.R; +import br.com.dhnews.adapters.RecyclerViewNoticiasAdapter; +import br.com.dhnews.model.Usuario; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.view.MainActivity; +import br.com.dhnews.view.autenticacao.LoginFragment; +import br.com.dhnews.view.noticias.DetalheNoticiaActivity; +import br.com.dhnews.viewmodel.NoticiasViewModel; + +import static br.com.dhnews.util.AppUtil.isNetworkConnected; + + +/** + * A simple {@link Fragment} subclass. + */ +public class HomeFragment extends Fragment implements RecyclerViewClickListener { + private List
noticiasList = new ArrayList<>(); + RecyclerViewNoticiasAdapter adapter; + private NoticiasViewModel viewModel; + private FirebaseAuth mAuth; + private DatabaseReference mDatabase; + private List favoritos; + public HomeFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_home, container, false); + + // Add findViewById para recycler + RecyclerView recyclerViewNoticias = view.findViewById(R.id.listaNoticiasRecyclerView); + + // Configurar recyclerview e adapater + + adapter = new RecyclerViewNoticiasAdapter(noticiasList); + + recyclerViewNoticias.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerViewNoticias.setAdapter(adapter); + + viewModel = ViewModelProviders.of(this).get(NoticiasViewModel.class); + + + mAuth = FirebaseAuth.getInstance(); + FirebaseUser user = mAuth.getCurrentUser(); + if(user == null ){ + ((MainActivity) getActivity()).replaceFragment(new LoginFragment()); + Toast.makeText(((MainActivity) getActivity()).getApplicationContext(), "Faça login ou se cadastre para ter acesso ao recurso!", Toast.LENGTH_LONG).show(); + return view; + + } + + + mDatabase = FirebaseDatabase.getInstance().getReference().child("noticias").child(user.getUid()).child("favoritos"); + ValueEventListener articletListener = new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + // Get Post object and use the values to update the UI + List
noticias = new ArrayList<>(); + for(DataSnapshot templateSnapshot : dataSnapshot.getChildren()) { + + // I've tried a million different things here, but all result in the error + // This is the error line + String item = templateSnapshot.getValue(String.class); + + viewModel.getNoticiasFavoritas(item, 2); + viewModel.getResults().observe(getViewLifecycleOwner(), results -> + adapter.update(results)); + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + // Getting Post failed, log a message + Log.w("ERRO", "loadPost:onCancelled", databaseError.toException()); + // ... + } + }; + mDatabase.addValueEventListener(articletListener); + + return view; + } + + + + + @Override + public void onClick(Article article) { + + Intent intent = new Intent(getContext(), DetalheNoticiaActivity.class); + + intent.putExtra("NOTICIAS", article); + + startActivity(intent); + + } + + @Override + public void onClick(Usuario usuario) { + + Intent intentLogin = new Intent(getContext(), MainActivity.class); + + intentLogin.putExtra("TELA", "LOGIN"); + + startActivity(intentLogin); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + } +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/lerdepois/detalhe/DetalheLerDepoisActivity.java b/app/src/main/java/br/com/dhnews/view/lerdepois/DetalheLerDepoisActivity.java similarity index 77% rename from app/src/main/java/br/com/dhnews/lerdepois/detalhe/DetalheLerDepoisActivity.java rename to app/src/main/java/br/com/dhnews/view/lerdepois/DetalheLerDepoisActivity.java index 75cffa9..50174d3 100644 --- a/app/src/main/java/br/com/dhnews/lerdepois/detalhe/DetalheLerDepoisActivity.java +++ b/app/src/main/java/br/com/dhnews/view/lerdepois/DetalheLerDepoisActivity.java @@ -1,23 +1,26 @@ -package br.com.dhnews.lerdepois.detalhe; +package br.com.dhnews.view.lerdepois; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import com.squareup.picasso.Picasso; + import br.com.dhnews.R; -import br.com.dhnews.model.Noticias; -import br.com.dhnews.view.MainActivy; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.view.MainActivity; + +import static br.com.dhnews.util.AppUtil.formatarData; public class DetalheLerDepoisActivity extends AppCompatActivity { //Declaracao de atributos private TextView textViewTituloDetalheLerDepois; - private TextView textViewSubTituloDetalheLerDepois; private TextView textViewHorarioDetalheLerDepois; private TextView textViewAssuntoDetalheLerDepois; private TextView textViewConteudoDetalheLerDepois; @@ -25,7 +28,7 @@ public class DetalheLerDepoisActivity extends AppCompatActivity { private ImageView imageViewShareDetalheLerDepois; private ImageView imageViewBookMarkDetalheLerDepois; private ImageView imageViewFotoDetalheLerDepois; - private Noticias noticias; + private Article article; @Override protected void onCreate(Bundle savedInstanceState) { @@ -37,51 +40,56 @@ protected void onCreate(Bundle savedInstanceState) { //Valido se veio algum dado na intent if (getIntent() != null && getIntent().getExtras() != null) { - Noticias noticias = getIntent().getParcelableExtra("NOTICIAS"); + Article article = getIntent().getParcelableExtra("NOTICIAS"); - if (noticias != null) { + if (article != null) { //Retorna o detalhe da noticia que foi selecionada para Ler depois - retornaDetalheListaLerDepois(noticias); + retornaDetalheListaLerDepois(article); - //Metodo para voltar para a tela com a Lista de noticias que será lida depois + //Metodo para voltar para a tela com a Lista de article que será lida depois chamaListaNoticiaLerDepois(); - //Metodo para acessar os aplicativos de compartilhamento de dados das noticias + //Metodo para acessar os aplicativos de compartilhamento de dados das article //que podem ser lidas depois compartilharNoticiaLerDepois(); //Metodo para desmarcar a opção ler depois da noticia - desmarcaLerDepois(); + imageViewBookMarkDetalheLerDepois.setOnClickListener(v-> desmarcaLerDepois()); + } } } private void initViews() { textViewTituloDetalheLerDepois = findViewById(R.id.textViewTituloDetalheLerDepois); - textViewSubTituloDetalheLerDepois = findViewById(R.id.textViewSubTituloDetalheLerDepois); textViewHorarioDetalheLerDepois = findViewById(R.id.textViewHorarioDetalheLerDepois); textViewAssuntoDetalheLerDepois = findViewById(R.id.textViewAssuntoDetalheLerDepois); - textViewConteudoDetalheLerDepois = findViewById(R.id.textViewConteudoDetalheLerDepois); + textViewConteudoDetalheLerDepois = findViewById(R.id.textViewConteudoNoticiaDetalhe); imageViewBackDetalheLerDepois = findViewById(R.id.imagemBackDetalheLerDepois); imageViewShareDetalheLerDepois = findViewById(R.id.imagemShareDetalheLerDepois); imageViewBookMarkDetalheLerDepois = findViewById(R.id.imagemBookMarkDetalheLerDepois); imageViewFotoDetalheLerDepois = findViewById(R.id.imagemDetalheLerDepois); } - private void retornaDetalheListaLerDepois(Noticias noticias) { + private void retornaDetalheListaLerDepois(Article article) { - textViewTituloDetalheLerDepois.setText(noticias.getTituloNoticia()); + textViewTituloDetalheLerDepois.setText(article.getTitle()); - textViewSubTituloDetalheLerDepois.setText(noticias.getDescricaoNoticia()); - textViewHorarioDetalheLerDepois.setText(noticias.getHoraNoticia()); + textViewHorarioDetalheLerDepois.setText(formatarData(article.getPublishedAt())); - textViewAssuntoDetalheLerDepois.setText(noticias.getAssuntoNoticia()); + textViewConteudoDetalheLerDepois.setText(article.getContent()); - textViewConteudoDetalheLerDepois.setText(noticias.getDescricaoNoticia()); + if (article.getUrlToImage() != null) { - imageViewFotoDetalheLerDepois.setImageResource(noticias.getImagemNoticias()); + Picasso.get().setIndicatorsEnabled(true); + Picasso.get() + .load(article.getUrlToImage()) + .error(R.mipmap.ic_launcher) + .placeholder(R.mipmap.ic_launcher) + .into(imageViewFotoDetalheLerDepois); + } } @@ -91,15 +99,15 @@ private void chamaListaNoticiaLerDepois() { @Override public void onClick(View v) { - //Chama a tela com a Lista de Noticias ler depois + //Chama a tela com a Lista de Article ler depois //Chama a Main Activity que verifica qual opcao do Menu Principal foi acionado para //chamar a tela/fragmento correspondente Intent intentListaLerDepois = new Intent( - DetalheLerDepoisActivity.this, MainActivy.class); + DetalheLerDepoisActivity.this, MainActivity.class); - //Chama o fragmento da tela de Noticias Ler depois(atraves de um flag 'Tela' - // com valor 'LERDEPOIS') para retornar para a lista de noticias ler depois + //Chama o fragmento da tela de Article Ler depois(atraves de um flag 'Tela' + // com valor 'LERDEPOIS') para retornar para a lista de article ler depois intentListaLerDepois.putExtra("TELA", "LERDEPOIS"); startActivity(intentListaLerDepois); @@ -117,7 +125,7 @@ public void onClick(View v) { //Envia texto no compartilhamento intentCompartilhar.putExtra( - Intent.EXTRA_TEXT, "Compartilhando noticias ler depois"); + Intent.EXTRA_TEXT, "Compartilhando article ler depois"); //tipo de compartilhamento intentCompartilhar.setType("text/plain"); @@ -159,8 +167,8 @@ public void onClick(DialogInterface dialog, int which) { Intent intentLerDepois = new Intent( DetalheLerDepoisActivity.this, DetalheNoticiaActivity.class); - //Envia flag para retornar para a lista de noticias sem ler depois - intentLerDepois.putExtra("NOTICIAS", noticias); + //Envia flag para retornar para a lista de article sem ler depois + intentLerDepois.putExtra("NOTICIAS", article); startActivity(intentLerDepois); */ @@ -168,14 +176,15 @@ public void onClick(DialogInterface dialog, int which) { //************************************************************************** //Ajuste temporário até a inclusão do banco de dados para validação de dados //************************************************************************** - //Chama a tela com a Lista de Noticias + //Chama a tela com a Lista de Article //Chama a Main Activity que verifica qual opcao do Menu Principal foi // acionado para chamar a tela/fragmento correspondente + Intent intentListaNoticias = new Intent( - DetalheLerDepoisActivity.this, MainActivy.class); + DetalheLerDepoisActivity.this, MainActivity.class); - //Chama o fragmento da tela de Noticias(atraves de um flag 'Tela' com valor - //'Noticia') para retornar para a lista de noticias + //Chama o fragmento da tela de Article(atraves de um flag 'Tela' com valor + //'Noticia') para retornar para a lista de article intentListaNoticias.putExtra("TELA", "NOTICIA"); startActivity(intentListaNoticias); diff --git a/app/src/main/java/br/com/dhnews/lerdepois/views/LerDepoisActivity.java b/app/src/main/java/br/com/dhnews/view/lerdepois/LerDepoisActivity.java similarity index 73% rename from app/src/main/java/br/com/dhnews/lerdepois/views/LerDepoisActivity.java rename to app/src/main/java/br/com/dhnews/view/lerdepois/LerDepoisActivity.java index aad054f..aefbb31 100644 --- a/app/src/main/java/br/com/dhnews/lerdepois/views/LerDepoisActivity.java +++ b/app/src/main/java/br/com/dhnews/view/lerdepois/LerDepoisActivity.java @@ -1,8 +1,8 @@ -package br.com.dhnews.lerdepois.views; +package br.com.dhnews.view.lerdepois; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.appcompat.app.AppCompatActivity; import br.com.dhnews.R; @@ -11,7 +11,7 @@ public class LerDepoisActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_ler_depois); + setContentView(R.layout.fragment_ler_depois); replaceFragment(new LerDepoisFragment()); diff --git a/app/src/main/java/br/com/dhnews/view/lerdepois/LerDepoisFragment.java b/app/src/main/java/br/com/dhnews/view/lerdepois/LerDepoisFragment.java new file mode 100644 index 0000000..634e166 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/lerdepois/LerDepoisFragment.java @@ -0,0 +1,132 @@ +package br.com.dhnews.view.lerdepois; + + +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.Toast; + +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; +import java.util.List; + +import br.com.dhnews.R; +import br.com.dhnews.adapters.RecyclerViewLerDepoisAdapter; +import br.com.dhnews.interfaces.RecyclerViewClickListener; +import br.com.dhnews.model.Usuario; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.view.MainActivity; +import br.com.dhnews.view.autenticacao.LoginFragment; +import br.com.dhnews.view.autenticacao.UsuarioFragment; +import br.com.dhnews.view.noticias.DetalheNoticiaActivity; + +/** + * A simple {@link Fragment} subclass. + */ +public class LerDepoisFragment extends Fragment implements RecyclerViewClickListener { + + private ImageButton btnRemoverNoticia; + RecyclerViewLerDepoisAdapter adapter; + private DatabaseReference mDatabase; + private FirebaseAuth mAuth; + + public LerDepoisFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_ler_depois, container, false); + + // Add findViewById para recycler + RecyclerView recyclerViewNoticias = view.findViewById(R.id.recyclerViewMark); + + // Configurar recyclerview e adapater + + + recyclerViewNoticias.setLayoutManager(new LinearLayoutManager(getContext())); + mAuth = FirebaseAuth.getInstance(); + FirebaseUser user = mAuth.getCurrentUser(); + + if(user == null ){ + ((MainActivity) getActivity()).replaceFragment(new LoginFragment()); + Toast.makeText(((MainActivity) getActivity()).getApplicationContext(), "Faça login ou se cadastre para ter acesso ao recurso!", Toast.LENGTH_LONG).show(); + return view; + + } + recyclerViewNoticias.setAdapter(adapter); + mDatabase = FirebaseDatabase.getInstance().getReference().child("noticias").child(user.getUid()).child("items"); + ValueEventListener articletListener = new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + // Get Post object and use the values to update the UI + List
noticias = new ArrayList<>(); + for(DataSnapshot templateSnapshot : dataSnapshot.getChildren()){ + + // I've tried a million different things here, but all result in the error + // This is the error line + Article article = templateSnapshot.getValue(Article.class); + noticias.add(article); + } + + adapter = new RecyclerViewLerDepoisAdapter(noticias); + + recyclerViewNoticias.setLayoutManager(new LinearLayoutManager(getContext())); + + recyclerViewNoticias.setAdapter(adapter); + // ... + } + + + @Override + public void onCancelled(DatabaseError databaseError) { + // Getting Post failed, log a message + Log.w("ERRO", "loadPost:onCancelled", databaseError.toException()); + // ... + } + }; + mDatabase.addValueEventListener(articletListener); + + + //btnRemoverNoticia = view.findViewById(R.id.btnBookMarkLerDepois); + + return view; + } + + //Recebe lista + + @Override + public void onClick(Article article) { + + Intent intent = new Intent(getContext(), DetalheLerDepoisActivity.class); + + intent.putExtra("NOTICIAS", article); + + startActivity(intent); + + } + + + @Override + public void onClick(Usuario usuario) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/view/noticias/DetalheNoticiaActivity.java b/app/src/main/java/br/com/dhnews/view/noticias/DetalheNoticiaActivity.java new file mode 100644 index 0000000..ddca630 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/noticias/DetalheNoticiaActivity.java @@ -0,0 +1,194 @@ +package br.com.dhnews.view.noticias; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.squareup.picasso.Picasso; + +import java.util.Random; + +import br.com.dhnews.R; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.model.noticias.Noticias; +import br.com.dhnews.view.MainActivity; +import br.com.dhnews.view.autenticacao.UsuarioFragment; + +import static br.com.dhnews.util.AppUtil.formatarData; + +public class DetalheNoticiaActivity extends AppCompatActivity { + + //Declaracao de atributos + private TextView textViewTituloDetalheNoticia; + private TextView textViewHorarioDetalheNoticia; + private TextView textViewFonteDetalheNoticia; + private TextView textViewConteudoDetalheNoticia; + private ImageView imageViewBackDetalheNoticia; + private ImageView imageViewShareDetalheNoticia; + private ImageView imageViewBookMarkDetalheNoticia; + private ImageView imageViewDetalheNoticia; + private AppBarLayout appBarLayout; + private Noticias noticias; + private Toolbar toolbar; + private View textViewFonteNoticia; + private DatabaseReference mDatabase; + private FirebaseAuth mAuth; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detalhe_noticia); + + + + //Metodo para inicializar as Views + initViews(); + //setSupportActionBar(toolbar); + + mDatabase = FirebaseDatabase.getInstance().getReference(); + mAuth = FirebaseAuth.getInstance(); + + + + //Valido se veio algum dado na intent + if (getIntent() != null && getIntent().getExtras() != null) { + Article noticias = getIntent().getParcelableExtra("NOTICIAS"); + + if (noticias != null) { + + retornaDetalheListaNoticias(noticias); + + //Metodo para voltar para a tela com a Lista de noticias + chamaListaNoticia(); + + //Metodo para acessar os aplicativos de compartilhamento de dados + compartilharNoticia(); + + + //Metodo para chamar a tela de LoginFragment para cadastrar da opcao ler noticia depois + + imageViewBookMarkDetalheNoticia.setOnClickListener(v->cadastraLerDepois(noticias)); + } + } + } + + // @SuppressLint("WrongViewCast") + private void initViews() { + toolbar = findViewById(R.id.toolbar); + imageViewBackDetalheNoticia = findViewById(R.id.imageBack); + imageViewDetalheNoticia = findViewById(R.id.imagemNoticiaDetalhe); + appBarLayout = findViewById(R.id.appBar); + textViewConteudoDetalheNoticia = findViewById(R.id.textViewConteudoNoticiaDetalhe); + + + textViewTituloDetalheNoticia = findViewById(R.id.textViewTituloNoticiaDetalhe); + textViewHorarioDetalheNoticia = findViewById(R.id.textViewHorarioNoticiaDetalhe); + textViewFonteDetalheNoticia = findViewById(R.id.textViewFonteNoticiaDetalhe); + imageViewShareDetalheNoticia = findViewById(R.id.imagemShareNoticiaDetalhe); + imageViewBookMarkDetalheNoticia = findViewById(R.id.imageBookmarkLerDepois); + } + + private void retornaDetalheListaNoticias(Article noticias) { + + textViewTituloDetalheNoticia.setText(noticias.getTitle()); + + + textViewHorarioDetalheNoticia.setText(formatarData(noticias.getPublishedAt())); + + + // textViewFonteNoticia.setText(noticias.getSource()); + textViewConteudoDetalheNoticia.setText(noticias.getContent()); + + // toolbar.setTitle(noticias.getTitle()); + + if (noticias.getUrlToImage() != null) { + + Picasso.get().setIndicatorsEnabled(true); + Picasso.get() + .load(noticias.getUrlToImage()) + .error(R.mipmap.ic_launcher) + .placeholder(R.mipmap.ic_launcher) + .into(imageViewDetalheNoticia); + } + + + } + + + private void chamaListaNoticia() { + imageViewBackDetalheNoticia.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + //Chama a tela com a Lista de Article + + //Chama a Main Activity que verifica qual opcao do Menu Principal foi acionado para + //chamar a tela/fragmento correspondente + Intent intentListaNoticias = new Intent( + DetalheNoticiaActivity.this, MainActivity.class); + + //Chama o fragmento da tela de Article(atraves de um flag 'Tela' com valor + //'Noticia') para retornar para a lista de noticias + intentListaNoticias.putExtra("TELA", "NOTICIA"); + + startActivity(intentListaNoticias); + } + }); + } + + private void compartilharNoticia() { + imageViewShareDetalheNoticia.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + //Acao de envio na intencao de chamar outra Actitivity + Intent intentCompartilhar = new Intent(Intent.ACTION_SEND); + + //Envia texto no compartilhamento + intentCompartilhar.putExtra(Intent.EXTRA_TEXT, "Compartilhando noticias"); + + //tipo de compartilhamento + intentCompartilhar.setType("text/plain"); + + //Mostra os aplicativos disponiveis para compartilhamento de dados + Intent intentChooser = Intent.createChooser( + intentCompartilhar, "Compartilhar via:"); + + //Start na Activity de compartilhamento + startActivity(intentChooser); + } + }); + } + + private String cadastraLerDepois(Article article) { + FirebaseUser user = mAuth.getCurrentUser(); + if(user == null ){ + Intent intentListaNoticias = new Intent( + DetalheNoticiaActivity.this, MainActivity.class); + intentListaNoticias.putExtra("TELA", "LOGIN"); + Toast.makeText(this, "Faça login ou se cadastre para ter acesso ao recurso!", Toast.LENGTH_LONG).show(); + startActivity(intentListaNoticias); + return "deu ruim"; + } + Random random = new Random(); + DatabaseReference mNoticias = FirebaseDatabase.getInstance().getReference() + .child("noticias") + .child(user.getUid()) + .child("items").child(Integer.toString(random.nextInt(10))); + mNoticias.setValue(article); + Toast.makeText(this, "Adicionado com sucesso!", Toast.LENGTH_SHORT).show(); + return "deu bom"; + } + +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/view/noticias/NoticiasFragment.java b/app/src/main/java/br/com/dhnews/view/noticias/NoticiasFragment.java new file mode 100644 index 0000000..c5df68c --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/noticias/NoticiasFragment.java @@ -0,0 +1,105 @@ +package br.com.dhnews.view.noticias; + + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.List; + +import br.com.dhnews.R; +import br.com.dhnews.adapters.RecyclerViewNoticiasAdapter; +import br.com.dhnews.interfaces.RecyclerViewClickListener; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.model.Usuario; +import br.com.dhnews.viewmodel.NoticiasViewModel; + +import static br.com.dhnews.util.AppUtil.isNetworkConnected; + +/** + * A simple {@link Fragment} subclass. + */ +public class NoticiasFragment extends Fragment implements RecyclerViewClickListener { + + private List
noticiasList = new ArrayList<>(); + private RecyclerViewNoticiasAdapter noticiasAdapter; + private RecyclerView recyclerView; + private NoticiasViewModel viewModel; + + + + public NoticiasFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_noticias, container, false); + + recyclerView = view.findViewById(R.id.listaNoticiasRecyclerView); + + noticiasAdapter = new RecyclerViewNoticiasAdapter(noticiasList); + + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setAdapter(noticiasAdapter); + + viewModel = ViewModelProviders.of(this).get(NoticiasViewModel.class); + + if (isNetworkConnected(getContext())) { + viewModel.getNoticias(); + } else { + viewModel.getFromLocal(); + } + + viewModel.getResults().observe(this, results -> noticiasAdapter.update(results)); + + return view; + } + + + + @Override + public void onClick(Article article) { + + } + + @Override + public void onClick(Usuario usuario) { + + } + private void setScrollListener() { + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + } + + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + + LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager(); + int totalItemCount = manager.getItemCount(); + int lastVisible = manager.findLastVisibleItemPosition(); + + boolean fimFoiEncontrado = lastVisible + 5 >= totalItemCount; + +// if (totalItemCount > 0 && fimFoiEncontrado) { +// pagina++; +// viewModel.searchItem(itemBusca, pagina, limite); +// } + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/view/pesquisa/PesquisaFragment.java b/app/src/main/java/br/com/dhnews/view/pesquisa/PesquisaFragment.java new file mode 100644 index 0000000..c9c01b8 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/view/pesquisa/PesquisaFragment.java @@ -0,0 +1,144 @@ +package br.com.dhnews.view.pesquisa; + +import android.content.Context; +import android.os.Bundle; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.appcompat.widget.SearchView; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; + +import java.util.ArrayList; +import java.util.List; + +import br.com.dhnews.R; +import br.com.dhnews.adapters.RecyclerViewNoticiasAdapter; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.viewmodel.NoticiasViewModel; + +public class PesquisaFragment extends Fragment { + + private RecyclerView recyclerView; + private SearchView editTextSearch; + private RecyclerViewNoticiasAdapter adapter; + private List
results = new ArrayList<>(); + private NoticiasViewModel viewModel; + + private int limite = 10; + private String itemBusca; + + public PesquisaFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_pesquisa, container, false); + recyclerView = view.findViewById(R.id.recyclerview); + + editTextSearch = view.findViewById(R.id.editPesquisa); + viewModel = ViewModelProviders.of(this).get(NoticiasViewModel.class); + adapter = new RecyclerViewNoticiasAdapter(results); + editTextSearch.requestFocus(); + + InputMethodManager mgr = (InputMethodManager)getActivity().getSystemService( + Context.INPUT_METHOD_SERVICE); + mgr.showSoftInput(editTextSearch, InputMethodManager.SHOW_IMPLICIT); + + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setAdapter(adapter); + + viewModel = ViewModelProviders.of(this).get(NoticiasViewModel.class); + + viewModel.searchItem(itemBusca, limite); + + viewModel.getResults().observe(this, results -> adapter.update(results)); + setScrollListener(); + + + editTextSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + itemBusca = query; + adapter.clear(); + viewModel.searchItem(itemBusca, limite); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + if (newText.length() > 3){ + itemBusca = newText; + adapter.clear(); + viewModel.searchItem(itemBusca, limite); + } + return false; + } + }); + return view; + } + + + + private void setScrollListener() { + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + } + + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + + LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager(); + int totalItemCount = manager.getItemCount(); + int lastVisible = manager.findLastVisibleItemPosition(); + + boolean fimEncontrado = lastVisible + 5 >= totalItemCount; + + if (totalItemCount > 0 && fimEncontrado) { + limite++; + viewModel.searchItem(itemBusca, limite); + } + + } + }); + } + + + +// String[] arrayList = new String[]{"Esporte", "Politica", "Cinema", "Tecnologia"}; +// final ArrayAdapter adapter; +// +// +// adapter = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, arrayList); + + +// searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { +// @Override +// public boolean onQueryTextSubmit(String query) { +// return false; +// } +// +// @Override +// public boolean onQueryTextChange(String newQuery) { +// +// adapter.getFilter().filter(newQuery); +// +// return false; +// } +// }); + + + +} \ No newline at end of file diff --git a/app/src/main/java/br/com/dhnews/splash/Splash.java b/app/src/main/java/br/com/dhnews/view/splash/SplashActivity.java similarity index 78% rename from app/src/main/java/br/com/dhnews/splash/Splash.java rename to app/src/main/java/br/com/dhnews/view/splash/SplashActivity.java index 7445f8a..133daba 100644 --- a/app/src/main/java/br/com/dhnews/splash/Splash.java +++ b/app/src/main/java/br/com/dhnews/view/splash/SplashActivity.java @@ -1,7 +1,7 @@ -package br.com.dhnews.splash; +package br.com.dhnews.view.splash; import android.content.Intent; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ImageView; @@ -9,10 +9,10 @@ import java.util.Timer; import java.util.TimerTask; -import br.com.dhnews.view.MainActivy; import br.com.dhnews.R; +import br.com.dhnews.view.MainActivity; -public class Splash extends AppCompatActivity { +public class SplashActivity extends AppCompatActivity { private Timer timer = new Timer(); @@ -30,7 +30,6 @@ public void onClick(View view) { jump(); } }); - timer.schedule(new TimerTask() { @Override public void run() { @@ -41,7 +40,7 @@ public void run() { private void jump() { timer.cancel(); - Intent intent = new Intent(Splash.this, MainActivy.class); + Intent intent = new Intent(SplashActivity.this, MainActivity.class); startActivity(intent); finish(); } diff --git a/app/src/main/java/br/com/dhnews/viewmodel/NoticiasViewModel.java b/app/src/main/java/br/com/dhnews/viewmodel/NoticiasViewModel.java new file mode 100644 index 0000000..c26eea7 --- /dev/null +++ b/app/src/main/java/br/com/dhnews/viewmodel/NoticiasViewModel.java @@ -0,0 +1,120 @@ +package br.com.dhnews.viewmodel; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import java.util.List; + +import br.com.dhnews.database.Database; +import br.com.dhnews.database.NoticiasDAO; +import br.com.dhnews.model.noticias.Noticias; +import br.com.dhnews.model.noticias.Article; +import br.com.dhnews.repository.NoticiasRepository; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; + +import static br.com.dhnews.util.AppUtil.isNetworkConnected; + +public class NoticiasViewModel extends AndroidViewModel { + + private MutableLiveData> resultLiveData = new MutableLiveData<>(); + private CompositeDisposable disposable = new CompositeDisposable(); + private NoticiasRepository repository = new NoticiasRepository(); + private MutableLiveData loadingLiveData = new MutableLiveData<>(); + private MutableLiveData errorLiveData = new MutableLiveData<>(); + + + public NoticiasViewModel(@NonNull Application application) { + super(application); + } + + public LiveData getErrorLiveData() { + + return errorLiveData; + + } + + public LiveData> getResults() { + return resultLiveData; + } + + public LiveData Loading() { + return loadingLiveData; + } + + public void searchItem(String item, int limite) { + if (isNetworkConnected(getApplication())) { + getNoticiasSearch(item, limite); + } else { + //getFromLocal(); + } + } + + public void getNoticias() { + + disposable.add( + repository.getNoticias() + .subscribeOn(Schedulers.newThread()) + .map(noticias -> saveItems(noticias)) + .observeOn(AndroidSchedulers.mainThread()) + .doOnSubscribe(disposable1 -> loadingLiveData.setValue(true)) + .doAfterTerminate(() -> loadingLiveData.setValue(false)) + .subscribe(noticias -> resultLiveData.setValue(noticias.getArticles()) + , throwable -> errorLiveData.setValue(throwable)) + ); + } + + public void getNoticiasSearch(String item, int limite) { + + disposable.add( + repository.searchItems(item, limite) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnSubscribe(disposable1 -> loadingLiveData.setValue(true)) + .doAfterTerminate(() -> loadingLiveData.setValue(false)) + .subscribe(noticias -> resultLiveData.setValue(noticias.getArticles()) + , throwable -> errorLiveData.setValue(throwable)) + ); + } + + public void getNoticiasFavoritas(String categoria, int limite) { + + disposable.add( + repository.getNoticiasFavoritas(categoria, limite) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnSubscribe(disposable1 -> loadingLiveData.setValue(true)) + .doAfterTerminate(() -> loadingLiveData.setValue(false)) + .subscribe(noticias -> resultLiveData.setValue(noticias.getArticles()) + , throwable -> errorLiveData.setValue(throwable)) + ); + } + + public void getFromLocal() { + + // Adicionamos a chamada a um disposible para podermos eliminar o disposable da destruição do viewmodel + disposable.add( + repository.getLocalResults(getApplication().getApplicationContext()) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnSubscribe(disposable1 -> loadingLiveData.setValue(true)) + .doAfterTerminate(() -> loadingLiveData.setValue(false)) + .subscribe(articles -> resultLiveData.setValue(articles) + , throwable -> errorLiveData.setValue(throwable)) + ); + } + + private Noticias saveItems(Noticias noticias) { + NoticiasDAO dao = Database.getDatabase(getApplication().getApplicationContext()) + .resultsDAO(); + dao.deleteAll(); + dao.insert(noticias.getArticles()); + + return noticias; + } +} diff --git a/app/src/main/res/drawable-xxxhdpi/loading.png b/app/src/main/res/drawable-xxxhdpi/loading.png new file mode 100644 index 0000000..b3bb3bb Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/loading.png differ diff --git a/app/src/main/res/drawable/ic_arrow_back.xml b/app/src/main/res/drawable/ic_arrow_back.xml new file mode 100644 index 0000000..71d5bbd --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_back.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/imagem_detalhe.jpg b/app/src/main/res/drawable/imagem_detalhe.jpg new file mode 100644 index 0000000..a12c7c8 Binary files /dev/null and b/app/src/main/res/drawable/imagem_detalhe.jpg differ diff --git a/app/src/main/res/drawable/progress_animation.xml b/app/src/main/res/drawable/progress_animation.xml new file mode 100644 index 0000000..6a68602 --- /dev/null +++ b/app/src/main/res/drawable/progress_animation.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/lato_light.ttf b/app/src/main/res/font/lato_light.ttf new file mode 100644 index 0000000..a958067 Binary files /dev/null and b/app/src/main/res/font/lato_light.ttf differ diff --git a/app/src/main/res/layout/activity_cadastro.xml b/app/src/main/res/layout/activity_cadastro.xml deleted file mode 100644 index 3962c84..0000000 --- a/app/src/main/res/layout/activity_cadastro.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -