Search code examples
androidandroid-listviewandroid-animationandroid-cursoradapterandroid-drawable

Animate background on listview


I have a ListView that have in each row 2 TextView and a CheckBox.

I have a drawable (a line), that I want once the user check the CheckBox that the drawable will be scale as an animation at the background of the checked CheckBox row, I was able in my getView() method on my Custom Adapter, to animate the drawable as a background but it also scale the 2 TextView and the CheckBox, and I want that only the drawable background will be scale as an animation, how do i do that?

here is my getView() method on the custom adapter:

public View getView(final int position, View convertView, final ViewGroup parent) {
    final ViewHolder holder;

    LayoutInflater inflater = LayoutInflater.from(context);
    convertView = inflater.inflate(R.layout.listview_item_row, parent, false);
    // cache view fields into the holder
    holder = new ViewHolder();
    holder.itemTitle = (TextView) convertView.findViewById(R.id.itemTitle);
    holder.itemQuantity = (TextView) convertView.findViewById(R.id.itemQuantity);
    holder.itemCheck = (CheckBox) convertView.findViewById(R.id.itemCheck);
    convertView.setTag(holder);

    final Cursor cursor = getCursor();
    final View rowView = convertView;
    cursor.moveToPosition(position);
    holder.itemTitle.setText(cursor.getString((cursor.getColumnIndex(MySQLiteHelper.KEY_NAME))));
    holder.itemQuantity.setText(cursor.getString((cursor.getColumnIndex(MySQLiteHelper.KEY_QUANTITY))));
    holder.itemCheck.setChecked(cursor.getInt(cursor.getColumnIndex(MySQLiteHelper.KEY_CHECKED)) == 1);

    holder.itemCheck.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    cursor.moveToPosition(position);
                    itemsDataSource.updateItemCheckBox(1, cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.KEY_ID)));
                    itemsDataSource.updateRoute(cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_NAME)), true);
                    Animation drawLine = AnimationUtils.loadAnimation(context, R.anim.item_done);
                    rowView.setBackgroundResource(R.drawable.line);
                    rowView.startAnimation(drawLine);
                    ShowListActivity.PRIORITY++;
                }
                else {
                    cursor.moveToPosition(position);
                    itemsDataSource.updateItemCheckBox(0, cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.KEY_ID)));
                    itemsDataSource.updateRoute(cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_NAME)), false);
                    rowView.setBackgroundResource(0);
                    ShowListActivity.PRIORITY--;
                }

            }
        });
    if (holder.itemCheck.isChecked()) rowView.setBackgroundResource(R.drawable.line);
    else rowView.setBackgroundResource(0);
    return rowView;
}
private static class ViewHolder {
    TextView itemTitle;
    TextView itemQuantity;
    CheckBox itemCheck;     
}

Solution

  • update

    I managed to solve the problem:

    first I changed the custom row layout file like this:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameRowLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:weightSum="10">
    
    <LinearLayout android:id="@+id/rowLayout" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" >
    
            <CheckBox android:id="@+id/itemCheck" 
                android:layout_width="0dp" 
                android:layout_height="wrap_content" 
                android:layout_marginBottom="5dp" 
                android:layout_marginTop="5dp" 
                android:layout_weight="2" android:gravity="center" 
                android:focusable="false" 
                android:focusableInTouchMode="false" 
                android:singleLine="false" />
    
           <TextView android:id="@+id/itemTitle" 
               android:layout_width="0dp" 
               android:layout_height="fill_parent" 
               android:layout_marginBottom="5dp" 
               android:layout_marginTop="5dp" 
               android:layout_weight="6" 
               android:gravity="center" 
               android:text="some text1" 
               android:textColor="#2B89A8" 
               android:textSize="22dp" 
               android:textStyle="bold" />
    
           <TextView android:id="@+id/itemQuantity" 
               android:layout_width="0dp" 
               android:layout_height="fill_parent" 
               android:layout_marginBottom="5dp" 
               android:layout_marginTop="5dp" 
               android:layout_weight="2" 
               android:gravity="center" 
               android:text="some text2" 
               android:textColor="#2B89A8" 
               android:textSize="22dp" 
               android:textStyle="bold" />
    
    </LinearLayout>
    
    <View
        android:id="@+id/backgroundView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    
    </FrameLayout>
    

    the whole idea of Framelayout is that views can overlap each other, there for the View after the LinearLayout is overlapping the LinearLayout.

    then I changed my getView() method in my custom adapter as Following:

    public View getView(final int position, View convertView, final ViewGroup parent) {
        final ViewHolder holder;
    
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.listview_item_row, parent, false);
        // cache view fields into the holder
        holder = new ViewHolder();
        holder.itemTitle = (TextView) convertView.findViewById(R.id.itemTitle);
        holder.itemQuantity = (TextView) convertView.findViewById(R.id.itemQuantity);
        holder.itemCheck = (CheckBox) convertView.findViewById(R.id.itemCheck);
        holder.rowView = (View) convertView.findViewById(R.id.backgroundView);
        convertView.setTag(holder);
    
        final Cursor cursor = getCursor();
        cursor.moveToPosition(position);
        holder.itemTitle.setText(cursor.getString((cursor.getColumnIndex(MySQLiteHelper.KEY_NAME))));
        holder.itemQuantity.setText(cursor.getString((cursor.getColumnIndex(MySQLiteHelper.KEY_QUANTITY))));
        holder.itemCheck.setChecked(cursor.getInt(cursor.getColumnIndex(MySQLiteHelper.KEY_CHECKED)) == 1);
    
        holder.itemCheck.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        cursor.moveToPosition(position);
                        itemsDataSource.updateItemCheckBox(1, cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.KEY_ID)));
                        itemsDataSource.updateRoute(cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_NAME)), true);
                        Animation drawLine = AnimationUtils.loadAnimation(context, R.anim.item_done);
                        holder.rowView.setBackgroundResource(R.drawable.line);
                        holder.rowView.startAnimation(drawLine);
                        ShowListActivity.PRIORITY++;
                    }
                    else {
                        cursor.moveToPosition(position);
                        itemsDataSource.updateItemCheckBox(0, cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.KEY_ID)));
                        itemsDataSource.updateRoute(cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_NAME)), false);
                        holder.rowView.setBackgroundResource(0);
                        ShowListActivity.PRIORITY--;
                    }
    
                }
            });
        if (holder.itemCheck.isChecked()) holder.rowView.setBackgroundResource(R.drawable.line);
        else holder.rowView.setBackgroundResource(0);
        return convertView;
    }
    private static class ViewHolder {
        TextView itemTitle;
        TextView itemQuantity;
        CheckBox itemCheck; 
        View rowView;
    }
    

    hope you can understand what I did.