如果将Webview作为子级,则布局onClick事件将不起作用 [英] Layout onClick event does not work if it has Webview as a child

查看:66
本文介绍了如果将Webview作为子级,则布局onClick事件将不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是,我在运行时将 LinearLayout 夸大到 ScrollView 中的 LinearLayout .
这是 main_activity.xml

 < ScrollViewandroid: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">< RelativeLayoutandroid: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.CardViewandroid:id ="@ + id/questionQuizCV"android:layout_width ="match_parent"android:layout_height ="wrap_content"app:cardElevation ="@ dimen/dp2">< com.emedicoz.app.CustomViews.JustifiedTextViewandroid:id ="@ + id/questionQuizTV"android:layout_width ="match_parent"android:layout_height ="wrap_content"android:padding ="@ dimen/dp5"android:text ="/></android.support.v7.widget.CardView>< LinearLayoutandroid: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> 


&这是 item_layout.xml

 < LinearLayoutxmlns: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 =水平"android:paddingBottom ="@ dimen/dp7"android:paddingTop ="@ dimen/dp7">< TextViewandroid: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.JustifiedTextViewandroid:id ="@ + id/optionTextTV"android:layout_width ="match_parent"android:layout_height ="match_parent"android:layout_marginLeft ="@ dimen/dp10"/></LinearLayout> 

这是我创建的CustomTextView,用于直接显示 HTML 内容. JustifiedTextView.class

 公共类JustifiedTextView扩展了WebView {private String text =";private int textSize = 12;private int backgroundColor = Color.TRANSPARENT;public JustifiedTextView(Context context,AttributeSet attrs){超级(上下文,attrs);this.setWebChromeClient(new WebChromeClient(){});}公共无效setText(String s){this.text = s;reloadData();}@SuppressLint("NewApi")私人void reloadData(){//loadData(...)有一个错误,可以正确显示utf-8.这就是为什么我们需要先设置它.this.getSettings().setDefaultTextEncodingName("utf-8");//this.loadData(String.format(core,textColor,textSize,text),"text/html","utf-8");this.loadData(text,"text/html","utf-8");//在加载数据后设置WebView的背景颜色.super.setBackgroundColor(backgroundColor);//硬件渲染会破坏背景颜色,使其按预期工作.//在这种情况下,需要使用软件渲染器.如果(android.os.Build.VERSION.SDK_INT> = 11)this.setLayerType(WebView.LAYER_TYPE_SOFTWARE,null);}@Override公共无效onMeasure(int widthMeasureSpec,int heightMeasureSpec){int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec,heightMeasureSpec_custom);ViewGroup.LayoutParams参数= getLayoutParams();params.height = getMeasuredHeight();}公共无效setTextSize(int textSize){this.textSize = textSize;reloadData();}} 

我尝试了下面提到的所有解决方案.

  1. 解决方案

    我终于找到了问题.
    基本上,这是父级 Scrollview CustomWebView Touch Event 冲突的问题.
    因此,通过使用新类本身覆盖了 ClickListener TouchListener .

     包com.app.CustomViews;导入android.content.Context;导入android.os.Build;导入android.util.AttributeSet;导入android.view.GestureDetector;导入android.view.MotionEvent;导入android.view.View;导入android.view.ViewGroup;导入android.webkit.WebView;公共类TestSeriesOptionWebView扩展了WebView的实现GestureDetector.OnGestureListener {私人布尔检查= false;类LongClick实现OnLongClickListener {最终/*合成*/TestSeriesOptionWebView testSeriesOptionWebView;LongClick(TestSeriesOptionWebView testSeriesOptionWebView){this.testSeriesOptionWebView = testSeriesOptionWebView;}public boolean onLongClick(View view){返回true;}}公共TestSeriesOptionWebView(上下文上下文){超级(上下文);handleClick();}公共TestSeriesOptionWebView(上下文上下文,AttributeSet attributeSet){超级(上下文,attributeSet);handleClick();}public TestSeriesOptionWebView(Context context,AttributeSet attributeSet,int i){super(context,attributeSet,i);handleClick();}私人void handleClick(){setFocusable(false);/*如果(Build.VERSION.SDK_INT> = Build.VERSION_CODES.KITKAT){setLayerType(View.LAYER_TYPE_HARDWARE,null);} 别的 {setLayerType(View.LAYER_TYPE_SOFTWARE,空);} */setLayerType(View.LAYER_TYPE_SOFTWARE,空);setVerticalScrollBarEnabled(false);setBackgroundColor(0);setHapticFeedbackEnabled(false);setOnLongClickListener(new LongClick(this));}公共无效setDisableWebViewTouchListener(boolean z){this.check = z;}public boolean onTouchEvent(MotionEvent motionEvent){如果(this.check){返回false;}返回super.onTouchEvent(motionEvent);}公共布尔canScrollHorizo​​ntal(int i){intcomputeHorizo​​ntalScrollOffset = computeHorizo​​ntalScrollOffset();intcomputeHorizo​​ntalScrollRange = computeHorizo​​ntalScrollRange()-computeHorizo​​ntalScrollExtent();如果(computeHorizo​​ntalScrollRange == 0){返回false;}如果(i< 0){如果(computeHorizo​​ntalScrollOffset< = 0){返回false;}返回true;}否则,如果(computeHorizo​​ntalScrollOffset> = computeHorizo​​ntalScrollRange-1){返回false;} 别的 {返回true;}}@Override公共无效onMeasure(int widthMeasureSpec,int heightMeasureSpec){int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec,heightMeasureSpec_custom);ViewGroup.LayoutParams参数= getLayoutParams();params.height = getMeasuredHeight();}public boolean onDown(MotionEvent motionEvent){返回true;}公共无效onShowPress(MotionEvent motionEvent){}public boolean onSingleTapUp(MotionEvent motionEvent){返回false;}public boolean onScroll(MotionEvent motionEvent,MotionEvent motionEvent2,float f,float f2){返回f!= 0.0f;}公共无效onLongPress(MotionEvent motionEvent){}public boolean onFling(MotionEvent motionEvent,MotionEvent motionEvent2,float f,float f2){返回true;}} 

    如果有人遇到这种类型的问题,请使用此自定义类 TestSeriesOptionWebView.class .

    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?

    解决方案

    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.

    这篇关于如果将Webview作为子级,则布局onClick事件将不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