On touch event for a lienar layout multiple screens pops up. It seems that the ontouch event gets fired twice for each child element of the linear layout. How can I prevent this from firing twice. On click event for the same linear layout causes, the linear layout onclick event to be fired on second click and not on the first click. I am not understanding where I am going wrong. Please help.
-- XML
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:weightSum="1.0" >
<LinearLayout
android:id="@+id/layout_button_sub"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/Home.Item.Spacing.Vertical"
android:layout_marginLeft="@dimen/Home.Item.Spacing.Horizontal"
android:layout_marginRight="@dimen/Home.Item.Spacing.Horizontal"
android:layout_marginTop="@dimen/Home.Item.Spacing.Vertical"
android:layout_weight="0.5"
android:background="@drawable/bg_home_item"
android:clickable="true"
android:descendantFocusability="blocksDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
android:inputType="none" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="false"
android:focusableInTouchMode="false"
android:src="@drawable/ic_subs" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:duplicateParentState="false"
android:focusableInTouchMode="false"
android:gravity="right"
android:inputType="none"
android:text="Subscriptions"
android:textColor="@color/White"
android:textSize="@dimen/Normal.Text.Size" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_button_find"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/Home.Item.Spacing.Vertical"
android:layout_marginLeft="@dimen/Home.Item.Spacing.Horizontal"
android:layout_marginRight="@dimen/Home.Item.Spacing.Horizontal"
android:layout_marginTop="@dimen/Home.Item.Spacing.Vertical"
android:layout_weight="0.5"
android:background="@drawable/bg_home_item"
android:clickable="true"
android:descendantFocusability="blocksDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
android:inputType="none">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="false"
android:focusableInTouchMode="false"
android:src="@drawable/ic_find" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:duplicateParentState="false"
android:focusableInTouchMode="false"
android:gravity="right"
android:inputType="none"
android:text="Find Nearby"
android:textColor="@color/White"
android:textSize="@dimen/Normal.Text.Size" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
-- Activity on Oncreate method
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
linearLayoutSubs = (LinearLayout)findViewById(R.id.layout_button_sub);
linearLayoutFind = (LinearLayout)findViewById(R.id.layout_button_find);
linearLayoutSubs.setOnTouchListener(new mOnTouchListener());
linearLayoutFind.setOnTouchListener(new mOnTouchListener());
}
-- onTouch listener
public class mOnTouchListener implements OnTouchListener {
Intent intent = null;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId()) {
case R.id.layout_button_subscriptions:
intent = new Intent(AppActivity.this, Subs.class);//class for navigation
break;
case R.id.layout_button_find_nearby:
intent = new Intent(AppActivity.this, Find.class);//class for navigation
break;
}
if(intent != null) {
startActivity(intent);
}
return true;
}
}
First, remove android:focusable="true"
and android:focusableInTouchMode="true"
from layout_button_sub
and layout_button_find
in your layout xml.
This prevents the first touch/click event from being consumed by a focus change.
Then, change your OnTouchListener
to an OnClickListener
:
private class mOnClickListener implements OnClickListener
{
Intent intent;
public void onClick(View v)
{
switch (v.getId())
{
case R.id.layout_button_sub:
intent = new Intent(AppActivity.this, Subs.class);
break;
case R.id.layout_button_find:
intent = new Intent(AppActivity.this, Find.class);
break;
}
if (intent != null)
{
startActivity(intent);
}
}
}
And set it as such for your LinearLayouts:
mOnClickListener listener = new mOnClickListener();
linearLayoutSubs.setOnClickListener(listener);
linearLayoutFind.setOnClickListener(listener);
The onTouch()
event fires on several MotionEvents: ACTION_DOWN
, ACTION_MOVE
, etc. Every time you "clicked" with an OnTouchListener
, the method was firing, at minimum, once when you put your finger down and once when you lifted your finger. Since your original onTouch()
method didn't account for the different actions, startActivity()
was being called for every touch event.
I guess the problem is because you have not defined actions MOVE, UP and DOWN for the touch. Try writing your code in MotionEvent.ACTION_DOWN, If this works for you.
case R.id.layout_button_subscriptions:{
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
{
break;
}
case MotionEvent.ACTION_DOWN: {
startActivity(new Intent(AppActivity.this,Subs.class));
break;
}
}
First mistake from the code I can see is that you are setting on touch listener twice, instead of the do following
mOnTouchListener listener = new mOnTouchListener();
linearLayoutSubs.setOnTouchListener(listener);
linearLayoutFind.setOnTouchListener(listener);
if possible use the if else condition in the onTouch and whenever the onTouch has happend return true from that position only.
since many times it's not returning from that position and hence the event is fired twice.
来源:https://stackoverflow.com/questions/19442082/how-to-prevent-ontouch-for-parent-linear-layout-from-executing-multiple-times-ch