package gui.simpleUI; import java.util.List; import android.app.Activity; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListAdapter; import android.widget.ListView; /** * This class is a subclass of {@link BaseAdapter} and allows to create a simple * to use {@link ListAdapter} for any {@link ListView}. Updates in the list will * be detected by the adapter automatically, so the list can be used as usual * * <br> * * The items in the list have to implement the {@link HasItsOwnView} interface. * This allows much more flexible {@link ListView} designs with custom UI for * each list element. * * @author Spobo * */ public class SimpleBaseAdapter extends BaseAdapter { public interface HasItsOwnView { /** * @param context * This object is needed to create new views * @param convertView * it might be possible to use this view if it is not null * and the correct type * @param parent * the parent view the item view will be contained in. The * item view does not have to be added to the parent manually * @param simpleBaseAdapter * if the displayed list is changed call * {@link SimpleBaseAdapter#notifyDataSetChanged()} * @param containerList * the list where the item is contained in * @param positionInList * the position in the list * @return */ public View getView(Context context, View convertView, ViewGroup parent, SimpleBaseAdapter simpleBaseAdapter, List<HasItsOwnView> containerList, int positionInList); } private static final int UPDATE_SPEED = 1000; private List<HasItsOwnView> myList; private int oldSize; private boolean keepUpdaterRunning = true; /** * @param activity * if the {@link ListView} should auto-update itself when the * {@link List} is changed pass the {@link Activity} which * displays the {@link ListView}, otherwise if auto-updates are * not necessary because the list does not change or the notify * method of the adapter is called manually on each change pass * null * @param listToDisplay * the {@link List} that should be displayed */ public SimpleBaseAdapter(final Activity activity, List<HasItsOwnView> listToDisplay) { myList = listToDisplay; if (activity != null) createAutoUpdaterForTheListAdapter(activity); } /** * call this method when the auto-update thread should be stopped */ public void stopAutoUpdatesOfTheListView() { keepUpdaterRunning = false; } private void createAutoUpdaterForTheListAdapter(final Activity a) { new Thread(new Runnable() { @Override public void run() { while (keepUpdaterRunning) { try { Thread.sleep(UPDATE_SPEED); a.runOnUiThread(new Runnable() { @Override public void run() { try { refreshCount(myList.size()); } catch (Exception e) { keepUpdaterRunning = false; } } }); } catch (InterruptedException e) { keepUpdaterRunning = false; } } } }).start(); } @Override public int getCount() { return refreshCount(myList.size()); } @Override public Object getItem(int position) { refreshCount(myList.size()); return myList.get(position); } @Override public long getItemId(int position) { refreshCount(myList.size()); return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { refreshCount(myList.size()); return myList.get(position).getView(parent.getContext(), convertView, parent, this, myList, position); } /** * This should allow the modification of the adapters list without a manual * call for {@link SimpleBaseAdapter#notifyDataSetChanged()} each time * * @param currentSize * @return the old size if it changed. This is needed for the * {@link SimpleBaseAdapter#getCount()} method! Do not modify! */ private int refreshCount(int currentSize) { if (oldSize != currentSize) { int result = oldSize; oldSize = currentSize; notifyDataSetChanged(); return result; } return currentSize; } }