android – ListView with horizontalScrollView OnItemClick not working-ThrowExceptions

Exception or error:

So really quickly i have a listView with a custom adapter and it inflates a view that contains a horizontalScrollView as well as a textview etc. The problem I am having is that when i try to attach a listener to this listView it is not receiving any callbacks.

I believe the problem has to do with the fact that my list item contains a scroll view which is intercepting the click events (although i thought it should only intercept other gestures).

code… (my list item xml)

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

    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/grey" >

        <TextView
            android:id="@+id/headerName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:padding="4dp"
            android:textColor="@color/text_header"
            android:textStyle="bold"
            android:text="TextView" />

    </RelativeLayout>
    <View
        android:background="@color/border"
        android:layout_width="fill_parent"
        android:layout_height="1px" />
    <HorizontalScrollView
        android:id="@+id/horizontalScrollView1"
        android:layout_width="fill_parent"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/linearImages"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal" 
            android:padding="4dp">
        </LinearLayout>
    </HorizontalScrollView>
    <View
        android:background="@color/border"
        android:layout_width="fill_parent"
        android:layout_height="1px" />
</LinearLayout>

and then in my onCreate…

lv.setAdapter(myobj.adapter);
    lv.setTextFilterEnabled(true);
    lv.setOnItemClickListener(new OnItemClickListener(){

        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub
            Log.w("dsdsds", "sdsdsds");
        }});

Any help or suggestions would be greatly appreciated

How to solve:

Add this to the topmost Layout:

android:descendantFocusability="blocksDescendants"

It did the trick for me, now onItemClickListener is being fired.

###

You can call setOnClickListener for linearMain in the getView() method of your adapter.

###

for ScrollView you should use OnTouchListener, like:

private class ScrollViewOnTouchListener   implements OnTouchListener{
        HorizontalScrollView view;
        float historicX = Float.NaN;
        static final int DELTA_ON_CLICK = 20;
        long historicTime;
        int position;
        public ScrollViewOnTouchListener(HorizontalScrollView view, int position){
            this.view = view;
            this.position = position;
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) 
        {
            switch (event.getAction()) 
            {
                case MotionEvent.ACTION_DOWN:
                historicX = event.getX();
                historicTime = System.currentTimeMillis();
                break;

                case MotionEvent.ACTION_UP:

                if (Math.abs(event.getX() - historicX) < DELTA_ON_CLICK)
                    // seems like onclick
                    // do what you want for onClick

                break;
                default: return false;
            }
            return true;
        }


    }

and in getView method of adapter:

public View getView(int position, View convertView, ViewGroup parent) {
    ...
  HorizontalScrollView scrollItem;
  scrollItem =(  HorizontalScrollView )itemView.findViewById(R.id.item_scroll_view);
  scrollItem .setOnTouchListener(new  ScrollViewOnTouchListener(scrollItem , position));       
} 

###

Inside list_item.xml mark your layout with some id:

<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                      xmlns:tools="http://schemas.android.com/tools"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:fillViewport="true">

    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

...

Open your custom adapter, in getView(...) write:

View layout = view.findViewById(R.id.layout);
layout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (callback != null) {
                callback.showItem(position);
            }
        }
    });

Below in the adapter write:

public interface OnClickInterface {
    void showItem(int position);
}

And in the constructor of the adapter assign a callback:

public CustomAdapter(Context context, List<YourClass> list, OnClickInterface callback, int resId) {
    this.callback = callback;
    ...

In your activity/fragment that contains a ListView create an adapter like so:

CustomAdapter.OnClickInterface callback = new CustomAdapter.OnClickInterface() {
        @Override
        public void showItem(int position) {
            // Do something with an item.
        }
}
adapter = new Customdapter(getActivity(), new ArrayList<YourClass>(), callback, R.layout.list_item);

Leave a Reply

Your email address will not be published. Required fields are marked *