【问题标题】:Android button onClick intercepts scrollAndroid按钮onClick拦截滚动
【发布时间】:2014-04-03 15:17:33
【问题描述】:

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

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

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

【问题讨论】:

    标签: android listview android-fragments scroll


    【解决方案1】:

    我找到的解决方案是删除按钮上的 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通过一个接口(在dispatchTouchEvent函数内部)将触摸事件传递给ListView并调用:

    listView.dispatchTouchEvent(motionEvent)
    

    有用的阅读包括this SO question和also this。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2019-04-07
      相关资源
      最近更新 更多