How to extend an ArrayAdapter?

by craiget » Fri, 10 Apr 2009 23:53:16 GMT


Sponsored Links
 Hello,

I'm running into difficulties overriding an ArrayAdapter to be
displayed in a ListActivity.

The ArrayAdapter is filled asynchronously.

What I'm trying to do is add a special "sentinel" object that sits at
the beginning of the list to show the progress of the computation.
Ultimately this may be a progress bar, but right now I am just using a
TextView as a placeholder.

The problem is that the sentinel seems to get inserted multiple times
into the list - not just once at the beginning. It *seems* to be
appearing once per "page" of list data (so if 8 list items fit on the
screen, my sentinel appears as the 1st, then 9th, then the 17th,
etc..), but that interpretation may not be accurate.

While maybe not how ArrayAdapters were intended to be extended, I
thought something like this should work by simply overriding getView()
to show my custom TextView for index 0:

public class CustomAdapter<E> extends ArrayAdapter<E> {

        private View sentinel;

        public CustomAdapter(Context context, int textViewResourceId, List<E>
objects) {
                super(context, textViewResourceId, objects);
                sentinel = new TextView(context);
                ((TextView)sentinel).setText("Still Loading..");
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
{
                if(position == 0)
                        return sentinel;
                return super.getView(position, convertView, parent);
        }

        public void finish() {
                //called when async list computation finishes
                remove(getItem(0));
        }

}

The adapter is created in the usual way:

...
ArrayList<String> data = new ArrayList<String>();
data.add('****'); //item 0, this should get replaced
adapter = new CustomAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1, data);
adapter.add("Sentinel");
setListAdapter(adapter);
...


My two guesses so far are: 1) When data is added asynchronously,
something goes wrong with redrawing the list view. 2) I'm not
correctly interpreting the "position" parameter of "getView()".

Any suggestions on why this doesn't work?

Thanks for reading folks.

 - C







--~--~---------~--~----~------------~-------~--~----~



How to extend an ArrayAdapter?

by Mark Murphy » Fri, 10 Apr 2009 23:58:11 GMT


 


Try addHeaderView().


You haven't indicated how you are adding stuff to the ArrayAdapter, and
your problem may lie in there.

However, I would use addHeaderView() for this circumstance, or have your
"sentinel" live outside the ListView. Remember: even though you are
using a ListActivity, you can still specify your own layout. You need
the magic android:id for the ListView (@android:id/list) in that case.

-- 
Mark Murphy (a Commons Guy)
 http://commonsware.com  |  http://twitter.com/commonsguy 

_The Busy Coder's Guide to Android Development_ Version 2.0 Available!

--~--~---------~--~----~------------~-------~--~----~


Sponsored Links


How to extend an ArrayAdapter?

by craiget » Sat, 11 Apr 2009 00:28:35 GMT


 Fantastic. listView.addHeaderView() works like a charm!

It seems this usage was already thought of by folks more clever than
myself. I guess it helps to know the API =)

Thanks Mark.







--~--~---------~--~----~------------~-------~--~----~



Other Threads

1. Problems with SSL Socket connection

I have socket based Transport. SSL cerificate also is in use in this
case.
I use this transport from standart Swing client - works fine. When I
try set it up to
Android application bacame following Exception :

05-27 08:31:24.332: WARN/System.err(223):
java.security.NoSuchAlgorithmException: SSLContext SSL implementation
not found
05-27 08:31:24.342: WARN/System.err(223):     at
org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:
104)
05-27 08:31:24.352: WARN/System.err(223):     at
javax.net.ssl.SSLContext.getInstance(SSLContext.java:58)
05-27 08:31:24.352: WARN/System.err(223):     at
com.dukascopy.transport.common.mina.ssl.SSLContextFactory.createClientSSLContext(SSLContextFactory.java:
158)
05-27 08:31:24.352: WARN/System.err(223):     at
com.dukascopy.transport.common.mina.ssl.SSLContextFactory.getInstance(SSLContextFactory.java:
80)
05-27 08:31:24.362: WARN/System.err(223):     at
com.dukascopy.transport.client.ClientConnector.run(ClientConnector.java:
105)


Have looked at many Android forums, and didn't find any solution...
Except this ->
http://stackoverflow.com/questions/995514/https-connection-android

But TLS is not ok for me.

I can not belive that on Android SDK is not possible create SSL
connection in standart way. (not http connection...)

Thanks! Hopefully anybody have experience with this

-- 

2. Ringtone picker calls onActivityResult() too early

I'm using the RingtoneManager to pick a ringtone. However, my
onActivityResult() method is getting invoked too soon. As soon as the
ringtone picker dialog appears, onActivityResult() is invoked with a
non-RESULT_OK result code, even before I select any ringtones or
select the "OK" button. Then, after choosing a ringtone and selecting
"OK", onActivityResult() doesn't get called any more.

Here are the pertinent sections of my code. Note that this.toast() is
just a wrapper to send a toast.

    private boolean menuChoice(MenuItem item) {
        switch (item.getItemId()) {
        case 0:
            this.ringtonePicker();
            return (true);
        }
        return (false);
    }

    public void ringtonePicker() {
        Intent intent = new
Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select
ringtone");
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT,
false);
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT,
true);
        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_NOTIFICATION);
        this.startActivityForResult(intent, 999);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode,
Intent intent) {
        this.toast("onActivityResult: " + requestCode + ", " +
resultCode);
        if (resultCode != RESULT_OK) {
            this.toast("result code not " + RESULT_OK);
            return;
        }
        if (requestCode == 999) {
            this.toast("request code is OK");
            Uri uri =
intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
            if (uri != null) {
                String ringTonePath = uri.toString();
                this.toast("ringtone path: " + ringTonePath);
            }
            else {
                this.toast("no ringtone path");
            }
        }
        else {
            this.toast("request code not OK");
        }
        super.onActivityResult(requestCode, resultCode, intent);
    }

The only toast messages I get are "onActivityResult: 999, 0" and
"result code not -1", and these occur when the ringtone picker first
shows up, and before I pick any ringtones or select "OK".

The onActivityResult() method doesn't get called any more, even after
I pick a ringtone and select "OK".

What could I be doing wrong which would cause onActivityResult() to be
called with a failure before I even pick a ringtone? ... even though
the ringtone picker shows up properly?

Thanks in advance.

-- 

3. how to download file from android web view file link?

4. parallax

5. JTwitter OAuth

6. Javascript problem with Webview runing under a HTC Desire

7. Homescreen widget stops responding on FroYo