1

My Issue is that I have a LinearLayout that I am inflating at runtime to a LinearLayout inside ScrollView.
This is the main_activity.xml

<ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/controlLayoutCV"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/toolLayoutCV">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="@dimen/dp5"
            android:paddingLeft="@dimen/dp7"
            android:paddingRight="@dimen/dp7"
            android:paddingTop="@dimen/dp5">

            <android.support.v7.widget.CardView
                android:id="@+id/questionQuizCV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:cardElevation="@dimen/dp2">

                <com.emedicoz.app.CustomViews.JustifiedTextView
                    android:id="@+id/questionQuizTV"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="@dimen/dp5"
                    android:text="" />
            </android.support.v7.widget.CardView>

            <LinearLayout
                android:id="@+id/quizQuestionLL"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/questionQuizCV"
                android:layout_marginTop="@dimen/dp5"
                android:orientation="vertical"
                android:padding="@dimen/dp5" />

        </RelativeLayout>
 </ScrollView>


& this is the item_layout.xml

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mcqlayout_LL"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/dp5"
    android:minHeight="30dp"
    android:orientation="horizontal"
    android:paddingBottom="@dimen/dp7"
    android:paddingTop="@dimen/dp7">

    <TextView
        android:id="@+id/optioniconTV"
        android:layout_width="@dimen/dp40"
        android:layout_height="@dimen/dp40"
        android:background="@drawable/circle_bg"
        android:gravity="center"
        android:padding="@dimen/dp3"
        android:text="A"
        android:textSize="@dimen/sub_heading_text_size" />

    <com.emedicoz.app.CustomViews.JustifiedTextView
        android:id="@+id/optionTextTV"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="@dimen/dp10" />
</LinearLayout>

This is the CustomTextView that I have created to show the HTML content directly. The JustifiedTextView.class is

public class JustifiedTextView extends WebView {
    private String text = "";
    private int textSize = 12;
    private int backgroundColor = Color.TRANSPARENT;

    public JustifiedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setWebChromeClient(new WebChromeClient() {});
    }

    public void setText(String s) {
        this.text = s;
        reloadData();
    }

    @SuppressLint("NewApi")
    private void reloadData() {

        // loadData(...) has a bug showing utf-8 correctly. That's why we need to set it first.
        this.getSettings().setDefaultTextEncodingName("utf-8");

        //        this.loadData(String.format(core,textColor,textSize,text), "text/html","utf-8");
        this.loadData(text, "text/html", "utf-8");

        // set WebView's background color *after* data was loaded.
        super.setBackgroundColor(backgroundColor);

        // Hardware rendering breaks background color to work as expected.
        // Need to use software renderer in that case.
        if (android.os.Build.VERSION.SDK_INT >= 11)
            this.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
            Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
        reloadData();
    }
}

I have tried All of the solutions mentioned below.

  1. Disable WebView touch events in Android
  2. Already tried to set the android:descendantFocusability="blocksDescendants" to ScrollView

Why the click Event of LinearLayout does not fire when making click on WebView?

This is the way I am inflating the Layout and handle the click event.

    private LinearLayout initAnswerMCViews(String text, String questions, Questions questionsModel) {
    LinearLayout view = (LinearLayout) View.inflate(activity, R.layout.mcq_quiz, null);

    answerTV = (JustifiedTextView) view.findViewById(R.id.optionTextTV);
    optionIconTV = (TextView) view.findViewById(R.id.optioniconTV);
    mcqItemLL = (LinearLayout) view.findViewById(R.id.mcqlayout_LL);

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
    lp.setMargins(3, 3, 3, 3);
    mcqItemLL.setLayoutParams(lp);

    if (questionsModel.isAnswered()) {
        String[] answer = questionsModel.getUser_answer().split(",");
        for (int i = 0; i < answer.length; i++) {
            if (answer[i].equals(text)) {
                answerTV.setText(questions);
                optionIconTV.setText(text);
                optionIconTV.setBackgroundResource(R.drawable.circle_bg_true);
            } else {
                answerTV.setText(questions);
                optionIconTV.setText(text);
            }
        }
    } else {
        answerTV.setText(questions);
        optionIconTV.setText(text);
    }

    mcqItemLL.setTag(R.id.questions, optionIconTV.getText().toString());
    mcqItemLL.setTag(R.id.optionsAns, mcqItemLL);
    mcqItemLL.setOnClickListener(optionClickListener);
    viewArrayList.add(mcqItemLL);
    return view;
}

Why the click is not get listen when clicked on the WebView part in the Layout?

enter image description here

live-love
  • 48,840
  • 22
  • 240
  • 204
