如何在Fragment中处理触摸事件?

61

我正在构建一个界面,需要处理触摸事件。特别地,我希望能够仅将其启用于碎片中的受限区域。

为了更好地理解问题、遵守标准并实现应用目标,我计划使用导航抽屉来管理许多碎片而非活动。实现具有触摸事件的活动相当容易,但是我在网上阅读到对于碎片可能会出现问题。

我的应用程序在架构层次上如下: - MainActivity.java - NavigationDrawer.java - TestFragment.java(现在只有一个碎片,在等待解决问题)

我没有找到解决方案或教程,可以很好地解释该如何做(或者规避问题)。因此,我简化问题为“仅在碎片中启用触摸事件(在此情况下使用getPressure()函数)”。以下是一些可能有助于解决问题的代码片段:

TestFragment

public class TestFragment extends Fragment {
    private static final String ARG_SECTION_NUMBER = "section_number";

    public static TestFragment newInstance(int sectionNumber) {
        TestFragment fragment = new TestFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public TestFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_test, container, false);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Here I want to return the press value (0 to 1)
    }
}

如何将监听器与整个片段关联?在特定区域的情况下呢?最后,如何返回屏幕上的压力值?

非常感谢您的帮助! :)


顺便说一下,在我的公司里,我们有一个 class MainActivity extends Activity,以及许多 Fragments。我们遇到的一个主要问题是:我们无法使片段的导航堆栈(又称后退堆栈)按照我们想要的方式工作(我认为 iOS 做得更好),因此我们最终在自己的代码中管理片段和后退按钮。也就是说,我们跟踪片段,并且当后退按钮被按下时,自己决定要返回哪里。(如果片段 A 链接到子片段 B1,B1 又链接到同级/同辈片段 B2,在某些情况下,我们希望后退返回到 A,而不是 B1) - ToolmakerSteve
我认为这个问题的一个答案在这里: https://dev59.com/L2gu5IYBdhLWcg3w46-5#11001443 - JAvAd
2个回答

125

我不确定我是否理解了你的问题,但我会尝试回答。所以要在片段上获取触摸事件,我会这样做:

- 在你的片段onCreateView方法中:

View view = inflater.inflate(R.layout.fragment_test, container, false);

    view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {

                if(event.getAction() == MotionEvent.ACTION_MOVE){
                    //do something
                }
                return true;
            }
    });

//here the rest of your code

return view;

你可以在onTouch中检查不同的MotionEvents,例如:

MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP,...

谢谢! :) 我已经按照你写的做了,但是Android Studio说方法调用 'view.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, [...] 可能会产生空指针异常。你有什么解决这个问题的想法吗? - user3319400
1
我认为你不必担心那个警告,我在Eclipse中使用过这种方法,它没有显示任何警告,并且我一直以这种方式使用它而没有遇到任何问题。 - intips
7
你也可以在你的Fragment中实现onTouch方法,并使用view.setOnTouchListener(this) - Ivan Black
3
为了澄清Ivan Black的评论:在你的代码片段开头处:public class YourFragmentName implements View.OnTouchListener。你的代码片段内的某个地方有一个方法public boolean onTouch(View v, MotionEvent event) { ... },然后你需要用view.setOnTouchListener(this)将它连接到你的视图中。 - ToolmakerSteve
1
仍没有我运气好:rootView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN){ Toast.makeText(getActivity(), "你刚刚触摸了屏幕:-)", Toast.LENGTH_SHORT).show(); } return true; } }); - Vishal Patel

4
在Kotlin中:
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

   val view =  inflater.inflate(R.layout.fragment_img_view, container, false)

    view.setOnTouchListener(object : View.OnTouchListener {
        override fun onTouch(v: View?, event: MotionEvent): Boolean {
            if (event.action == MotionEvent.ACTION_MOVE) {
                scaleGestureDetector.onTouchEvent(event)
            }
            return true
        }
    })
    return view
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接