From: gumartinm Date: Tue, 24 Apr 2012 06:59:45 +0000 (+0200) Subject: Android lists: nice example. X-Git-Url: https://git.gumartinm.name/?a=commitdiff_plain;h=017ac12a651d9713b88d203b35790aab43dd84ad;p=JavaForFun Android lists: nice example. From: http://www.learn-android.com/2011/11/22/lots-of-lists-custom-adapter/ --- diff --git a/Android/Lists/AndroidManifest.xml b/Android/Lists/AndroidManifest.xml new file mode 100644 index 0000000..222741d --- /dev/null +++ b/Android/Lists/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/Lists/gen/de/example/lists/BuildConfig.java b/Android/Lists/gen/de/example/lists/BuildConfig.java new file mode 100644 index 0000000..3e4ca63 --- /dev/null +++ b/Android/Lists/gen/de/example/lists/BuildConfig.java @@ -0,0 +1,6 @@ +/** Automatically generated file. DO NOT MODIFY */ +package de.example.lists; + +public final class BuildConfig { + public final static boolean DEBUG = true; +} \ No newline at end of file diff --git a/Android/Lists/gen/de/example/lists/R.java b/Android/Lists/gen/de/example/lists/R.java new file mode 100644 index 0000000..dca0664 --- /dev/null +++ b/Android/Lists/gen/de/example/lists/R.java @@ -0,0 +1,33 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package de.example.lists; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int ic_launcher=0x7f020000; + public static final int news_icon_1=0x7f020001; + public static final int news_icon_2=0x7f020002; + } + public static final class id { + public static final int list=0x7f050000; + public static final int news_entry_icon=0x7f050001; + public static final int news_entry_subtitle=0x7f050003; + public static final int news_entry_title=0x7f050002; + } + public static final class layout { + public static final int main=0x7f030000; + public static final int news_entry_list_item=0x7f030001; + } + public static final class string { + public static final int app_name=0x7f040001; + public static final int desc=0x7f040002; + public static final int hello=0x7f040000; + } +} diff --git a/Android/Lists/proguard-project.txt b/Android/Lists/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/Android/Lists/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/Android/Lists/project.properties b/Android/Lists/project.properties new file mode 100644 index 0000000..0840b4a --- /dev/null +++ b/Android/Lists/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-15 diff --git a/Android/Lists/res/drawable-hdpi/ic_launcher.png b/Android/Lists/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/Android/Lists/res/drawable-hdpi/ic_launcher.png differ diff --git a/Android/Lists/res/drawable-ldpi/ic_launcher.png b/Android/Lists/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000..9923872 Binary files /dev/null and b/Android/Lists/res/drawable-ldpi/ic_launcher.png differ diff --git a/Android/Lists/res/drawable-mdpi/ic_launcher.png b/Android/Lists/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/Android/Lists/res/drawable-mdpi/ic_launcher.png differ diff --git a/Android/Lists/res/drawable-mdpi/news_icon_1.png b/Android/Lists/res/drawable-mdpi/news_icon_1.png new file mode 100644 index 0000000..f7afc6f Binary files /dev/null and b/Android/Lists/res/drawable-mdpi/news_icon_1.png differ diff --git a/Android/Lists/res/drawable-mdpi/news_icon_2.png b/Android/Lists/res/drawable-mdpi/news_icon_2.png new file mode 100644 index 0000000..d2921c3 Binary files /dev/null and b/Android/Lists/res/drawable-mdpi/news_icon_2.png differ diff --git a/Android/Lists/res/drawable-xhdpi/ic_launcher.png b/Android/Lists/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/Android/Lists/res/drawable-xhdpi/ic_launcher.png differ diff --git a/Android/Lists/res/layout/main.xml b/Android/Lists/res/layout/main.xml new file mode 100644 index 0000000..dd5ea07 --- /dev/null +++ b/Android/Lists/res/layout/main.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/Android/Lists/res/layout/news_entry_list_item.xml b/Android/Lists/res/layout/news_entry_list_item.xml new file mode 100644 index 0000000..3c3d3bf --- /dev/null +++ b/Android/Lists/res/layout/news_entry_list_item.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/Lists/res/values/strings.xml b/Android/Lists/res/values/strings.xml new file mode 100644 index 0000000..a3e87a0 --- /dev/null +++ b/Android/Lists/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + Hello World, ListActivityActivity! + ListActivity + description + + \ No newline at end of file diff --git a/Android/Lists/src/de/example/lists/ListActivityActivity.java b/Android/Lists/src/de/example/lists/ListActivityActivity.java new file mode 100644 index 0000000..2c5902b --- /dev/null +++ b/Android/Lists/src/de/example/lists/ListActivityActivity.java @@ -0,0 +1,49 @@ +package de.example.lists; + +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import android.app.Activity; +import android.os.Bundle; +import android.widget.ListView; + +public class ListActivityActivity extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + // Setup the list view + final ListView newsEntryListView = (ListView) findViewById(R.id.list); + final NewsEntryAdapter newsEntryAdapter = new NewsEntryAdapter(this, R.layout.news_entry_list_item); + newsEntryListView.setAdapter(newsEntryAdapter); + + // Populate the list, through the adapter + for(final NewsEntry entry : getNewsEntries()) { + newsEntryAdapter.add(entry); + } + } + + private List getNewsEntries() { + + // Let's setup some test data. + // Normally this would come from some asynchronous fetch into a data source + // such as a sqlite database, or an HTTP request + + final List entries = new ArrayList(); + + for(int i = 1; i < 50; i++) { + entries.add( + new NewsEntry( + "Test Entry " + i, + "Anonymous Author " + i, + new GregorianCalendar(2011, 11, i).getTime(), + i % 2 == 0 ? R.drawable.news_icon_1 : R.drawable.news_icon_2 + ) + ); + } + + return entries; + } +} \ No newline at end of file diff --git a/Android/Lists/src/de/example/lists/NewsEntry.java b/Android/Lists/src/de/example/lists/NewsEntry.java new file mode 100644 index 0000000..51728ab --- /dev/null +++ b/Android/Lists/src/de/example/lists/NewsEntry.java @@ -0,0 +1,51 @@ +package de.example.lists; + +import java.util.Date; + +/** + * Encapsulates information about a news entry + */ +public final class NewsEntry { + + private final String title; + private final String author; + private final Date postDate; + private final int icon; + + public NewsEntry(final String title, final String author, + final Date postDate, final int icon) { + this.title = title; + this.author = author; + this.postDate = postDate; + this.icon = icon; + } + + /** + * @return Title of news entry + */ + public String getTitle() { + return title; + } + + /** + * @return Author of news entry + */ + public String getAuthor() { + return author; + } + + /** + * @return Post date of news entry + */ + public Date getPostDate() { + return postDate; + } + + /** + * @return Icon of this news entry + */ + public int getIcon() { + return icon; + } + +} diff --git a/Android/Lists/src/de/example/lists/NewsEntryAdapter.java b/Android/Lists/src/de/example/lists/NewsEntryAdapter.java new file mode 100644 index 0000000..05b26d0 --- /dev/null +++ b/Android/Lists/src/de/example/lists/NewsEntryAdapter.java @@ -0,0 +1,102 @@ +package de.example.lists; + +import android.widget.ArrayAdapter; +import java.text.DateFormat; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +/** + * Adapts NewsEntry objects onto views for lists + */ +public final class NewsEntryAdapter extends ArrayAdapter { + + private final int newsItemLayoutResource; + + public NewsEntryAdapter(final Context context, final int newsItemLayoutResource) { + super(context, 0); + this.newsItemLayoutResource = newsItemLayoutResource; + } + + @Override + public View getView(final int position, final View convertView, final ViewGroup parent) { + + // We need to get the best view (re-used if possible) and then + // retrieve its corresponding ViewHolder, which optimizes lookup efficiency + final View view = getWorkingView(convertView); + final ViewHolder viewHolder = getViewHolder(view); + final NewsEntry entry = getItem(position); + + // Setting the title view is straightforward + viewHolder.titleView.setText(entry.getTitle()); + + // Setting the subTitle view requires a tiny bit of formatting + final String formattedSubTitle = String.format("By %s on %s", + entry.getAuthor(), + DateFormat.getDateInstance(DateFormat.SHORT).format(entry.getPostDate()) + ); + + viewHolder.subTitleView.setText(formattedSubTitle); + + // Setting image view is also simple + viewHolder.imageView.setImageResource(entry.getIcon()); + + return view; + } + + private View getWorkingView(final View convertView) { + // The workingView is basically just the convertView re-used if possible + // or inflated new if not possible + View workingView = null; + + if(null == convertView) { + final Context context = getContext(); + final LayoutInflater inflater = (LayoutInflater)context.getSystemService + (Context.LAYOUT_INFLATER_SERVICE); + + workingView = inflater.inflate(newsItemLayoutResource, null); + } else { + workingView = convertView; + } + + return workingView; + } + + private ViewHolder getViewHolder(final View workingView) { + // The viewHolder allows us to avoid re-looking up view references + // Since views are recycled, these references will never change + final Object tag = workingView.getTag(); + ViewHolder viewHolder = null; + + + if(null == tag || !(tag instanceof ViewHolder)) { + viewHolder = new ViewHolder(); + + viewHolder.titleView = (TextView) workingView.findViewById(R.id.news_entry_title); + viewHolder.subTitleView = (TextView) workingView.findViewById(R.id.news_entry_subtitle); + viewHolder.imageView = (ImageView) workingView.findViewById(R.id.news_entry_icon); + + workingView.setTag(viewHolder); + + } else { + viewHolder = (ViewHolder) tag; + } + + return viewHolder; + } + + /** + * ViewHolder allows us to avoid re-looking up view references + * Since views are recycled, these references will never change + */ + private static class ViewHolder { + public TextView titleView; + public TextView subTitleView; + public ImageView imageView; + } + + +}