Search code examples
androidtalkbackaccessibility

Double tap doesn't click the parent view in talkback mode


I have the following xml file.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/linear_layout1"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:focusable="true"
        android:layout_margin="10dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/text1"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="first text"
            android:layout_margin="10dp"/>

        <TextView
            android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="second text"
            android:layout_margin="10dp"/>

    </LinearLayout>

</LinearLayout>

I have set a click listener for LinearLayout and TextView.

TextView textView1 = (TextView) findViewById(R.id.text1);
LinearLayout linearLayout = findViewById(R.id.linear_layout1);
linearLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(v.getContext(), "Linear layout clicked", Toast.LENGTH_SHORT).show();
                }
            });

textView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(), "text view clicked", Toast.LENGTH_SHORT).show();
            }
        });

I have made the LinearLayout focusable so that in talkback mode, it can get the accessibility focus. Now when I double tap on it, click event of text view is called instead of linear layout.

How can I make it call the click listener of linear layout instead?


Solution

  • I had the same problem and I solved it by creating new View, which was extending LinearLayout and in this View I have overriden onInterceptTouchEvent() method. In this method is checked whether Accessibility is turned on and if the ViewGroup (LinearLayout) is selected. If so, return true and intercept this event.

    public class AccessibleLinearLayout extends LinearLayout {
    
        public AccessibleLinearLayout(Context context) {
            super(context);
        }
    
        public AccessibleLinearLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public AccessibleLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (((AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled() && isAccessibilityFocused()) {
                return true;
            }
            return super.onInterceptTouchEvent(ev);
        }
    }
    

    I'm not sure if you need to check ((AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled() when you check if isAccessibilityFocused()