安卓按钮的onClick拦截了滚动

4
我有一个由Button覆盖在FrameLayout上的Fragment。第二个ListView Fragment被插入到FrameLayout中。ListView可以正确滚动,但如果触摸事件开始于Button上方,则Button的onClick监听器似乎会拦截下面ListView的滚动。如何使Button处理点击事件而不是滚动事件。
我有一个基本的解决方案,在Button上使用GestureDetector,并将onScroll事件传递给ListView的smoothScrollBy函数。但这对于fling事件并不容易起作用。 这个问题看起来很相似,尽管情况相反。我认为接受的答案并没有帮助我。
示例:

main_fragment.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/sub_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="80dp"
        android:layout_height="70dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="#999"
        android:text="Button" />

</RelativeLayout>

MainFragment 膨胀:

public class MainFragment extends Fragment {

    private static final String TAG = MainFragment.class.getSimpleName();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.main_fragment, container, false);

        Button button = (Button) view.findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "click");
            }
        });

        FragmentTransaction fragmentTransaction = getActivity()
                .getSupportFragmentManager().beginTransaction();
        ListFragment f = new ListFragment();
        fragmentTransaction.replace(R.id.sub_content, f);
        fragmentTransaction.commit();

        return view;
    }
}

按钮具有onClickListner,第二个片段被膨胀以替换FrameLayout的位置:

fragment_item_list.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

ListFragment 填充:

public class ListFragment extends Fragment {

    private static final String TAG = ListFragment.class.getSimpleName();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item_list,
                                     container, false);

        ListView listView = (ListView) view.findViewById(R.id.list);

        List<String> list = new ArrayList<String>();
        for (int i=0; i<30; i++) {
            list.add("Item: " + i);
        }
        MyAdapter adapter = new MyAdapter(getActivity(), list);
        listView.setAdapter(adapter);

        return view;
    }

    private class MyAdapter extends BaseAdapter {

        private List<String> items;
        private Context context;

        public MyAdapter(Context context, List<String> items) {
            this.items = items;
            this.context = context;
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public String getItem(int i) {
            return items.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int i, View convertView, ViewGroup parent) {
            if (convertView==null) {
                convertView = LayoutInflater.from(context).inflate(
                        R.layout.list_item, parent, false);
            }

            TextView textView = (TextView) convertView.findViewById(
                                R.id.list_item_text);
            textView.setText(getItem(i));

            return convertView;
        }
    }
}
1个回答

3
我找到的解决方案是取消按钮上的 onClickListener,并改为在按钮上使用 SimpleGestureDetector(请参见文档)。
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        clickButton();
        return true;
    }
}

当按钮在onTouchListener中实现时:

mDetector = new GestureDetectorCompat(getActivity(), new MyGestureListener());
button.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return mDetector.onTouchEvent(motionEvent)
               || dispatchTouchEvent(motionEvent);
    }
});

按钮通过接口将触摸事件传递给ListView(在dispatchTouchEvent函数中),并调用:

listView.dispatchTouchEvent(motionEvent)

有用的阅读材料包括这个SO问题还有这个


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