joates
joates

Reputation: 1103

SlidingDrawer prevents onTouchEvent

I have a large custom ImageView with regions defined as hotspots. When a user touches a hotspot on the image, I want to present them with a list of options appropriate for the selected hotspot. To maximize the space available for the image, I'm presenting the options in a SlidingDrawer.

As soon as I touch a hotspot, the area that would be covered by the sliding drawer stops producing OnTouchEvent callbacks even though the SlidingDrawer is still closed. Once I have manually opened and closed the sliding drawer, I can get a single callback. The area at the top of the image on either side of the sliding drawer handle (that would never be covered by the SlidingDrawer), however, continues to produce callbacks.

I have tried the following without success:

If I programmatically set the ViewState of the SlidingDrawer to "gone", then all the hotspots produce OnTouchEvent callbacks while the SlidingDrawer is closed.

Here's the Layout description:

<company.views.CustomDetailView     
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:xsns="http://schemas.android.com/apk/res/com.xactware.xactscopedroid" 
    android:id="@+id/ref_search_detail_view"
    style="@style/BaseFullLayout.Vertical">

<company.views.CustomImageView
    android:id="@+id/full_image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"  />

<SlidingDrawer
    android:id="@+id/drawer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:handle="@+id/handle"
    android:content="@+id/content"
    android:focusableInTouchMode="false">   

    <TextView
        android:id="@id/handle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/font_xlarge"
        android:textColor="@color/dark_gray"
        android:textStyle="bold"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp"
        android:background="@drawable/shape_data_background"
        android:focusableInTouchMode="false"    />
    <ListView
        android:id="@id/content"
        style="@style/ScopeList.ListView" />
</SlidingDrawer>

Here's the code I use to set up the image, the list of options, and the OnHotSpotSelected callback.

private void LoadImage(ParentTopic pTopic)
        {
            if (_imageView == null)
            {
                _imageView = FindViewById<RefSearchImageView>(Resource.Id.full_image);
            }

        string imgPath = pTopic.FullImage;
        if (imgPath != null)
        {
            var stream = Context.Assets.Open(System.IO.Path.Combine("en-USrefSearch", pTopic.FullImage));
            Bitmap bmp = BitmapFactory.DecodeStream(stream);
            _imageView.SetImageBitmap(bmp);
            _imageView.PTopic = pTopic;
            _imageView.OnHotSpotSelected = new HotSpotSelectedDelegate(OnHotSpotSelected);
        }


    }

    private void LoadList()
    {

        if (_parentHeaderLabel == null)
        {
            _parentHeaderLabel = FindViewById<TextView>(Resource.Id.handle);
        }

        if (Resources.Configuration.Orientation == Android.Content.Res.Orientation.Landscape)
        {
            _slidingDrawer = FindViewById<SlidingDrawer>(Resource.Id.drawer);
            //_slidingDrawer.Visibility = ViewStates.Gone;
        }
        _parentHeaderLabel.Text = null;

        if (_listView == null)
        {
            _listView = FindViewById<ListView>(Resource.Id.content);
        }
        if (_currentHeaderList != null)
        {
            _currentHeaderList.Clear();
        }

        LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
        View emptyView = inflater.Inflate(Resource.Layout.RefSearchDetailEmptyList, _listView, false);
        _listView.EmptyView = emptyView;

        var ia = Context as ItemsActivity;
        _listView.OnItemClickListener = new OnRSHeaderClickListener(ia, _currentHeaderList);
    }

    public void OnHotSpotSelected(string code)
    {
        ItemsActivity ia = Context as ItemsActivity;
        RSParentHeader parentHeader = ia.Data.GetRSParentHeader(code);
        _parentHeaderLabel.Text = parentHeader.Desc;

        _currentHeaderList = ia.Data.GetRSHeaders(parentHeader.ID);
        _listView.Adapter = new RSHeaderListAdapter(Context, Resource.Layout.RSHeaderListItem, Resource.Id.rsheader_desc, _currentHeaderList);
        _imageView.Invalidate();
        _imageView.RequestFocus();

    }

Upvotes: 0

Views: 993

Answers (1)

joates
joates

Reputation: 1103

I'm still not sure why, but the ListView that was the content of my SlidingDrawer continued to consume TouchEvents even when the drawer was closed. I created a custom ListView and overrode OnTouchEvent() to tell it not to do that.

public override bool OnTouchEvent (MotionEvent e){
    bool consumed = base.OnTouchEvent (e);
    SlidingDrawer drawer = (SlidingDrawer)this.Parent;
    if (!drawer.IsOpened)
    {
        return false;
    }
    return consumed;
}

Upvotes: 1

Related Questions