Abhinav Suman
  • 940
  • 1
  • 9
  • 29
  • Try setting the clickable attributes (via setClickable(boolean)) of your generated views. Set your LinearLayout to non-clickable and the child views to clickable – Gabriel Costa Nov 28 '17 at 14:18
  • I am in need to make clickable the main parent layout. so I can't do that – Abhinav Suman Nov 28 '17 at 14:23
  • Oh, I misunderstood your question. You want to call the onClick() of your LinearLayout instead of your child's onClick(), right? In that case, you can do the opposite: set the childs as non-clickable and the LinearLayout as clickable. If you need childs to be clickable as well, you can use an onTouchListener, detect a click (use GestureDetector for that) and return true to indicate that the click event has been consumed in the LinearLayout's onTouch(). – Gabriel Costa Nov 28 '17 at 14:42
  • @GabrielCosta already have implemented by enabling clickable false in the both TextView but it is still not working. – Abhinav Suman Nov 28 '17 at 14:44
  • I believe the default clickable of a LinearLayout is false. So, did you try adding clickable=true to your LinearLayout? Try putting "clickable=true" to both LinearLayouts (quizQuestionLL and mcqlayout_LL) – Gabriel Costa Nov 28 '17 at 14:56
  • @GabrielCosta as you can see the layouts and code also it is same implemented even in my system. Especially I have spent more than 2 Hr on this to solve this. but unable to solve it. As you can see that the click outside the web view in the image that can be changed the background of options. – Abhinav Suman Nov 28 '17 at 15:00
  • Well, somewhere in between your hierarchy, the click is either being ignored or being consumed. Try adding click listeners to the parents as well (ScrollView, RelativeLayout, the quizQuestionLL LinearLayout) and log where you're getting the event. This way, you'll know the last view to get it – Gabriel Costa Nov 28 '17 at 15:43
  • maybe, I will try tomorrow and log it that where it goes away. – Abhinav Suman Nov 28 '17 at 18:21

1 Answers1

2

I finally found the issue.
It is basically the issue of conflicting Touch Event of both parent Scrollview and CustomWebView.
So, by using the new classes that itself overriding the ClickListener and TouchListener.

package com.app.CustomViews;

import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;


public class TestSeriesOptionWebView extends WebView implements GestureDetector.OnGestureListener {
    private boolean check = false;

    class LongClick implements OnLongClickListener {
        final /* synthetic */ TestSeriesOptionWebView testSeriesOptionWebView;

        LongClick(TestSeriesOptionWebView testSeriesOptionWebView) {
            this.testSeriesOptionWebView = testSeriesOptionWebView;
        }

        public boolean onLongClick(View view) {
            return true;
        }
    }

    public TestSeriesOptionWebView(Context context) {
        super(context);
        handleClick();
    }

    public TestSeriesOptionWebView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        handleClick();
    }

    public TestSeriesOptionWebView(Context context, AttributeSet attributeSet, int i) {
        super(context, attributeSet, i);
        handleClick();
    }

    private void handleClick() {
        setFocusable(false);
        /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setLayerType(View.LAYER_TYPE_HARDWARE, null);
        } else {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }*/
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        setVerticalScrollBarEnabled(false);
        setBackgroundColor(0);
        setHapticFeedbackEnabled(false);
        setOnLongClickListener(new LongClick(this));
    }

    public void setDisableWebViewTouchListener(boolean z) {
        this.check = z;
    }

    public boolean onTouchEvent(MotionEvent motionEvent) {
        if (this.check) {
            return false;
        }
        return super.onTouchEvent(motionEvent);
    }

    public boolean canScrollHorizontal(int i) {
        int computeHorizontalScrollOffset = computeHorizontalScrollOffset();
        int computeHorizontalScrollRange = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
        if (computeHorizontalScrollRange == 0) {
            return false;
        }
        if (i < 0) {
            if (computeHorizontalScrollOffset <= 0) {
                return false;
            }
            return true;
        } else if (computeHorizontalScrollOffset >= computeHorizontalScrollRange - 1) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }

    public boolean onDown(MotionEvent motionEvent) {
        return true;
    }

    public void onShowPress(MotionEvent motionEvent) {
    }

    public boolean onSingleTapUp(MotionEvent motionEvent) {
        return false;
    }

    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float f, float f2) {
        return f != 0.0f;
    }

    public void onLongPress(MotionEvent motionEvent) {
    }

    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float f, float f2) {
        return true;
    }
}  

If anybody faces this type of issue, then Use this Custom Class TestSeriesOptionWebView.class.

Abhinav Suman
  • 940
  • 1
  • 9
  • 29