Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialAlessandro Maculotti
4,954 PointsDisplay an image on a ListView
Hi! I would try to modify the BlogReader App with an Image into the listView. I found this library "CWAC Adapter" by Mark Murphy that do this work. Do you think I should use this library or I should implement a custom view?
6 Answers
Liam Peters
8,792 PointsImplement a custom adapter. it's really simple! Where will you be getting the images from? I have a Github Project where I extend the Simple blog reader to pull down badges. I use a gridview but the adapter for each is the same. Here's the BadgeAdapter class!
Alessandro Maculotti
4,954 PointsOh Thanks! I would get the images from a http request in AsynkTask. So now I will try to implement your class. Thanks so much.
Liam Peters
8,792 PointsPicasso is a fantastic library. You give it the image URL and the imageview that you want the image in and it will lazy load it for you. It will even do local caching so you don't need to worry about any of that! No need to reinvent the wheel!
Neil Quinn
768 PointsWhat adapter would I have to use if I wanted to have thumbnails beside the title and author using JSON?
Alessandro Maculotti
4,954 PointsImplement a custom adapter
SimpleAdapter adapter = new SimpleAdapter(context, date,
R.layout.custom_list, keys, ids);
Create an xml layout file: custom_list.xml like this:
<ImageView
android:id="@+id/thumbRifugio"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginBottom="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:contentDescription="@string/alt"
android:src="@drawable/segnaposto_thumb">
</ImageView>
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
Neil Quinn
768 Pointsso where in my main activity would I put the custom adapter?
public class MainListActivity extends ListActivity {
public static final int NUMBER_OF_POSTS = 20;
public static final String TAG = MainListActivity.class.getSimpleName();
protected JSONObject mBlogData;
protected ProgressBar mProgressBar;
private final String KEY_TITLE = "title";
private final String KEY_DATE = "date";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_list);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
if(NetworkIsAvailable()) {
mProgressBar.setVisibility(View.VISIBLE);
GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
getBlogPostsTask.execute();
}
else {
Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show();
}
//String message = getString(R.string.no_items);
//Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
try {
JSONArray jsonPosts = mBlogData.getJSONArray("posts");
JSONObject jsonPost = jsonPosts.getJSONObject(position);
String blogUrl = jsonPost.getString("url");
Intent intent = new Intent(this,BlogWebViewActivity.class);
intent.setData(Uri.parse(blogUrl));
startActivity(intent);
}
catch (JSONException e) {
logException(e);
}
}
private void logException(Exception e) {
Log.e(TAG, "Exception caught!", e);
}
private boolean NetworkIsAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if(networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
public void handleBlogResponse() {
mProgressBar.setVisibility(View.INVISIBLE);
if (mBlogData == null) {
updateDisplayForError();
}
else {
try {
JSONArray jsonPosts = mBlogData.getJSONArray("posts");
ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < jsonPosts.length(); i++) {
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String date = post.getString(KEY_DATE);
date = Html.fromHtml(date).toString();
HashMap<String, String> blogPost = new HashMap<String, String>();
blogPost.put(KEY_TITLE, title);
blogPost.put(KEY_DATE, date);
blogPosts.add(blogPost);
}
String[] keys = { KEY_TITLE, KEY_DATE };
int[] ids = { android.R.id.text1, android.R.id.text2 };
SimpleAdapter adapter = new SimpleAdapter(this, blogPosts, android.R.layout.simple_list_item_2, keys, ids);
setListAdapter(adapter);
} catch (JSONException e) {
logException(e);
}
}
}
private void updateDisplayForError() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.error_title));
builder.setMessage(getString(R.string.error_message));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
TextView emptyTextView = (TextView) getListView().getEmptyView();
emptyTextView.setText(getString(R.string.no_items));
}
private class GetBlogPostsTask extends AsyncTask<Object, Void, JSONObject> {
@Override
protected JSONObject doInBackground(Object... params) {
int responseCode = -1;
JSONObject jsonResponse = null;
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.ilovelimerick.ie/?json=1&count=");
try {
HttpResponse response = client.execute(httpget);
StatusLine statusLine = response.getStatusLine();
responseCode = statusLine.getStatusCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while((line = reader.readLine()) != null){
builder.append(line);
}
jsonResponse = new JSONObject(builder.toString());
}
else {
Log.i(TAG, String.format("Unsuccessful HTTP response code: %d", responseCode));
}
}
catch (JSONException e) {
logException(e);
}
catch (Exception e) {
logException(e);
}
return jsonResponse;
}
@Override
protected void onPostExecute(JSONObject result) {
mBlogData = result;
handleBlogResponse();
}
}
}
sorry but I am very new to this!
Ben Jakuben
Treehouse TeacherWe cover all this (including Picasso!) in the Build a Self-Destructing Message App project. I think it's stage 7 or so. Check it out! :-)