Created
March 5, 2017 13:05
-
-
Save IsabelManiega/100db2a04350352a3c6a0ae08733ad26 to your computer and use it in GitHub Desktop.
News Feed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context="com.example.isa.newsfeed.MainActivity"> | |
<android.support.v4.widget.SwipeRefreshLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/swiperefresh" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<ListView | |
android:id="@+id/list_view" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:scrollbars="none"> | |
</ListView> | |
</android.support.v4.widget.SwipeRefreshLayout> | |
</RelativeLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.example.isa.newsfeed"> | |
<uses-permission android:name="android.permission.INTERNET"/> | |
<application | |
android:allowBackup="true" | |
android:icon="@mipmap/ic_launcher" | |
android:label="@string/app_name" | |
android:supportsRtl="true" | |
android:theme="@style/AppTheme"> | |
<activity android:name=".MainActivity"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
</activity> | |
</application> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:orientation="vertical" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="horizontal"> | |
<TextView | |
android:id="@+id/date" | |
tools:text="Sep 22, 2016" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
style="@style/date"/> | |
<TextView | |
android:id="@+id/section" | |
tools:text="Development" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_weight="1" | |
style="@style/section"/> | |
</LinearLayout> | |
<TextView | |
android:id="@+id/author" | |
tools:text="Max Mustermann" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
style="@style/author" /> | |
<TextView | |
android:id="@+id/title" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
tools:text="This is going to be a long headline, I'm sure." | |
style="@style/title"/> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.isa.newsfeed; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.os.Bundle; | |
import android.support.v4.app.LoaderManager; | |
import android.support.v4.content.Loader; | |
import android.support.v4.widget.SwipeRefreshLayout; | |
import android.support.v7.app.AppCompatActivity; | |
import android.view.View; | |
import android.widget.AdapterView; | |
import android.widget.ListView; | |
import java.util.List; | |
public class MainActivity extends AppCompatActivity | |
implements LoaderManager.LoaderCallbacks<List<News>>, SwipeRefreshLayout.OnRefreshListener { | |
private NewsAdapter adapter; | |
private static int LOADER_ID = 0; | |
SwipeRefreshLayout swipe; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
swipe = (SwipeRefreshLayout) findViewById(R.id.swiperefresh); | |
swipe.setOnRefreshListener(this); | |
swipe.setColorSchemeColors(getResources().getColor(R.color.colorAccent)); | |
ListView listView = (ListView) findViewById(R.id.list_view); | |
adapter = new NewsAdapter(this); | |
listView.setAdapter(adapter); | |
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |
@Override | |
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { | |
News news = adapter.getItem(i); | |
String url = news.url; | |
Intent intent = new Intent(Intent.ACTION_VIEW); | |
intent.setData(Uri.parse(url)); | |
startActivity(intent); | |
} | |
}); | |
getSupportLoaderManager().initLoader(LOADER_ID, null, this); | |
} | |
@Override | |
public Loader<List<News>> onCreateLoader(int id, Bundle args) { | |
return new NewsLoader(this); | |
} | |
@Override | |
public void onLoadFinished(Loader<List<News>> loader, List<News> data) { | |
swipe.setRefreshing(false); | |
if (data != null) { | |
adapter.setNotifyOnChange(false); | |
adapter.clear(); | |
adapter.setNotifyOnChange(true); | |
adapter.addAll(data); | |
} | |
} | |
@Override | |
public void onLoaderReset(Loader<List<News>> loader) { | |
} | |
@Override | |
public void onRefresh() { | |
getSupportLoaderManager().restartLoader(LOADER_ID, null, this); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.isa.newsfeed; | |
public class News{ | |
String title; | |
String author; | |
String url; | |
String date; | |
String section; | |
public News(String title, String author, String url, String date, String section) { | |
this.title = title; | |
this.author = author; | |
this.url = url; | |
this.date = date; | |
this.section = section; | |
} | |
public String getTitle() { | |
return title; | |
} | |
public void setTitle(String title) { | |
this.title = title; | |
} | |
public String getAuthor() { | |
return author; | |
} | |
public void setAuthor(String author) { | |
this.author = author; | |
} | |
public String getUrl() { | |
return url; | |
} | |
public void setUrl(String url) { | |
this.url = url; | |
} | |
public String getDate() { | |
return date; | |
} | |
public void setDate(String date) { | |
this.date = date; | |
} | |
public String getSection() { | |
return section; | |
} | |
public void setSection(String section) { | |
this.section = section; | |
} | |
@Override | |
public String toString() { | |
return "News{" + | |
"title='" + title + '\'' + | |
", author='" + author + '\'' + | |
", url='" + url + '\'' + | |
", date='" + date + '\'' + | |
", section='" + section + '\'' + | |
'}'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.isa.newsfeed; | |
import android.content.Context; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ArrayAdapter; | |
import android.widget.TextView; | |
import java.util.ArrayList; | |
public class NewsAdapter extends ArrayAdapter<News>{ | |
public NewsAdapter(Context context) { | |
super(context, -1, new ArrayList<News>()); | |
} | |
@Override | |
public View getView(int position, View convertView, ViewGroup parent) { | |
if (convertView == null) { | |
convertView | |
= LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false); | |
} | |
TextView title = (TextView) convertView.findViewById(R.id.title); | |
TextView author = (TextView) convertView.findViewById(R.id.author); | |
TextView date = (TextView) convertView.findViewById(R.id.date); | |
TextView section = (TextView) convertView.findViewById(R.id.section); | |
News currentNews = getItem(position); | |
title.setText(currentNews.getTitle()); | |
author.setText(currentNews.getAuthor()); | |
date.setText(currentNews.getDate()); | |
section.setText(currentNews.getSection()); | |
return convertView; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.isa.newsfeed; | |
import android.content.Context; | |
import android.support.v4.content.AsyncTaskLoader; | |
import android.util.Log; | |
import java.io.IOException; | |
import java.net.URL; | |
import java.util.List; | |
/** | |
* Created by ISA on 04/03/2017. | |
*/ | |
public class NewsLoader extends AsyncTaskLoader<List<News>> { | |
public NewsLoader(Context context) { | |
super(context); | |
} | |
@Override | |
protected void onStartLoading() { | |
super.onStartLoading(); | |
forceLoad(); | |
} | |
@Override | |
public List<News> loadInBackground() { | |
List<News> listOfNews = null; | |
try { | |
URL url = QueryUtils.createUrl(); | |
String jsonResponse = QueryUtils.makeHttpRequest(url); | |
listOfNews = QueryUtils.parseJson(jsonResponse); | |
} catch (IOException e) { | |
Log.e("Queryutils", "Error Loader LoadInBackground: ", e); | |
} | |
return listOfNews; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.isa.newsfeed; | |
import android.net.Uri; | |
import android.util.Log; | |
import org.json.JSONArray; | |
import org.json.JSONException; | |
import org.json.JSONObject; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.net.HttpURLConnection; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import java.nio.charset.Charset; | |
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.List; | |
import java.util.Locale; | |
/** | |
* Created by ISA on 04/03/2017. | |
*/ | |
public class QueryUtils { | |
static String createStringUrl() { | |
Uri.Builder builder = new Uri.Builder(); | |
builder.scheme("http") | |
.encodedAuthority("content.guardianapis.com") | |
.appendPath("search") | |
.appendQueryParameter("order-by", "newest") | |
.appendQueryParameter("show-references", "author") | |
.appendQueryParameter("show-tags", "contributor") | |
.appendQueryParameter("q", "Android") | |
.appendQueryParameter("api-key", "test"); | |
String url = builder.build().toString(); | |
return url; | |
} | |
static URL createUrl() { | |
String stringUrl = createStringUrl(); | |
try { | |
return new URL(stringUrl); | |
} catch (MalformedURLException e) { | |
Log.e("Queryutils", "Error creating URL: ", e); | |
return null; | |
} | |
} | |
private static String formatDate(String rawDate) { | |
String jsonDatePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'"; | |
SimpleDateFormat jsonFormatter = new SimpleDateFormat(jsonDatePattern, Locale.US); | |
try { | |
Date parsedJsonDate = jsonFormatter.parse(rawDate); | |
String finalDatePattern = "MMM d, yyy"; | |
SimpleDateFormat finalDateFormatter = new SimpleDateFormat(finalDatePattern, Locale.US); | |
return finalDateFormatter.format(parsedJsonDate); | |
} catch (ParseException e) { | |
Log.e("QueryUtils", "Error parsing JSON date: ", e); | |
return ""; | |
} | |
} | |
static String makeHttpRequest(URL url) throws IOException { | |
String jsonResponse = ""; | |
if (url == null){ | |
return jsonResponse; | |
} | |
HttpURLConnection urlConnection = null; | |
InputStream inputStream = null; | |
try { | |
urlConnection = (HttpURLConnection) url.openConnection(); | |
urlConnection.setRequestMethod("GET"); | |
urlConnection.setReadTimeout(10000 /* milliseconds */); | |
urlConnection.setConnectTimeout(15000 /* milliseconds */); | |
urlConnection.connect(); | |
if (urlConnection.getResponseCode() == 200){ | |
inputStream = urlConnection.getInputStream(); | |
jsonResponse = readFromStream(inputStream); | |
} else { | |
Log.e("mainActivity", "Error response code: " + urlConnection.getResponseCode()); | |
} | |
} catch (IOException e) { | |
Log.e("Queryutils", "Error making HTTP request: ", e); | |
} finally { | |
if (urlConnection != null) { | |
urlConnection.disconnect(); | |
} | |
if (inputStream != null) { | |
inputStream.close(); | |
} | |
} | |
return jsonResponse; | |
} | |
private static String readFromStream(InputStream inputStream) throws IOException { | |
StringBuilder output = new StringBuilder(); | |
if (inputStream != null) { | |
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8")); | |
BufferedReader reader = new BufferedReader(inputStreamReader); | |
String line = reader.readLine(); | |
while (line != null) { | |
output.append(line); | |
line = reader.readLine(); | |
} | |
} | |
return output.toString(); | |
} | |
static List<News> parseJson(String response) { | |
ArrayList<News> listOfNews = new ArrayList<>(); | |
try { | |
JSONObject jsonResponse = new JSONObject(response); | |
JSONObject jsonResults = jsonResponse.getJSONObject("response"); | |
JSONArray resultsArray = jsonResults.getJSONArray("results"); | |
for (int i = 0; i < resultsArray.length(); i++) { | |
JSONObject oneResult = resultsArray.getJSONObject(i); | |
String webTitle = oneResult.getString("webTitle"); | |
String url = oneResult.getString("webUrl"); | |
String date = oneResult.getString("webPublicationDate"); | |
date = formatDate(date); | |
String section = oneResult.getString("sectionName"); | |
JSONArray tagsArray = oneResult.getJSONArray("tags"); | |
String author = ""; | |
if (tagsArray.length() == 0) { | |
author = null; | |
} else { | |
for (int j = 0; j < tagsArray.length(); j++) { | |
JSONObject firstObject = tagsArray.getJSONObject(j); | |
author += firstObject.getString("webTitle") + ". "; | |
} | |
} | |
listOfNews.add(new News(webTitle, author, url, date, section)); | |
} | |
} catch (JSONException e) { | |
Log.e("Queryutils", "Error parsing JSON response", e); | |
} | |
return listOfNews; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<resources> | |
<!-- Base application theme. --> | |
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | |
<!-- Customize your theme here. --> | |
<item name="colorPrimary">@color/colorPrimary</item> | |
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> | |
<item name="colorAccent">@color/colorAccent</item> | |
</style> | |
<style name="title" parent="Base.TextAppearance.AppCompat.Large"> | |
<item name="android:layout_marginBottom">8dp</item> | |
<item name="android:layout_marginTop">6dp</item> | |
<item name="android:layout_marginLeft">16dp</item> | |
<item name="android:layout_marginRight">16dp</item> | |
</style> | |
<style name="author" parent="Base.TextAppearance.AppCompat.Small"> | |
<item name="android:layout_marginBottom">8dp</item> | |
<item name="android:layout_marginLeft">16dp</item> | |
<item name="android:layout_marginRight">16dp</item> | |
</style> | |
<style name="date" parent="Base.TextAppearance.AppCompat.Small"> | |
<item name="android:layout_marginBottom">8dp</item> | |
<item name="android:layout_marginLeft">16dp</item> | |
<item name="android:layout_marginTop">16dp</item> | |
</style> | |
<style name="section" parent="Base.TextAppearance.AppCompat.Small"> | |
<item name="android:gravity">right</item> | |
<item name="android:layout_marginTop">16dp</item> | |
<item name="android:layout_marginBottom">8dp</item> | |
<item name="android:layout_marginRight">16dp</item> | |
</style> | |
</resources> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment