diff --git a/README.md b/README.md
index e46e1b6..81e2541 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
App for getting video game news from different websites!
-See release notes on master branch releases for features that cover last release.
+See release notes on master branch releases for features that cover last release. You could also download last .apk version here. (**Android min. version: 4.1**)
See changelog on develop branch for not-official features.
@@ -14,8 +14,38 @@ See changelog on develop branch for not-official features.
-RSS Parser (https://github.com/prof18/RSS-Parser)
+# Build
+
+1. Open Android Studio.
+2. Select File -> New -> Project from Version Control -> GitHub
+3. Enter your github username and password.
+4. Copy this repo's clone url.
+5. Select the repository and hit clone.
+
+
# Changelog
--11/7/2018: Changed colors. Added app icon inside toolbar. Added a Floating Action Button for back to top compability.
--2/7/2018: Bugfixes for Locale and proper onBackPressed when paserMaker.isRunning = true. Change min. version for Android 4.1 Improvement of ParserMaker
--27/6/2018: First commit.
\ No newline at end of file
+**-14/7/2018:**
+ Added a drawer layout with a navigation view.
+
+ Changed MainActivity's all in one for a Fragment that can handle all categories of news.
+
+ Changed ParserMaker's use of variable Activity in order to avoid a NullException. Now use an interface.
+
+ Created Urls.json file for reading urls depending on language.
+
+ Added GSON library for Json reading.
+
+ Created Categories inside Models package.
+
+ Created LoadUrls for handling the reading of the Json file.
+
+ Created WebViewActivity.
+
+ Deleted icon in toolbar.xml layout. Now is added with toolbar.setIcon()
+
+ Changed harcoded strings and dimens.
+
+**-11/7/2018:** Changed colors. Added app icon inside toolbar. Added a Floating Action Button for back to top compability.
+**-2/7/2018:** Bugfixes for Locale and proper onBackPressed when paserMaker.isRunning = true. Change min. version for Android 4.1 Improvement of ParserMaker
+**-27/6/2018:** First commit.
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 30e9d6f..603ff67 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -26,11 +26,13 @@ dependencies {
implementation 'com.android.support:design:26.1.0'
implementation 'com.prof.rssparser:rssparser:1.4.1'
implementation 'com.squareup.picasso:picasso:2.71828'
+ implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.okhttp:okhttp:2.5.0'
implementation 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:cardview-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
+ implementation 'com.android.support:support-v4:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 54d49f5..fe9b738 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,23 +3,33 @@
package="com.example.emmanuel.gamingnews">
-
+
-
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/Urls.json b/app/src/main/assets/Urls.json
new file mode 100644
index 0000000..3d4fdb9
--- /dev/null
+++ b/app/src/main/assets/Urls.json
@@ -0,0 +1,65 @@
+[
+ {
+ "language": "es",
+ "all_urls": [
+ "https://www.eurogamer.es/?format=rss",
+ "https://vandal.elespanol.com/xml.cgi",
+ "https://www.levelup.com/rss",
+ "https://puregaming.es/feed/"
+ ],
+ "ps4_urls": [
+ "http://feeds.feedburner.com/SCEEBlogES",
+ "https://puregaming.es/juegos-ps4/feed/",
+ "https://www.egamers.com/category/ps4/feed/",
+ "http://es.ign.com/ps4.xml",
+ "http://www.laps4.com/foro/external.php?type=RSS2&forumids=2"
+ ],
+ "xboxO_urls":[
+ "https://puregaming.es/juegos-xbox-one/feed/",
+ "https://www.somosxbox.com/feed",
+ "http://es.ign.com/xbox-one.xml"
+ ],
+ "switch_urls": [
+ "https://www.nintenderos.com/category/switch/noticias-switch/feed/",
+ "https://search.nintendo-europe.com/es/feed/news/",
+ "https://www.eurogamer.es/?format=rss&platform=SWITCH"
+ ],
+ "pc_urls": [
+ "https://puregaming.es/juegos-pc/feed/",
+ "https://www.eurogamer.es/?format=rss&platform=PC",
+ "https://www.egamers.com/category/pc/feed/"
+ ]
+ },
+ {
+ "language": "en",
+ "all_urls": [
+ "https://www.gamespot.com/feeds/news/",
+ "https://www.vg247.com/feed/",
+ "https://www.eurogamer.net/?format=rss",
+ "https://kotaku.com/tag/gaming/rss",
+ "https://www.gameinformer.com/news.xml"
+ ],
+ "ps4_urls": [
+ "https://www.eurogamer.net/?format=rss&platform=PS4",
+ "http://feeds.feedburner.com/psblog",
+ "http://pureplaystation.com/category/latest-news/feed/"
+ ],
+ "xboxO_urls":[
+ "http://www.thisisxbox.com/feed/",
+ "https://news.xbox.com/en-us/feed/",
+ "http://in.ign.com/xbox-one.xml"
+ ],
+ "switch_urls": [
+ "https://nintendotoday.com/tag/switch/feed/",
+ "https://kotaku.com/tag/nintendo-switch/rss",
+ "https://mynintendonews.com/feed/",
+ "https://nintendowire.com/switch/feed/",
+ "http://www.nintendolife.com/feeds/news"
+ ],
+ "pc_urls": [
+ "https://www.rockpapershotgun.com/category/pc-game-news/feed/",
+ "https://venturebeat.com/category/pc-gaming/feed/",
+ "https://www.pcgamer.com/rss/"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/Fragments/NewsListFragment.java b/app/src/main/java/com/example/emmanuel/gamingnews/Fragments/NewsListFragment.java
new file mode 100644
index 0000000..06a8930
--- /dev/null
+++ b/app/src/main/java/com/example/emmanuel/gamingnews/Fragments/NewsListFragment.java
@@ -0,0 +1,239 @@
+package com.example.emmanuel.gamingnews.Fragments;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import com.example.emmanuel.gamingnews.Adapter.NewsAdapter;
+import com.example.emmanuel.gamingnews.Models.NewsModel;
+import com.example.emmanuel.gamingnews.R;
+import com.example.emmanuel.gamingnews.Utility.ParserMaker;
+import com.example.emmanuel.gamingnews.views.WebViewActivity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class NewsListFragment extends Fragment{
+
+ private static final String TAG = "NewsListFragment";
+
+ private RecyclerView recyclerView;
+ private SwipeRefreshLayout refreshLayout;
+ private NewsAdapter newsAdapter;
+ private List newsList = new ArrayList<>();
+ private ParserMaker parserMaker;
+ private FloatingActionButton fab;
+ private OnFragmentInteractionListener mListener;
+
+ public NewsListFragment() {
+ // Required empty public constructor
+ }
+
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View view = inflater.inflate(R.layout.fragment_news_list,container,false);
+ String[] urls;
+ recyclerView = view.findViewById(R.id.recyclerview);
+ refreshLayout = view.findViewById(R.id.refreshlayout);
+ fab = view.findViewById(R.id.mainFAB);
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ recyclerView.smoothScrollToPosition(0);
+ }
+ });
+ newsAdapter = new NewsAdapter(newsList, clickListener());
+ urls = getArguments().getStringArray("urls");
+ manageRecyclerView(true,true);
+
+ ParserMaker.OnNewsFinishListener newsFinishListener = new ParserMaker.OnNewsFinishListener() {
+ @Override
+ public void onNewsFinish() {
+ refreshLayout.setRefreshing(false);
+ parserMaker.setRunning(false);
+ }
+ };
+
+ parserMaker = new ParserMaker(newsFinishListener,urls,
+ Toast.makeText(getActivity(), R.string.cant_get_articles, Toast.LENGTH_SHORT),
+ this.newsAdapter,this.newsList);
+
+ parserMaker.create();
+
+ refreshLayout.setRefreshing(true);
+ manageRefreshLayout(parserMaker);
+ return view;
+ }
+
+ // TODO: Rename method, update argument and hook method into UI event
+ public void onButtonPressed(Uri uri) {
+ if (mListener != null) {
+ mListener.onFragmentInteraction(uri);
+ }
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ if (context instanceof OnFragmentInteractionListener) {
+ mListener = (OnFragmentInteractionListener) context;
+ } else {
+ throw new RuntimeException(context.toString()
+ + " must implement OnFragmentInteractionListener");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mListener = null;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if(newsList!=null){
+ newsList.clear();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ //parserMaker.setActivity(parserMaker.isRunning() ? getActivity():null);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ //parserMaker.setActivity(parserMaker.isRunning() ? getActivity():null);
+ }
+
+
+
+
+ private void manageRecyclerView(boolean autoMeasure, boolean fixedSize) {
+ RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
+ layoutManager.setAutoMeasureEnabled(autoMeasure);
+
+ recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setAdapter(newsAdapter);
+ recyclerView.setHasFixedSize(fixedSize);
+
+ recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ if(dy > 0 && fab.getVisibility() == View.VISIBLE){
+ fab.setVisibility(View.INVISIBLE);
+ Log.d(TAG,"Entré para esconder"+fab.getVisibility());
+ }
+ else if(dy < 0 && fab.getVisibility() != View.VISIBLE){
+ Log.d(TAG,"Entré para mostrar"+fab.getVisibility());
+ fab.setVisibility(View.VISIBLE);
+ }
+ super.onScrolled(recyclerView, dx, dy);
+ }
+ /*
+ hide() and show() are two methods provided by the FAB to hide/show the FAB button with a smooth animation.
+ dy is a value that changes when you scroll vertically, when the user scrolls down the value is positive
+ and when the user scrolls up the value is negative.
+ So we check if the FAB is visible and the value is positive(i.e. user is scrolling down)
+ we will hide it and if the FAB is hidden and the value is negative(i.e. user is scrolling up) we will show the FAB.
+ */
+ });
+ }
+
+ private void manageRefreshLayout(final ParserMaker parserMaker) {
+ refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+ @Override
+ public void onRefresh() {
+ if(isNetworkAvailable() && !parserMaker.isRunning()) {
+ refreshLayout.setRefreshing(true);
+ parserMaker.create();
+ }
+ else if(!isNetworkAvailable()){
+ AlertDialog dialog = generateDialog(R.string.check_your_connection);
+ dialog.show();
+ refreshLayout.setRefreshing(false);
+ }
+ else if(parserMaker.isRunning()){
+ AlertDialog dialog = generateDialog(R.string.still_refreshing);
+ dialog.show();
+ refreshLayout.setRefreshing(false);
+ }
+ }
+ });
+ }
+
+ private boolean isNetworkAvailable() {
+ ConnectivityManager connectivityManager
+ = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
+ return activeNetworkInfo != null;
+ }
+
+ private AlertDialog generateDialog(int message)
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+ builder.setMessage(message);
+ builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ dialogInterface.dismiss();
+ }
+ });
+ return builder.create();
+ }
+
+
+ private NewsAdapter.NewsViewHolder.OnItemClickListener clickListener() {
+ return new NewsAdapter.NewsViewHolder.OnItemClickListener() {
+ @Override
+ public void OnItemClick(NewsModel item) {
+
+ Intent intent = new Intent(getActivity(), WebViewActivity.class);
+ intent.putExtra("url",item.getLink());
+
+ if(fab.getVisibility() == View.VISIBLE)
+ fab.setVisibility(View.INVISIBLE);
+
+ getActivity().startActivity(intent);
+ }
+ };
+ }
+
+
+ public ParserMaker getParserMaker() {
+ return parserMaker;
+ }
+
+ public interface OnFragmentInteractionListener {
+ // TODO: Update argument type and name
+ void onFragmentInteraction(Uri uri);
+ }
+}
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/MainActivity.java b/app/src/main/java/com/example/emmanuel/gamingnews/MainActivity.java
deleted file mode 100644
index 833e973..0000000
--- a/app/src/main/java/com/example/emmanuel/gamingnews/MainActivity.java
+++ /dev/null
@@ -1,263 +0,0 @@
-package com.example.emmanuel.gamingnews;
-
-import android.content.Context;
-import android.content.DialogInterface;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.ProgressBar;
-import android.widget.Toast;
-
-import com.example.emmanuel.gamingnews.Adapter.NewsAdapter;
-import com.example.emmanuel.gamingnews.Models.NewsModel;
-import com.example.emmanuel.gamingnews.Utility.ParserMaker;
-
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-public class MainActivity extends AppCompatActivity {
-
- private static final String TAG = "MainActivity";
-
- private RecyclerView recyclerView;
- private SwipeRefreshLayout refreshLayout;
- private NewsAdapter newsAdapter;
- private List newsList = new ArrayList<>();
- private ParserMaker parserMaker;
- private WebView webView;
- private ProgressBar progressBar;
- private FloatingActionButton fab;
-
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- String[] urls;
- setContentView(R.layout.activity_main);
- recyclerView = findViewById(R.id.recyclerview);
- refreshLayout = findViewById(R.id.refreshlayout);
- webView = findViewById(R.id.webview);
- fab = findViewById(R.id.mainFAB);
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- recyclerView.smoothScrollToPosition(0);
- }
- });
- newsAdapter = new NewsAdapter(newsList, clickListener());
- if(Locale.getDefault().getLanguage().equals("es")){
- urls = new String[]{"https://www.eurogamer.es/?format=rss","https://vandal.elespanol.com/xml.cgi","https://www.levelup.com/rss","http://www.tierragamer.com/feed/"};
- }
- else{
- urls = new String[]{"https://www.gamespot.com/feeds/news/","https://www.vg247.com/feed/","https://www.eurogamer.net/?format=rss","https://kotaku.com/tag/gaming/rss","https://www.gameinformer.com/news.xml"};
- }
- Toolbar toolbar = findViewById(R.id.toolbar);
- showToolbar(toolbar,R.string.app_name,false);
-
- manageRecyclerView(true,true);
-
- parserMaker = new ParserMaker(MainActivity.this,urls,
- Toast.makeText(MainActivity.this, "Can't get all articles from sites...", Toast.LENGTH_SHORT),
- this.newsAdapter,this.newsList);
-
- parserMaker.create();
-
- refreshLayout.setRefreshing(true);
- manageRefreshLayout(parserMaker);
- }
-
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if(newsList!=null){
- newsList.clear();
- }
- parserMaker.setActivity(null);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- parserMaker.setActivity(parserMaker.isRunning() ? MainActivity.this:null);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- parserMaker.setActivity(parserMaker.isRunning() ? MainActivity.this:null);
- }
-
- @Override
- public void onBackPressed() {
- if(webView.getVisibility() == View.INVISIBLE || webView.getVisibility() == View.GONE){
- if(parserMaker.isRunning()){
- //Bugfix for parserMaker's activity setting to null when onBackPressed. This puts MainActivity on stack, but there's
- //no other activity, so basic funcionality of onBackPressed() stays the same...
- moveTaskToBack(true);
- }
- else{
- super.onBackPressed();
- }
- }
- }
-
- private void showToolbar(Toolbar toolbar, int title, boolean upButton){
- setSupportActionBar(toolbar);
- getSupportActionBar().setTitle(title);
- getSupportActionBar().setDisplayHomeAsUpEnabled(upButton);
- Log.d(TAG,"Title: "+getSupportActionBar().getTitle().toString());
- progressBar = findViewById(R.id.toolbarProgressBar);
- progressBar.setVisibility(View.GONE);
- progressBar.setIndeterminate(false);
- }
-
- private void manageRecyclerView(boolean autoMeasure, boolean fixedSize) {
- RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
- layoutManager.setAutoMeasureEnabled(autoMeasure);
-
- recyclerView.setLayoutManager(layoutManager);
- recyclerView.setAdapter(newsAdapter);
- recyclerView.setHasFixedSize(fixedSize);
-
- recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- if(dy > 0 && fab.getVisibility() == View.VISIBLE){
- fab.setVisibility(View.INVISIBLE);
- Log.d(TAG,"Entré para esconder"+fab.getVisibility());
- }
- else if(dy < 0 && fab.getVisibility() != View.VISIBLE){
- Log.d(TAG,"Entré para mostrar"+fab.getVisibility());
- fab.setVisibility(View.VISIBLE);
- }
- super.onScrolled(recyclerView, dx, dy);
- }
- /*
- hide() and show() are two methods provided by the FAB to hide/show the FAB button with a smooth animation.
- dy is a value that changes when you scroll vertically, when the user scrolls down the value is positive
- and when the user scrolls up the value is negative.
- So we check if the FAB is visible and the value is positive(i.e. user is scrolling down)
- we will hide it and if the FAB is hidden and the value is negative(i.e. user is scrolling up) we will show the FAB.
- */
- });
- }
-
- private void manageRefreshLayout(final ParserMaker parserMaker) {
- refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
- @Override
- public void onRefresh() {
- if(isNetworkAvailable() && !parserMaker.isRunning()) {
- refreshLayout.setRefreshing(true);
- if(parserMaker.getActivity() == null)
- parserMaker.setActivity(MainActivity.this);
- parserMaker.create();
- }
- else if(!isNetworkAvailable()){
- AlertDialog dialog = generateDialog("Check your internet connection");
- dialog.show();
- refreshLayout.setRefreshing(false);
- }
- else if(parserMaker.isRunning()){
- AlertDialog dialog = generateDialog("App is still refreshing");
- dialog.show();
- refreshLayout.setRefreshing(false);
- }
- }
- });
- }
-
- private boolean isNetworkAvailable() {
- ConnectivityManager connectivityManager
- = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
- return activeNetworkInfo != null;
- }
-
- private AlertDialog generateDialog(String message)
- {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(message);
- builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- dialogInterface.dismiss();
- }
- });
- return builder.create();
- }
-
- private NewsAdapter.NewsViewHolder.OnItemClickListener clickListener() {
- return new NewsAdapter.NewsViewHolder.OnItemClickListener() {
- @Override
- public void OnItemClick(NewsModel item) {
- getSupportActionBar().setTitle("Loading...");
- progressBar.setVisibility(View.VISIBLE);
- WebSettings webSettings = webView.getSettings();
- webSettings.setJavaScriptEnabled(true);
-
- if(fab.getVisibility() == View.VISIBLE)
- fab.setVisibility(View.INVISIBLE);
-
- webView.setWebChromeClient(new WebChromeClient(){
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- super.onProgressChanged(view, newProgress);
- progressBar.setProgress(newProgress);
- if(newProgress == 100){
- progressBar.setVisibility(View.GONE);
- getSupportActionBar().setTitle(R.string.app_name);
- }
- }
- }
- );
-
- webView.setWebViewClient(new WebViewClient() {
- public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
- Toast.makeText(getApplicationContext(), "Oh no! " + description, Toast.LENGTH_SHORT).show();
- }
- });
-
- webView.setOnKeyListener(new View.OnKeyListener() {
- @Override
- public boolean onKey(View view, int i, KeyEvent keyEvent) {
- if(i == KeyEvent.KEYCODE_BACK){
- webView.loadUrl("about:blank");
- progressBar.setVisibility(View.GONE);
- webView.setVisibility(View.GONE);
- recyclerView.setVisibility(View.VISIBLE);
- refreshLayout.setEnabled(true);
- getSupportActionBar().setTitle(R.string.app_name);
- return true;
- }
- else{
- return false;
- }
- }
- });
-
- webView.loadUrl(item.getLink());
- recyclerView.setVisibility(View.INVISIBLE);
- webView.setVisibility(View.VISIBLE);
- refreshLayout.setEnabled(false);
- }
- };
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/Models/Categories.java b/app/src/main/java/com/example/emmanuel/gamingnews/Models/Categories.java
new file mode 100644
index 0000000..d2b6b85
--- /dev/null
+++ b/app/src/main/java/com/example/emmanuel/gamingnews/Models/Categories.java
@@ -0,0 +1,73 @@
+package com.example.emmanuel.gamingnews.Models;
+
+import java.util.Arrays;
+
+public class Categories {
+ private String language;
+ private String[] all_urls;
+ private String[] ps4_urls;
+ private String[] xboxO_urls;
+ private String[] switch_urls;
+ private String[] pc_urls;
+
+ public Categories(String language, String[] all_urls) {
+ this.language = language;
+ this.all_urls = all_urls;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String[] getAll_urls() {
+ return all_urls;
+ }
+
+ public void setAll_urls(String[] all_urls) {
+ this.all_urls = all_urls;
+ }
+
+ public String[] getPs4_urls() {
+ return ps4_urls;
+ }
+
+ public void setPs4_urls(String[] ps4_urls) {
+ this.ps4_urls = ps4_urls;
+ }
+
+ public String[] getXboxO_urls() {
+ return xboxO_urls;
+ }
+
+ public void setXboxO_urls(String[] xboxO_urls) {
+ this.xboxO_urls = xboxO_urls;
+ }
+
+ public String[] getSwitch_urls() {
+ return switch_urls;
+ }
+
+ public void setSwitch_urls(String[] switch_urls) {
+ this.switch_urls = switch_urls;
+ }
+
+ public String[] getPc_urls() {
+ return pc_urls;
+ }
+
+ public void setPc_urls(String[] pc_urls) {
+ this.pc_urls = pc_urls;
+ }
+
+ @Override
+ public String toString() {
+ return "Categories{" +
+ "language='" + language + '\'' +
+ ", all_urls=" + Arrays.toString(all_urls) +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/Objects/LoadUrls.java b/app/src/main/java/com/example/emmanuel/gamingnews/Objects/LoadUrls.java
new file mode 100644
index 0000000..cc99ac7
--- /dev/null
+++ b/app/src/main/java/com/example/emmanuel/gamingnews/Objects/LoadUrls.java
@@ -0,0 +1,89 @@
+package com.example.emmanuel.gamingnews.Objects;
+
+import android.app.Activity;
+
+import com.example.emmanuel.gamingnews.Models.Categories;
+import com.google.gson.Gson;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class LoadUrls {
+ private String language;
+ private InputStream jsonFile;
+ private String[] allUrls;
+ private String[] ps4Urls;
+ private String[] xboxOUrls;
+ private String[] switchUrls;
+ private String[] pcUrls;
+
+ public LoadUrls(String language, InputStream jsonFile){
+ this.language = language;
+ this.jsonFile = jsonFile;
+ }
+ private Categories[] loadCategories(){
+ Gson gson = new Gson();
+ return gson.fromJson(loadJSONFromAsset(),Categories[].class);
+ }
+ private Categories getLocalCategory(){
+ Categories[] categories = loadCategories();
+ Categories category = null;
+ for(Categories cat:categories){
+ if(cat.getLanguage().equals(language)){
+ category = cat;
+ break;
+ }
+ else if(cat.getLanguage().equals("en") && category == null){
+ category = cat;
+ }
+ }
+ return category;
+ }
+
+ public void setUrls(){
+ Categories category = getLocalCategory();
+ allUrls = category.getAll_urls();
+ ps4Urls = category.getPs4_urls();
+ xboxOUrls = category.getXboxO_urls();
+ switchUrls = category.getSwitch_urls();
+ pcUrls = category.getPc_urls();
+ }
+
+ private String loadJSONFromAsset() {
+ String json = null;
+ try {
+ InputStream is = jsonFile;
+ int size = is.available();
+ byte[] buffer = new byte[size];
+ is.read(buffer);
+ is.close();
+ json = new String(buffer, "UTF-8");
+ return json;
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ return json;
+ }
+
+
+ public String[] getAllUrls() {
+ return allUrls;
+ }
+
+ public String[] getPs4Urls() {
+ return ps4Urls;
+ }
+
+ public String[] getXboxOUrls() {
+ return xboxOUrls;
+ }
+
+ public String[] getSwitchUrls() {
+ return switchUrls;
+ }
+
+ public String[] getPcUrls() {
+ return pcUrls;
+ }
+
+}
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/Utility/ParserMaker.java b/app/src/main/java/com/example/emmanuel/gamingnews/Utility/ParserMaker.java
index 98a599f..a1ae53a 100644
--- a/app/src/main/java/com/example/emmanuel/gamingnews/Utility/ParserMaker.java
+++ b/app/src/main/java/com/example/emmanuel/gamingnews/Utility/ParserMaker.java
@@ -1,6 +1,7 @@
package com.example.emmanuel.gamingnews.Utility;
import android.app.Activity;
+import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.Html;
import android.util.Log;
@@ -9,6 +10,7 @@
import com.example.emmanuel.gamingnews.Adapter.NewsAdapter;
import com.example.emmanuel.gamingnews.Models.NewsModel;
import com.example.emmanuel.gamingnews.R;
+import com.example.emmanuel.gamingnews.views.MainActivity;
import com.prof.rssparser.Article;
import com.prof.rssparser.Parser;
@@ -16,6 +18,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.logging.Handler;
public class ParserMaker{
@@ -23,28 +26,26 @@ public class ParserMaker{
private static final String TAG = "ParserMaker";
private static final int OBJ_NUMBER = 65532;
- private Activity activity;
private String[] urls;
private Toast toast;
private NewsAdapter newsAdapter;
private boolean running;
private boolean firstRun;
- private boolean error;
private boolean newItems;
private List newsList;
+ private OnNewsFinishListener onNewsFinishListener;
- public ParserMaker(Activity activity,String[] urls, Toast toast, NewsAdapter newsAdapter, List newsList){
- firstRun = true;
+ public ParserMaker(OnNewsFinishListener onNewsFinishListener,String[] urls, Toast toast, NewsAdapter newsAdapter, List newsList){
+ firstRun = newsList.isEmpty();
this.urls = urls;
- this.activity = activity;
+ this.onNewsFinishListener = onNewsFinishListener;
this.toast = toast;
this.newsAdapter = newsAdapter;
this.newsList = newsList;
}
public void create(){
running = true;
- error = false;
newItems = false;
Parser[] parsers = new Parser[urls.length];
for (int i = 0;i list) {
- if(firstRun){
+ if(newsList.isEmpty()){
newItems = true;
for(com.prof.rssparser.Article article:list){
newsList.add(new NewsModel(article.getImage() == null ? "":article.getImage(),article.getTitle(),
@@ -84,10 +85,7 @@ public void onTaskCompleted(ArrayList list) {
}
Log.d(TAG,"Size: "+newsList.size()+" Count: "+newsAdapter.getItemCount());
if(stopRefresh){
- if(error){
- toast.show();
- }
- if(firstRun || newItems){
+ if(newItems){
newItems = false;
firstRun = false;
orderListRecentFirst();
@@ -99,12 +97,9 @@ public void onTaskCompleted(ArrayList list) {
@Override
public void onError() {
- error = true;
- if(stopRefresh){
- if(newsList.size() != 0){
- firstRun = false;
- }
- toast.show();
+ toast.show();
+ if(stopRefresh) {
+ firstRun = !newsList.isEmpty();
refreshingStatus();
}
}
@@ -134,7 +129,6 @@ private void orderListRecentFirst() {
Collections.sort(newsList, new Comparator() {
@Override
public int compare(NewsModel newsModel, NewsModel t1) {
- Log.d(TAG,"ENTRÉ A COMPARAR");
if(newsModel.getPubDate() != null && t1.getPubDate() != null){
return t1.getPubDate().compareTo(newsModel.getPubDate());
}
@@ -146,25 +140,26 @@ public int compare(NewsModel newsModel, NewsModel t1) {
}
private void refreshingStatus(){
- activity.runOnUiThread(new Runnable() {
+ onNewsFinishListener.onNewsFinish();
+ /*activity.runOnUiThread(new Runnable() {
@Override
public void run() {
((SwipeRefreshLayout)activity.findViewById(R.id.refreshlayout)).setRefreshing(false);
running = false;
}
- });
-
- }
- public Activity getActivity() {
- return activity;
+ });*/
}
- public void setActivity(Activity activity){
- this.activity = activity;
+ public void setRunning(boolean running) {
+ this.running = running;
}
public boolean isRunning() {
return running;
}
+ public interface OnNewsFinishListener{
+ void onNewsFinish();
+ }
+
}
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/views/MainActivity.java b/app/src/main/java/com/example/emmanuel/gamingnews/views/MainActivity.java
new file mode 100644
index 0000000..4f44876
--- /dev/null
+++ b/app/src/main/java/com/example/emmanuel/gamingnews/views/MainActivity.java
@@ -0,0 +1,147 @@
+package com.example.emmanuel.gamingnews.views;
+
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.design.widget.NavigationView;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ProgressBar;
+
+import com.example.emmanuel.gamingnews.Fragments.NewsListFragment;
+import com.example.emmanuel.gamingnews.Objects.LoadUrls;
+import com.example.emmanuel.gamingnews.R;
+
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+public class MainActivity extends AppCompatActivity implements NewsListFragment.OnFragmentInteractionListener {
+
+ private static final String TAG = "MainActivity";
+ private static final String[] News_TAG = {"NewsListFragment_All","NewsListFragment_PS4","NewsListFragment_XboxO",
+ "NewsListFragment_Switch","NewsListFragment_PC"
+ };
+
+ private DrawerLayout drawerLayout;
+ private ProgressBar progressBar;
+ private LoadUrls loadUrls;
+ private NavigationView navigationView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ navigationView = findViewById(R.id.navigation_view);
+ showToolbar(toolbar, R.string.app_name, false);
+ startDrawerLayout(toolbar);
+ InputStream is = null;
+ loadUrls = null;
+ try {
+ is = getAssets().open("Urls.json");
+ loadUrls = new LoadUrls(Locale.getDefault().getLanguage(), is);
+ loadUrls.setUrls();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ startNavigationView();
+ makeFragmentTransaction(loadUrls.getAllUrls(), R.id.all_news,News_TAG[0]);
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ NewsListFragment fragment = null;
+ for(int i = 0;i<5;i++){
+ fragment = (NewsListFragment) getSupportFragmentManager().findFragmentByTag(News_TAG[i]);
+ if(fragment!=null){
+ break;
+ }
+ }
+ if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
+ getSupportFragmentManager().popBackStack();
+ } else {
+ if (fragment.getParserMaker().isRunning()) {
+ moveTaskToBack(true);
+ } else {
+ finish();
+ }
+ }
+ }
+
+ private void showToolbar(Toolbar toolbar, int title, boolean upButton) {
+ setSupportActionBar(toolbar);
+ getSupportActionBar().setTitle(title);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(upButton);
+ getSupportActionBar().setLogo(R.mipmap.ic_launcher_round);
+ toolbar.getLogo().setBounds(3, 3, 3, 3);
+ Log.d(TAG, "Title: " + getSupportActionBar().getTitle().toString());
+ progressBar = findViewById(R.id.toolbarProgressBar);
+ progressBar.setVisibility(View.GONE);
+ progressBar.setIndeterminate(false);
+ }
+
+
+ private void startDrawerLayout(Toolbar toolbar) {
+ drawerLayout = findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
+ toolbar, R.string.drawer_open, R.string.drawer_close);
+ drawerLayout.addDrawerListener(drawerToggle);
+ drawerToggle.syncState();
+ }
+
+ private void startNavigationView() {
+ navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.all_news:
+ makeFragmentTransaction(loadUrls.getAllUrls(), R.id.all_news,News_TAG[0]);
+ break;
+ case R.id.ps4_news:
+ makeFragmentTransaction(loadUrls.getPs4Urls(), R.id.all_news,News_TAG[1]);
+ break;
+ case R.id.xboxo_news:
+ makeFragmentTransaction(loadUrls.getXboxOUrls(), R.id.all_news,News_TAG[2]);
+ break;
+ case R.id.switch_news:
+ makeFragmentTransaction(loadUrls.getSwitchUrls(), R.id.all_news,News_TAG[3]);
+ break;
+ case R.id.PC_news:
+ makeFragmentTransaction(loadUrls.getPcUrls(), R.id.all_news,News_TAG[4]);
+ break;
+ }
+ return true;
+ }
+ });
+ }
+
+ private void makeFragmentTransaction(String[] urls, int item, String TAG) {
+ Bundle bundle = new Bundle();
+ bundle.putStringArray("urls", urls);
+ NewsListFragment newsFragment = (NewsListFragment) getSupportFragmentManager().findFragmentByTag(TAG);
+ if(newsFragment == null){
+ newsFragment = new NewsListFragment();
+ }
+ newsFragment.setArguments(bundle);
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.container, newsFragment, TAG)
+ .addToBackStack(null)
+ .commit();
+ navigationView.setCheckedItem(item);
+ drawerLayout.closeDrawers();
+ }
+
+ @Override
+ public void onFragmentInteraction(Uri uri) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/emmanuel/gamingnews/views/WebViewActivity.java b/app/src/main/java/com/example/emmanuel/gamingnews/views/WebViewActivity.java
new file mode 100644
index 0000000..9b6a0c5
--- /dev/null
+++ b/app/src/main/java/com/example/emmanuel/gamingnews/views/WebViewActivity.java
@@ -0,0 +1,87 @@
+package com.example.emmanuel.gamingnews.views;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import com.example.emmanuel.gamingnews.R;
+
+public class WebViewActivity extends AppCompatActivity {
+ private static final String TAG = "WebViewActivity";
+
+ private WebView webView;
+ private ProgressBar progressBar;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_web_view);
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ showToolbar(toolbar,R.string.loading,true);
+ webView = findViewById(R.id.webview);
+ String url = getIntent().getExtras().getString("url");
+ loadUrl(url);
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (webView.canGoBack()) {
+ webView.goBack();
+ return;
+ }
+ // Otherwise defer to system default behavior.
+ webView.loadUrl("about:blank");
+ super.onBackPressed();
+ }
+ private void showToolbar(Toolbar toolbar, int title, boolean upButton){
+ setSupportActionBar(toolbar);
+ getSupportActionBar().setTitle(title);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(upButton);
+ getSupportActionBar().setLogo(R.mipmap.ic_launcher_round);
+ Log.d(TAG,"Title: "+getSupportActionBar().getTitle().toString());
+ progressBar = findViewById(R.id.toolbarProgressBar);
+ progressBar.setVisibility(View.INVISIBLE);
+ progressBar.setIndeterminate(false);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Log.d(TAG,"Entré a terminar ");
+ finish();
+ }
+ });
+ }
+
+ private void loadUrl(String url) {
+ progressBar.setVisibility(View.VISIBLE);
+ WebSettings webSettings = webView.getSettings();
+ webSettings.setJavaScriptEnabled(true);
+ webView.setWebChromeClient(new WebChromeClient(){
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ super.onProgressChanged(view, newProgress);
+ progressBar.setProgress(newProgress);
+ if(newProgress == 100){
+ progressBar.setVisibility(View.GONE);
+ getSupportActionBar().setTitle(R.string.app_name);
+ }
+ }
+ }
+ );
+
+ webView.setWebViewClient(new WebViewClient() {
+ public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+ Toast.makeText(WebViewActivity.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ webView.loadUrl(url);
+ webView.setVisibility(View.VISIBLE);
+ }
+}
diff --git a/app/src/main/res/layout/actionbar_toolbar.xml b/app/src/main/res/layout/actionbar_toolbar.xml
index 59cd92c..2644284 100644
--- a/app/src/main/res/layout/actionbar_toolbar.xml
+++ b/app/src/main/res/layout/actionbar_toolbar.xml
@@ -13,16 +13,6 @@
android:layout_height="match_parent"
android:orientation="horizontal"
>
-
-
-
-
+ android:layout_height="match_parent">
+
+
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_web_view.xml b/app/src/main/res/layout/activity_web_view.xml
new file mode 100644
index 0000000..ced8d84
--- /dev/null
+++ b/app/src/main/res/layout/activity_web_view.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/cardview_news.xml b/app/src/main/res/layout/cardview_news.xml
index bbfb22a..acf90dd 100644
--- a/app/src/main/res/layout/cardview_news.xml
+++ b/app/src/main/res/layout/cardview_news.xml
@@ -20,7 +20,7 @@
@@ -36,14 +36,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimaryLight"
- android:textSize="20sp"
+ android:textSize="@dimen/primary_text_cardv"
/>
diff --git a/app/src/main/res/layout/fragment_news_list.xml b/app/src/main/res/layout/fragment_news_list.xml
new file mode 100644
index 0000000..5b69331
--- /dev/null
+++ b/app/src/main/res/layout/fragment_news_list.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/navigation_menu.xml b/app/src/main/res/menu/navigation_menu.xml
new file mode 100644
index 0000000..81d516b
--- /dev/null
+++ b/app/src/main/res/menu/navigation_menu.xml
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 943e4e8..83ad343 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1,5 +1,16 @@
Gaming News
- Image from this news
+ Imagen de la noticia
+ All
+ PS4
+ Xbox One
+ Nintendo Switch
+ PC
+ Abrir navigation drawer
+ Cerrar navigation drawer
+ Cargando...
+ No se obtuvieron todos los artículos de un sitio...
+ Revisa tu conexión a internet
+ Aún se esta recargando.
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index aa1e51c..0b9c0ba 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -2,4 +2,9 @@
12dp
12dp
+ 10sp
+ 20sp
+ 300dp
+ 10dp
+ 16dp
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8d413af..3251a4a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,4 +1,18 @@
Gaming News
Image from this news
+ All
+ PS4
+ Xbox One
+ Nintendo Switch
+ PC
+ Open navigation drawer
+ Close navigation drawer
+
+
+ Hello blank fragment
+ Loading...
+ Can\'t get all articles from sites...
+ Check your internet connection
+ App is still refreshing