繁体   English   中英

具有2层时FrameLayout无法正确处理触摸请求

FrameLayout doesn't handle touch request correct when having 2 layers

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在尝试扩展FrameLayout以便能够确定要为哪个视图传递触摸事件:

myApp是这样的: 在此处输入图片说明

点在水平滚动视图中,矩形只是一个视图。 当您触摸点区域时,它就会滚动。 我希望矩形是可拖动的。 我一次可以做一次(我的意思是-如果框架只有一个孩子)。 但不是两者兼而有之。 我认为我需要重写:onInterceptTouchEvent,但没有设法将事件传递给Rectange View。 这是我的代码:activity_main.xml:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/LinearLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <com.example.trashproject.FrameWithTouchControl
            android:id="@+id/frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <View
                android:id="@+id/selector"
                android:layout_width="45dp"
                android:layout_height="match_parent"
                android:background="#33FF0000" >
            </View>

             <HorizontalScrollView
            android:id="@+id/horizontalScroll"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" >

            <TableLayout
                android:id="@+id/table"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:orientation="horizontal" >
            </TableLayout>
        </HorizontalScrollView>

        </com.example.trashproject.FrameWithTouchControl>
    </LinearLayout>

FrameWithTouchControl.java:

package com.example.trashproject;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;

public class FrameWithTouchControl extends FrameLayout {

    private static final String TAG ="FrameWithTouchControl" ;
    private float curSelectorPositionX1;
    private float curSelectorPositionX2;
    private boolean isDragging = false;
    private View mSelector;
    private int mTouchSlop;

    public FrameWithTouchControl(Context context) {
        super(context);
        init();

    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        initViewMembers();
    }


    public FrameWithTouchControl(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }


    public FrameWithTouchControl(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        init();
    }


    private void initViewMembers() {
        mSelector = this.findViewById(R.id.selector);

    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        // Always handle the case of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Release the scroll.
            isDragging = false;
            return false; // Do not intercept touch event, let the child handle it
        }
        curSelectorPositionX1 = mSelector.getLeft();
        curSelectorPositionX2 = mSelector.getRight();
        float evX = ev.getX();
        //if the touch is out of the selector's area
        if (evX >= curSelectorPositionX2 || evX <= curSelectorPositionX1) {
            return false;
        }

        switch (action) {
        case MotionEvent.ACTION_MOVE:
            if (isDragging) {
                // We're currently dragging, so yes, intercept the 
                // touch event!
                mSelector.onTouchEvent(ev);
                return true;
            }

            mSelector.onTouchEvent(ev);
            return true;



        }//switch
        return false;
    }//onIntercept
}

MainActivity.java:

package com.example.trashproject;

import java.util.Calendar;
import java.util.Random;

import android.content.ClipData;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
import android.widget.TextView;
public class MainActivity extends FragmentActivity{


    private static final int ROWS =8;
    private static final int COLS = 100;
    private static final String TAG = "MainActivity";
    private TableLayout mTable;
    private TextView[][] mCircles;
    private boolean[][] mData;
    private LayoutInflater mInflater;
    private FrameLayout mFrame;
    private View mSelector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mData = generateFakeGuestsTimes();
        mInflater =(LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        makeTable();
        mFrame = (FrameLayout) findViewById(R.id.frame);

        mSelector = findViewById(R.id.selector);
        mSelector.setOnTouchListener(new OnTouchListener() {

            boolean isDragging;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.d(TAG, "selector touch triggered" );
                Log.d(TAG, event.toString());
                int action = event.getAction();
                float deltaX = 0;
                if (action==MotionEvent.ACTION_DOWN && !isDragging) {
                    isDragging = true;
                    deltaX = event.getX();
                    return true;
                } else if (isDragging) {
                    if (action== MotionEvent.ACTION_MOVE) {
                        v.setX(v.getX() + event.getX() - deltaX);
                    } else if (action == MotionEvent.ACTION_CANCEL) {
                        isDragging = false;
                        return true;
                    } else if (action == MotionEvent.ACTION_UP) {
                        isDragging = false;
                        return false;
                    }
                }
                return false;
            }
        });


    }
