Android按钮onClick拦截滚动

标签 android listview android-fragments scroll

我有一个 Fragment,它由一个覆盖在 FrameLayout 上的 Button 组成。第二个 ListView fragment 被插入到 FrameLayout 中。 ListView 正确滚动,除非触摸事件在 Button 顶部开始。 Button 的 onClick 监听器似乎拦截了下方 ListView 的滚动。如何让 Button 处理点击事件,但不处理滚动事件。

我有一个基本的解决方案,在 Button 上使用 GestureDetector 并将 onScroll 事件传递给 ListView 的 smoothScrollBy 函数。不过,这对于 fling 事件来说并不容易。

This question尽管情况相反,但似乎相似。我认为已接受的答案对我没有帮助。

例子:

ma​​in_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;
    }
}

Button 有一个 onClickListener 并且第二个 fragment 被膨胀以代替 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;
        }
    }
}

最佳答案

我找到的解决方案是删除按钮上的 onClickListener 并在按钮上添加一个 SimpleGestureDetector(参见 the docs)。

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

然后 Button 通过接口(interface)(在 dispatchTouchEvent 函数内)将触摸事件传递给 ListView 并调用:

listView.dispatchTouchEvent(motionEvent)

有用的阅读包括this SO questionalso this .

关于Android按钮onClick拦截滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22841976/

相关文章:

android - ListView 中的动画列表项

android - 如何在 Android Activity 的元素周围绘制一个矩形框?

android - Android 中旋转设备后 Fragment 字段为 NULL

android - TelephonyManager.getCellLocation 在某些设备中崩溃请求 READ_PHONE_STATE 权限

java - 在 Android 上分析来自麦克风的声音(谐波、分音、泛音)

android - 如何结合使用 android 的 "openvpn connect"应用程序和 Intent 以编程方式连接和断开 vpn 连接?

android - Android 中自定义 ListView 中复选框的单击事件

java - Android AdView NoClassDefFoundError

java - 无法更新自定义适配器中的项目

android - 任何示例显示如何使用自己的按钮或 Facebook 按钮在 Android 中使用 Facebook SDK 4.0 登录?