Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispatch Touch event from DialogFragment view to parent activity view

Here is how my layout looks like:

enter image description here

I have a parent activity which has a custom view (view1 that handle onTouch events by itself) and 2 buttons (view2 and view3). The DialogFragment has a visible layout shown and the rest is transparent. My dialog fragments look like this:

public class FragmentText extends DialogFragment{

  public static FragmentText newInstance() {
        FragmentText frag = new FragmentText();

        frag.setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar);
        return frag;
    }

  @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);

        // instantiate the custom layout
        final View layout = inflater.inflate(R.layout.fragment_layout, null);

        .....
        }

}

and the layout file looks like this:

<com.TransparentView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layMain"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginBottom="70dp"
    android:background="@color/transparent"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingBottom="70dp" >

    <LinearLayout
        android:id="@+id/layContent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="5dp"
        android:background="@drawable/bk_text_edit"
        android:orientation="vertical"
        android:padding="@dimen/margin" >

          all my layouts and buttons
    </LinearLayout>
</com.TransparentView>

and

public class TransparentView extends LinearLayout {

    @SuppressLint("NewApi")
    public TransparentView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public TransparentView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TransparentView(Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false; // event get propagated
    }

}

When the user presses outside the visible layout of the DialogFragment I want to: 1. dismiss the dialog fragment 2. pass the onTouch to the parent activity and allow the user to interact with the views.

So basically if I drag my finger over View1, I want to dismiss the dialog and continue my dragging interaction against view1.

Is this possible to achieve ?

LE: also this does not work:

layMain.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            getActivity().dispatchTouchEvent(event);

            return false;
        }
    });
like image 679
Alin Avatar asked Jun 03 '14 20:06

Alin


3 Answers

I had the same problem with BottomSheetDialog. I solved my problem:

final BottomSheetDialog dialog = getDialog();
final View touchOutside = dialog.findViewById(R.id.touch_outside);
touchOutside.setOnTouchListener((v, event) -> {
    getActivity().dispatchTouchEvent(event);
    return false;
});

So looks like solution of Finn should work correctly.

like image 145
Vitaly Avatar answered Oct 31 '22 16:10

Vitaly


In the end, as Luksprog suggested, I ended up with ditching DialogFragment. I did a test using simple Fragment which is hosted in an activity's FrameLayout so it looks just like an overlay on where I need it. In this way I still get all the interaction I need with the rest of the views.

Thank you all for your support.

like image 28
Alin Avatar answered Oct 31 '22 15:10

Alin


even though you ditched DialogFragment this might help others.

you need to get the actual decor view and intercept the touch event there:

 @Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);


    getDialog().getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            getActivity().dispatchTouchEvent(event);
            return false;
        }
    });

    return super.onCreateView(inflater, container, savedInstanceState);
}
like image 1
Finn Marquardt Avatar answered Oct 31 '22 17:10

Finn Marquardt