views:

60

answers:

1

Hi, I'm having a several issues with ListViews.

The first problem is the layout that I use for every row of the listview. When I click in a row I've programmed that it expands with some other views. All works fine, but when I try to click again for shrink it, it seems that it's no focusable and doesn't highlight and, of course, it doesn't shrink. If I change the deprecated singleLine in the XML to inputType="text" all works fine but the row never highlithts.

The second problem goes when I try the method that Romain Guy said about the RelativeLayouts and the alignwithParentIfMissing. No matter whatever I try, but it seems impossible to implement in a ListView.

Another problem is with ellipsize, but it looks is a Android SDK bug and only works fine if I set singleLine in the attributes of the TextView

Well, I hope someone can helps me. I put the code of the listview and the XML of the layout. If you need some more code or information, as if you find any improvement or error, please, tell me.

Activity with the listview

public class LoginActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        final ListView lv = (ListView)findViewById(R.id.login_list_view);

           lv.setAdapter(new LoginListAdapter(this,mUserNames));
        lv.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> a, View view, int position, long id) {
                ((LoginListAdapter)lv.getAdapter()).expand(position);
                return true;
            }
        });
    }

    private class LoginListAdapter extends BaseAdapter {
        LoginListAdapter(Context context, String[] users){
            mContext = context;
            mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mUserNames = users;
            mExtend = new Boolean[mUserNames.length];
            for(int i=0; i<mUserNames.length; i++)
                mExtend[i] = false;
        }

        public int getCount() {
            return mUserNames.length;
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        private class ViewHolder{
            private TextView text;
            private CheckBox checkbox;
            private Button button;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if(convertView==null){
                convertView = mInflater.inflate(R.layout.login_list_item, parent, false);
                holder=new ViewHolder();
                holder.text=(TextView)convertView.findViewById(R.id.user_name);
                holder.checkbox=(CheckBox)convertView.findViewById(R.id.login_list_item_access_always);
                holder.button=(Button)convertView.findViewById(R.id.login_list_item_login);
                convertView.setTag(holder);
            }
            else
                holder=(ViewHolder)convertView.getTag();

            holder.text.setText(mUserNames[position]);
            Animation animation=null;
            if(mExtend[position] == true)
                animation = AnimationUtils.loadAnimation(mContext, R.anim.alpha);
            holder.checkbox.setVisibility(mExtend[position] ? View.VISIBLE : View.GONE);
            if(mExtend[position] == true)
                holder.checkbox.startAnimation(animation);
            holder.button.setVisibility(mExtend[position] ? View.VISIBLE : View.GONE);
            if(mExtend[position] == true)
                holder.button.startAnimation(animation);

            return convertView;
        }

        public void expand(int position) {
            if(mExtend[position] == true)
                mExtend[position] = false;
            else {
                for(int i=0; i<mUserNames.length; i++)
                    mExtend[i] = false;
                mExtend[position] = true;
            }
            notifyDataSetChanged();
        }

        private Context mContext;
        private String[] mUserNames;
        private Boolean[] mExtend;
        private LayoutInflater mInflater=null;
    }

    private String[] mUserNames = {
        "Nombre1 Apellido_1 Apellid",
        "Nombre2 Apellido 1 Apellido2",
        "Nombre3 Apellido 1 Apellido2",
        "Nombre4 Apellido 1 Apellido2",
        "Nombre5 Apellido 1 Apellido2",
        "Nombre6 Apellido 1 Apellido2",
        "Nombre7 Apellido 1 Apellido2",
        "Nombre8 Apellido 1 Apellido2",
        "Nombre9 Apellido 1 Apellido2",
        "Nombre10 Apellido 1 Apellido2",
        "Nombre11 Apellido 1 Apellido2",
        "Nombre12 Apellido 1 Apellido2",
        "Nombre13 Apellido 1 Apellido2",
    };
}

login_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="6dip"
    android:paddingBottom="0dip"
    android:background="@drawable/login_list_item_background">
    <ImageView android:id="@+id/user_image"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:layout_alignParentTop="true"
        android:layout_marginRight="6dip"
        android:src="@drawable/icon"
        android:scaleType="fitXY"/>
    <TextView android:id="@+id/user_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/user_image"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignWithParentIfMissing="true"
        android:inputType="text"
        android:paddingTop="12dip"
        android:paddingBottom="10dip"
        android:textColor="#FF6D84B4"
        android:textSize="18sp"/>
    <CheckBox android:id="@+id/login_list_item_access_always"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/user_name"
        android:layout_toRightOf="@id/user_image"
        android:text="@string/login_list_item_access_always"
        android:textColor="#83021837"
        android:textSize="15sp"
        android:paddingLeft="45dip"
        android:visibility="gone"/>
    <Button android:id="@+id/login_list_item_login"
        android:layout_below="@id/login_list_item_access_always"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/login"
        android:textColor="#FF000000"
        android:visibility="gone"/>
</RelativeLayout>

About the response of adamp, I've done this:

In LoginActivity I've put lv.setItemCanFocus(true). I've created a list selector and I put it to the listview with XML parameter "android:listSelector="@drawable/login_list_selector"":

login_list_selector.xml And finally, I have this listener:

lv.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> a, View view, int position, long id) {
                ((LoginListAdapter)lv.getAdapter()).expand(position);
                return true;
            }
        });

Once I've done that, there is no change about the behaviour of the listview. But I noticed that only I can expand the row clicking in the textview, if I click inside the row but in a empty area nothing happens.

Very thanks.

+1  A: 

As soon as you have visible child views such as buttons or checkboxes that can focus within a list item, ListView stops treating the item as a single tappable unit. (Think about it; in a list item with buttons you want to tap the buttons, not the whole item.)

The answer you're probably looking for is probably the same answer from this other question, setItemsCanFocus.

adamp
Thanks, I understand what you tell me, but I set the descendantFocusability parameter with beforeDescendants in the XML of the listview, that is the equivalent of setItemsCanFocus, and doesn't fix anything, all works equal.
Adrian
That is most certainly *not* the equivalent of setItemsCanFocus. :)
adamp
Ok, I've tried setting lv.setItemsCanFocus(false) with the singleLine or inputType on the TextView, and the behaviour it's the same as doesn't using that method. I don't know if it a bug of Android SDK or what, but I can't work it properly.
Adrian
setItemsCanFocus(false) is the default behavior. setItemsCanFocus(true) means list items handle their own focus, and the default ListView focus handling is disabled. (You won't be able to tap whole items by themselves at all.) Next, you set a state list drawable as the background for the root view of the list item (so that the item lights up when tapped or focused) and attach a click listener to it to listen for whole-item taps (not on the button or checkbox) to open/close the item.
adamp
I've edited my question at the end with I've done and the issues. If you can tell me what I'm doing bad I would thank you.
Adrian