布局 onClick 事件如果将 Webview 作为子项则不起作用
Layout onClick event does not work if it has Webview as a child
我的问题是我有一个 LinearLayout
,我在运行时将其膨胀到 ScrollView
.
中的 LinearLayout
这是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>
& 这是 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>
这是我创建的用于直接显示 HTML
内容的 CustomTextView。 JustifiedTextView.class
是
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();
}
}
我已经尝试了下面提到的所有解决方案。
- Disable WebView touch events in Android
- 已经尝试将
android:descendantFocusability="blocksDescendants"
设置为 ScrollView
为什么点击 WebView
时 LinearLayout
的点击事件没有触发?
这就是我给 Layout
充气并处理点击事件的方式。
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;
}
为什么点击 Layout
中的 WebView
部分,点击没有被监听?
我终于找到问题了。
这基本上是 parent Scrollview
和 CustomWebView
.
冲突的问题 Touch Event
因此,通过使用新的 类,它本身会覆盖 ClickListener
和 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;
}
}
如果有人遇到此类问题,请使用此自定义 Class TestSeriesOptionWebView.class
。
我的问题是我有一个 LinearLayout
,我在运行时将其膨胀到 ScrollView
.
中的 LinearLayout
这是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>
& 这是 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>
这是我创建的用于直接显示 HTML
内容的 CustomTextView。 JustifiedTextView.class
是
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();
}
}
我已经尝试了下面提到的所有解决方案。
- Disable WebView touch events in Android
- 已经尝试将
android:descendantFocusability="blocksDescendants"
设置为ScrollView
为什么点击 WebView
时 LinearLayout
的点击事件没有触发?
这就是我给 Layout
充气并处理点击事件的方式。
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;
}
为什么点击 Layout
中的 WebView
部分,点击没有被监听?
我终于找到问题了。
这基本上是 parent Scrollview
和 CustomWebView
.
冲突的问题 Touch Event
因此,通过使用新的 类,它本身会覆盖 ClickListener
和 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;
}
}
如果有人遇到此类问题,请使用此自定义 Class TestSeriesOptionWebView.class
。