/**** NOT RELEVANT FROM HERE *******/
    private boolean[][] generateFakeGuestsTimes() {
        boolean[][] values = new boolean[ROWS][COLS];
        Random rand = new Random();
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS    ; j++) {
                values[i][j] = rand.nextBoolean();
            }
        }
        return values;

    }
    public void onClick(View view) {
        Log.d(TAG, "numOfChildren" + mTable.getChildCount());
    }


    private void makeTable() {
        mTable = (TableLayout) findViewById(R.id.table);

        TableRow.LayoutParams rowParams = new TableRow.LayoutParams();
        rowParams.width = LayoutParams.WRAP_CONTENT;
        rowParams.height = 67;
        mCircles = new TextView[ROWS][COLS];
        final TableRow[] row = new TableRow[ROWS];
        final TextView[] headerText = new TextView[ROWS];
        long start = cal.getTimeInMillis();
        for (int i = 0; i < ROWS; i++) {
            row[i] = new TableRow(this);
            row[i].setLayoutParams(rowParams);
            for (int j = 0; j < COLS; j++) {
                mCircles[i][j] = (TextView) mInflater.inflate(R.layout.calendar_month_grid, null);
                if (mData[i][j]) {
                    mCircles[i][j].setBackgroundResource(R.drawable.small_circle);
                } else {                    
                    mCircles[i][j].setBackgroundResource(R.drawable.small_circle_red);
                }
                row[i].addView(mCircles[i][j]);
            }
            mTable.addView(row[i]);
        }//outer loop

        long end = cal.getTimeInMillis();
        Log.d(TAG, "time of operation=" + end + ", " + start + ", " + String.valueOf(end - start));
    }
1 个回复

我通过在FrameLayout中切换顺序解决了该问题。 显然,框架布局以相反的顺序设置图层。 即:

<FrameLAyout>
   <View1/>
   <View2/>
</FrameLAyout>

View2将位于上层。 View2将首先获取触摸回调,如果未处理触摸,则View1将获得呼叫。 即与图纸相同。 最底层是View1,最上层是View2。 说得通

1 停留在FrameLayout外部的视图不会拦截触摸事件

我在屏幕的左下角有相机拍摄的最后一张图像的缩略图。 在其左上角,我有一个X按钮来删除相机拍摄的最后一张图像。 当我尝试按下该按钮时,什么都没有发生,除非我按下它的右下角,否则该按钮仍位于其本来应该位于的范围之内: 这是我的布局 外观如下: 我该如何解决这个问题? ...

2016-06-09 10:06:24 1 100   android
3 FrameLayout 不适合屏幕

所以我正在开发一个应用程序,它使用 FrameLayout 作为片段容器,其内容取决于底部导航器上的所选项目。 我的问题是,由于某种原因,我无法让 FrameLayout 适合整个屏幕,因此每当我运行应用程序时,片段顶部总是有一个空白区域。 我试图改变长度,改变边距,但似乎没有任何效果。 我错过了什 ...

4 SHGetFileInfo没有返回正确的句柄图标

我正在使用SHGetFileInfo函数来获取文件夹和不同文件类型的图标。 根据MSDN ,此函数的调用应从后台线程完成,并且在调用之前必须使用CoInitialize或OleInitialize初始化组件对象模型(COM)。 我的代码如下所示: 通常,问题是在第一次调用代码后出现的 ...

5 如何正确处理多层触摸事件?

我目前有一个“ Console” CClayer,它正在处理已添加到其中的精灵的触摸检测。 不过,我也有一些精灵,我想要做的触摸检测上没有控制台层的一部分......目前,他们从CCNode继承的类的儿童。 我的理解是,cocos对象将“ isTouchEnabled”属性设置为true ...

6 Http请求没有给出正确的响应

我正在尝试发出http请求并以字符串形式获取整个页面。 得到响应后,我试图在其中找到子字符串的位置。 但是我在响应中找不到该子字符串,而原始网页在Google Chrome-&gt;查看源代码中包含该子字符串。 (已在移动版本中签入)。 因此,我的猜测是: 1)也许不要 ...

2014-01-15 19:18:35 2 70   android
7 触摸外部时弹出窗口不会隐藏

当我在一个空的地方点击时,我需要关闭弹出窗口,但是在滚动时,我需要显示一个弹出窗口。 现在,滚动时隐藏了我的弹出窗口,请帮助我解决此问题。 这是我的代码: 现在,当我滚动时会显示弹出窗口,但是当我在外部点击时弹出窗口不会隐藏。 ...

8 Bot 不处理 Http 请求

我已经使用 Microsoft Bot Framework 创建了 Bot 并希望它处理 http 请求。 根据这个文档,我创建了控制器,清除了 Get 方法主体(只为调用者留下了 ContentResult 的返回 - 我至少要处理请求),部署了机器人,但不断收到 500 内部服务器错误。 ...

9 FrameLayout不适合其空间

我是第一次使用NavigationBar小部件工作,因此无法将FrameLayout设置为不落后于NavigationBar。 我实际上已经尝试了所有方法:都在RelativeLayout(NavigationBar消失)中进行设置,我在StackOverflow周围找到的每个设置都没有成功。 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM