ListView Choices: What the devil is happening?

by kingkung » Thu, 23 Oct 2008 10:31:21 GMT


Sponsored Links
 I wrote a small activity which illustrates some crazy behavior I found
while implementing ListView and choices.  Feel free to plug this in
and try it yourselves (and be sure to check logcat as well):

public class TestActivity extends ListActivity {

        public String[] strings = { "What","the","devil","is","happening?" };

        @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.listview);
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        getListView().setAdapter(new
ArrayAdapter<String>(this,R.layout.main,strings));
        getListView().setOnItemClickListener(new OnItemClickListener()
{
                        public void onItemClick(AdapterView<?> arg0, View arg1, 
int arg2,
                                        long arg3) {
                                        Log.d("test","Checked: "+
((TextView)getListView().getChildAt(arg2)).getText().toString());
                                        if (getListView().isItemChecked(arg2))
                                        {
                                                for (int i=0; 
i<getListView().getChildCount(); i++)
                                                {
                                                        if (i==arg2)
                                                                
getListView().getChildAt(i).setBackgroundColor(Color.MAGENTA);
                                                        else
        
getListView().getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
                                                }
                                        }
                                        else
        
getListView().getChildAt(arg2).setBackgroundColor(Color.TRANSPARENT);

                                }
        });
    }
}

The R.layout.main is just your standard default TextView when you
create a new project in Eclipse.  The R.layout.listview is the
standard LinearLayout with embedded ListView for ListActivities shown
below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=" http://schemas.android.com/apk/res/ 
android"
      android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    >
        <ListView android:id="@+id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    />
</LinearLayout>

Can anyone explain rationally what is causing this to happen?
--~--~---------~--~----~------------~-------~--~----~



ListView Choices: What the devil is happening?

by Romain Guy » Thu, 23 Oct 2008 10:40:53 GMT


 You haven't explained what the crazy behavior is :) My bet is that you
call isChecked() too early. Try to postpone everything you do in the
OnItemClickListener by posting a Runnable into a Handler (or with
getListView().post()).






-- 
Romain Guy
www.curious-creature.org

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


Sponsored Links


ListView Choices: What the devil is happening?

by kingkung » Thu, 23 Oct 2008 10:49:25 GMT


  kind of wanted people to try it and find out :)  I can try that, but
it doesn't look like it's a race condition (like something gets called
too early or something) of any kind... it's a very distinct pattern of
behavior that's happening, though it's not what I would consider the
expected behavior...

On Oct 22, 7:40pm, "Romain Guy" <[EMAIL PROTECTED]> wrote:
--~--~---------~--~----~------------~-------~--~----~



ListView Choices: What the devil is happening?

by Romain Guy » Thu, 23 Oct 2008 10:51:56 GMT


 ould you please explain what you are witnessing? (I work on ListView,
I'd like to help... :)

There's another issue in your code. In the for loop, you are comparing
a position (arg2) with an index (i). These are different and mixing
them will cause tons of "weird" issues.

On Wed, Oct 22, 2008 at 7:49 PM, kingkung <[EMAIL PROTECTED]> wrote:



--
Romain Guy
www.curious-creature.org

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



ListView Choices: What the devil is happening?

by kingkung » Thu, 23 Oct 2008 11:30:26 GMT


  just sent you an email explaining the problem to your google
account. :)

On Oct 22, 7:51pm, "Romain Guy" <[EMAIL PROTECTED]> wrote:
--~--~---------~--~----~------------~-------~--~----~



ListView Choices: What the devil is happening?

by Romain Guy » Thu, 23 Oct 2008 11:55:37 GMT


 k so the issue is what I noticed: you are mixing index and positions.
A ListView contains only as many items as it needs to fill the screen.
For instance, you can see 8 items on screens, there are 8 children in
the ListView, numbered from 0 to 7 (the index.) However, your adapter
can have many more items, for instance 400. The position (arg2 in your
code) indicates the index of an item *in the adapter*. This means that
the View of index 2 is not necessarily the adapter's item of position
2. To do the conversion, you can use
ListView.getFirstVisiblePosition().

Here is your code with the fix:

if (i==arg2) becomes if (getListView().getFirstVisiblePosition() + i == arg2)
and all the getChildAt(arg2) become getChildAt(arg2 -
getListView().getFirstVisiblePosition())


On Wed, Oct 22, 2008 at 8:20 PM, kingkung <[EMAIL PROTECTED]> wrote:



--
Romain Guy
www.curious-creature.org

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



ListView Choices: What the devil is happening?

by kingkung » Fri, 24 Oct 2008 00:43:10 GMT


 ust made the changes, the behavior is identical... this is my updated
code, feel free to make sure I made all changes:

public String[] strings = { "What","the","devil","is","happening?" };

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.listview);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setAdapter(new
ArrayAdapter<String>(this,R.layout.main,strings));
getListView().setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2,
long arg3) {
// Log.d("test","Checked: "+
((TextView)getListView().getChildAt(arg2)).getText().toString());
if (getListView().isItemChecked(arg2))
{
for (int i=0;
i<getListView().getChildCount(); i++)
{
if
(getListView().getFirstVisiblePosition()+i==arg2)

getListView().getChildAt(i).setBackgroundColor(Color.MAGENTA);
else

getListView().getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
}
else
getListView().getChildAt(arg2-
getListView().getFirstVisiblePosition()).setBackgroundColor(Color.TRANSPARENT);

}
});
}

On Oct 22, 8:45pm, "Romain Guy" <[EMAIL PROTECTED]> wrote:
--~--~---------~--~----~------------~-------~--~----~



Other Threads

1. How to reliably terminate supporting threads

Is there a way to reliably terminate my supporting threads when my
application is destroyed, particularly in the case
Activity.onDestroy() never gets called?

Suppose when my application starts up it creates separate threads
using the Thread class to run support tasks (game update, path
finding, AI, asset loading, whatever).

The Dev Guide states this: "For example, if it has a thread running in
the background to download data from the network, it may create that
thread in onCreate() and then stop the thread in onDestroy()", but
what if onDestroy() never gets called? It seems like the thread would
live on after the application is destroyed.

My thinking right now is that I have to terminate the threads during
onPause() and recreate them if the activity resumes. AsyncTask does
not seem right for repeated per-frame tasks like this, unless I
misunderstand its intended uses.

My thanks for any tips or pointers to helpful documentation.

-- 

2. How do I make it so that if an SMS message fails to send, no dialogue pops up asking the user if they want to retry or cancel?

Thanks!

-- 

3. ListView problem

4. Programatically check TalkBack is on

5. opening new screen help

6. Android Market update bug?

7. android.net.Uri to java.net.URI