diff --git a/HW5/AndroidManifest.xml b/HW5/AndroidManifest.xml index b8a6f7c..d8f05a2 100644 --- a/HW5/AndroidManifest.xml +++ b/HW5/AndroidManifest.xml @@ -1,4 +1,4 @@ - + - + android:targetSdkVersion="18" /> + + + + diff --git a/HW5/res/drawable/add_bookmark.png b/HW5/res/drawable/add_bookmark.png new file mode 100644 index 0000000..a42453d Binary files /dev/null and b/HW5/res/drawable/add_bookmark.png differ diff --git a/HW5/res/drawable/not_retweeted.png b/HW5/res/drawable/not_retweeted.png new file mode 100644 index 0000000..6b370ef Binary files /dev/null and b/HW5/res/drawable/not_retweeted.png differ diff --git a/HW5/res/drawable/profile_twitter.png b/HW5/res/drawable/profile_twitter.png new file mode 100644 index 0000000..9c67019 Binary files /dev/null and b/HW5/res/drawable/profile_twitter.png differ diff --git a/HW5/res/drawable/retweeted.png b/HW5/res/drawable/retweeted.png new file mode 100644 index 0000000..52720c7 Binary files /dev/null and b/HW5/res/drawable/retweeted.png differ diff --git a/HW5/res/layout/activity_tweets_list.xml b/HW5/res/layout/activity_tweets_list.xml new file mode 100644 index 0000000..905f1b9 --- /dev/null +++ b/HW5/res/layout/activity_tweets_list.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/HW5/res/layout/tweet_list.xml b/HW5/res/layout/tweet_list.xml new file mode 100644 index 0000000..666eb7e --- /dev/null +++ b/HW5/res/layout/tweet_list.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HW5/res/menu/tweets_list.xml b/HW5/res/menu/tweets_list.xml new file mode 100644 index 0000000..d122a4b --- /dev/null +++ b/HW5/res/menu/tweets_list.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/HW5/res/values/strings.xml b/HW5/res/values/strings.xml index 759b9b7..2418083 100644 --- a/HW5/res/values/strings.xml +++ b/HW5/res/values/strings.xml @@ -1,8 +1,9 @@ - + HW5 Settings Hello world! + TweetsListActivity diff --git a/HW5/src/edu/uncc/itcs4180/hw5/BitmapDownloader.java b/HW5/src/edu/uncc/itcs4180/hw5/BitmapDownloader.java new file mode 100644 index 0000000..2702ac4 --- /dev/null +++ b/HW5/src/edu/uncc/itcs4180/hw5/BitmapDownloader.java @@ -0,0 +1,51 @@ +package edu.uncc.itcs4180.hw5; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.widget.ImageView; + +public class BitmapDownloader extends AsyncTask { + ImageView iv; + Bitmap downloaded; + + public BitmapDownloader(ImageView iv) { + this.iv = iv; + } + + @Override + protected Void doInBackground(String... params) { + downloaded = downloadBitmap(params[0]); + return null; + } + + private Bitmap downloadBitmap(String sUrl) { + try { + URL url = new URL(sUrl); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.connect(); + if (con.getResponseCode() == 200) { + return BitmapFactory.decodeStream(con.getInputStream()); + } + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return null; + } + + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + iv.setImageBitmap(downloaded); + } +} diff --git a/HW5/src/edu/uncc/itcs4180/hw5/MainActivity.java b/HW5/src/edu/uncc/itcs4180/hw5/MainActivity.java index 7567719..a523aa8 100644 --- a/HW5/src/edu/uncc/itcs4180/hw5/MainActivity.java +++ b/HW5/src/edu/uncc/itcs4180/hw5/MainActivity.java @@ -9,6 +9,7 @@ import edu.uncc.itcs4180.hw5.twitter.TweetList; import edu.uncc.itcs4180.hw5.twitter.TwitterClient; import android.os.Bundle; import android.app.Activity; +import android.content.Intent; import android.util.Log; import android.view.Menu; import android.view.View; @@ -46,6 +47,19 @@ public class MainActivity extends Activity { ListView feeds = (ListView)findViewById(R.id.listNewsFeeds); ListAdapter adapter = new ArrayAdapter(this, R.layout.news_site, R.id.txtSiteName, newsSitesTitles); feeds.setAdapter(adapter); + feeds.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, + long id) { + String key = ((TextView)view.findViewById(R.id.txtSiteName)).getText().toString(); + String handle = newsSites.get(key); + // Shenanigans to get the parent instance + // http://stackoverflow.com/questions/2076037/inside-onclicklistener-i-cannot-access-a-lot-of-things-how-to-approach + Intent i = new Intent(MainActivity.this, TweetsListActivity.class); + i.putExtra("handle", handle); + startActivity(i); + } + }); } @Override @@ -64,16 +78,4 @@ public class MainActivity extends Activity { Toast.makeText(this, "All Saved News are Cleared!", Toast.LENGTH_SHORT).show(); } - private class FeedListener implements OnItemClickListener { - - @Override - public void onItemClick(AdapterView parent, View view, int position, - long id) { - String key = ((TextView)view.findViewById(R.id.txtSiteName)).getText().toString(); - String handle = newsSites.get(key); - - } - - } - } diff --git a/HW5/src/edu/uncc/itcs4180/hw5/TweetListAdapter.java b/HW5/src/edu/uncc/itcs4180/hw5/TweetListAdapter.java new file mode 100644 index 0000000..ab1369e --- /dev/null +++ b/HW5/src/edu/uncc/itcs4180/hw5/TweetListAdapter.java @@ -0,0 +1,88 @@ +package edu.uncc.itcs4180.hw5; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.http.HttpConnection; + +import edu.uncc.itcs4180.hw5.twitter.Tweet; +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +public class TweetListAdapter extends ArrayAdapter { + private final int TWEET_TAG_KEY = 1337; + Activity activity; + Tweet[] tweets; + + public TweetListAdapter(Activity activity, Tweet[] tweets) { + super(activity, R.layout.tweet_list, tweets); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View rowView = convertView; + TweetView tv = null; + Tweet tweet = tweets[position]; + + if (rowView == null) { + // Inflate a new row + rowView = activity.getLayoutInflater().inflate(R.layout.tweet_list, null); + + tv = new TweetView(); + tv.imgProfileImage = (ImageView) rowView.findViewById(R.id.imgProfileImage); + tv.txtTweetText = (TextView) rowView.findViewById(R.id.txtTweetText); + tv.txtTweetInfo = (TextView) rowView.findViewById(R.id.txtTweetInfo); + tv.imgIsRetweet = (ImageView) rowView.findViewById(R.id.imgIsRetweet); + tv.ibtnSaveTweet = (ImageButton) rowView.findViewById(R.id.ibtnSaveTweet); + + rowView.setTag(tv); + rowView.setTag(TWEET_TAG_KEY, tweet); + } else { + tv = (TweetView) rowView.getTag(); + } + + // Add information to the current row + // Start up our BitmapDownloader - it will update the ImageView for us + new BitmapDownloader(tv.imgProfileImage).execute(tweet.getUser().getProfileImageUrl()); + tv.txtTweetText.setText(tweet.getText()); + tv.txtTweetInfo.setText(tweet.getDateCreated()); + // Set the retweet image + if (tweet.isRetweet()) { + tv.imgIsRetweet.setImageDrawable(activity.getResources().getDrawable(R.drawable.retweeted)); + } + // Save tweets when we are clicked + tv.ibtnSaveTweet.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + saveTweet((Tweet)v.getTag(TWEET_TAG_KEY)); + } + }); + + return rowView; + } + + protected static class TweetView { + ImageView imgProfileImage; + TextView txtTweetText; + TextView txtTweetInfo; + ImageView imgIsRetweet; + ImageButton ibtnSaveTweet; + } + + private void saveTweet(Tweet t) { + // TODO: Save tweets here. + Toast.makeText(activity, "Saved in DB!", Toast.LENGTH_SHORT).show(); + } + +} diff --git a/HW5/src/edu/uncc/itcs4180/hw5/TweetsListActivity.java b/HW5/src/edu/uncc/itcs4180/hw5/TweetsListActivity.java new file mode 100644 index 0000000..5f5a1c2 --- /dev/null +++ b/HW5/src/edu/uncc/itcs4180/hw5/TweetsListActivity.java @@ -0,0 +1,53 @@ +package edu.uncc.itcs4180.hw5; + +import edu.uncc.itcs4180.hw5.twitter.TweetList; +import edu.uncc.itcs4180.hw5.twitter.TwitterClient; +import android.os.AsyncTask; +import android.os.Bundle; +import android.app.Activity; +import android.app.ProgressDialog; +import android.util.Log; +import android.view.Menu; + +public class TweetsListActivity extends Activity { + + ProgressDialog dialog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_tweets_list); + + // Fetch our tweets + String handle = getIntent().getExtras().getString("handle"); + + dialog = new ProgressDialog(this); + dialog.setCancelable(false); + dialog.setMessage("Downloading tweets for: " + handle); + dialog.show(); + + // For whatever reason, we have to call the TwitterClient downloader ourselves. + // AsyncTask inside AsyncTask simply doesn't work. This leads to an ugly double-new, + // despite me trying to write a nice clean API. + // Also, totally didn't know Java syntax allowed me to do this. + new TwitterClient().new TweetListDownloader(){ + @Override + protected void onPostExecute(TweetList result) { + displayTweets(result); + dialog.cancel(); + }; + }.execute(handle); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.tweets_list, menu); + return true; + } + + private void displayTweets(TweetList list) { + + } + +} diff --git a/HW5/src/edu/uncc/itcs4180/hw5/twitter/Tweet.java b/HW5/src/edu/uncc/itcs4180/hw5/twitter/Tweet.java index b7f66e3..a60bae7 100644 --- a/HW5/src/edu/uncc/itcs4180/hw5/twitter/Tweet.java +++ b/HW5/src/edu/uncc/itcs4180/hw5/twitter/Tweet.java @@ -29,6 +29,9 @@ public class Tweet { @SerializedName("user") private TwitterUser user; + + @SerializedName("retweeted") + private boolean retweeted; public String getDateCreated() { return dateCreated; @@ -85,6 +88,14 @@ public class Tweet { public TwitterUser getUser() { return user; } + + public boolean isRetweet() { + return retweeted; + } + + public void setRetweet(boolean retweeted) { + this.retweeted = retweeted; + } @Override public String toString() { diff --git a/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterClient.java b/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterClient.java index 8e205e0..3dbab5e 100644 --- a/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterClient.java +++ b/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterClient.java @@ -47,7 +47,7 @@ public class TwitterClient { return null; } - private class TweetListDownloader extends AsyncTask { + public class TweetListDownloader extends AsyncTask { @Override protected TweetList doInBackground(String... params) { diff --git a/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterUser.java b/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterUser.java index bbae277..d9fce86 100644 --- a/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterUser.java +++ b/HW5/src/edu/uncc/itcs4180/hw5/twitter/TwitterUser.java @@ -15,6 +15,9 @@ public class TwitterUser { @SerializedName("profile_image_url") private String profileImageUrl; + + @SerializedName("profile_background_image_url") + private String profileBackgroundImageUrl; public String getProfileImageUrl() { return profileImageUrl; @@ -39,4 +42,12 @@ public class TwitterUser { public void setName(String name) { this.name = name; } + + public String getProfileBackgroundImageUrl() { + return profileBackgroundImageUrl; + } + + public void setProfileBackgroundImageUrl(String profileBackgroundImageUrl) { + this.profileBackgroundImageUrl = profileBackgroundImageUrl; + } } \ No newline at end of file