Hello Android UI Gurus,

I have been struggling for a few days now with an annoying UI issue.
I've whittled the project down to nothing but a small demonstration of
the problem.  I admit I'm pretty new to Android UI work, but at the
same time I'm an experienced, qualified engineer and I just can't seem
to figure this out.  I was hoping to get some feedback from some of
you out there who are more familiar with the internals and
idiosyncrasies  of the platform.  Any help would be greatly
appreciated!

The desired behavior:
I have a list view.  Each list view row consists of a text element,
and a hidden image.  When an item is selected from the list, I'd like
to make the image visible, and, start an animation on it.  Pretty
standard stuff here, we're talking basically about a "loading"
spinner.

The problem:
After selecting 2 or sometimes 3 items in the list, I see spinners
become visible and start animating for rows which were never
selected.  The two things that lead me to believe this is a bug with
the platform are:

A) Putting in a break point I can clearly see that the underlying data
source from the list does not have the "isSpinning" property set for
the items that begin animating in a seemingly random manner.

and

B) The only code that makes the image visible and begins the animation
for that row is inside of my custom data adapter.  Before it can start
the animation it changes the text field in that row as well.  The text
fields are not changed in the rows where my spinners seem to appear of
their own accord.

The code:
As I said when I started this post I've removed everything from the
project except the relevant UI code.  Here is what I have.

/res/layout
main.xml=>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello"/>
        <ListView
            android:id="@+id/android:list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:cacheColorHint="#0000"
            android:background="@android:color/transparent"
            android:dividerHeight="1dip"/>
</LinearLayout>

list_view_row.xml=>
<?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="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
            <TextView
                        android:id="@+id/label"
                android:textSize="11sp"
                android:padding="2dip"
                android:gravity="center_vertical|center"
                android:layout_gravity="center_vertical|center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#ffffff"/>
            <ImageView
                android:id="@+id/spinner"
                android:padding="2dip"
                android:src="@drawable/loading"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </LinearLayout>
</LinearLayout>

/res/anim
rotate.xml=>
<?xml version="1.0" encoding="UTF-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android";
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="1900" />

/res/drawable
spinner.png

/src
MyContainer.java=>
public class MyContainer {
        private String mText = "";
        private Boolean mLoading = false;

        public void setText(String mText) {
                this.mText = mText;
        }
        public String getText() {
                return mText;
        }
        public void setIsLoading(Boolean mLoading) {
                this.mLoading = mLoading;
        }
        public Boolean isLoading() {
                return mLoading;
        }
}

CustomAdapter.java=>
public class CustomAdapter extends ArrayAdapter<MyContainer> {

        private ArrayList<MyContainer> items;
        private Context c = null;

        public CustomAdapter(Context context, int textViewResourceId,
ArrayList<MyContainer> items) {
       super(context, textViewResourceId, items);
       this.items = items;
       this.c = context;
   }

        @Override
    public View getView(int position, View convertView, ViewGroup
parent) {
                View v = convertView;
        if (v == null) {
            LayoutInflater vi =
(LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.list_view_row, null);
        }
        TextView label = (TextView) v.findViewById(R.id.label);
        ImageView spinner = (ImageView) v.findViewById(R.id.spinner);
        MyContainer item = (MyContainer) items.get(position);
        if (item.isLoading()) {
                label.setText("***"+item.getText()+"***");
                spinner = (ImageView)v.findViewById(R.id.spinner);
                spinner.setVisibility(View.VISIBLE);
                Animation spinnerAnimation =
AnimationUtils.loadAnimation(getContext(), R.anim.rotate);
                spinner.startAnimation(spinnerAnimation);
        } else {
                label.setText(item.getText());
                spinner.setVisibility(View.INVISIBLE);
        }

        return v;
        }

}

Main.java=>
public class Main extends ListActivity {

        private ArrayList<MyContainer> mItems = null;
        private CustomAdapter mAdapter;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mItems = new ArrayList<MyContainer>();
        for (int i=0; i<10; i++) {
                MyContainer item = new MyContainer();
                item.setIsLoading(false);
                item.setText("item number "+Integer.toString(i));
                mItems.add(item);
        }
        mAdapter = new CustomAdapter(this, R.layout.list_view_row,
mItems);
        setListAdapter(mAdapter);

    }

    /**
     * Listview on click handler.
     */
        @Override
        public void onListItemClick(ListView parent, View v, int position,
long id){
                MyContainer item  = 
(MyContainer)parent.getItemAtPosition(position);
                for (int i = 0; i<mItems.size(); i++) {
                        MyContainer tmp =  mItems.get(i);
                        if (tmp.equals(item)) {
                                tmp.setIsLoading(true);
                                break;
                        }
                }
                mAdapter.notifyDataSetChanged();
    }
}







-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to