How to prevent onTouch for parent Linear Layout fr

2019-03-05 12:38发布

问题:

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;
    }
}

回答1:

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.



回答2:

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;
                    }
    }


回答3:

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.