Android按钮onClick拦截滚动

时间:2014-04-03 15:17:34

标签: android listview android-fragments scroll

我有一个片段,它由一个覆盖在FrameLayout上的Button组成。第二个ListView片段插入到FrameLayout中。除非触摸事件在按钮顶部开始,否则ListView会正确滚动。 Button的onClick监听器似乎拦截了ListView下方的滚动。如何让Button进程单击事件,但不能滚动事件。

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

This question看似相似,尽管情况相反。我不认为接受的答案可以帮助我。

示例:

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

Button有一个onClickListener,第二个片段被膨胀代替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 个答案:

答案 0 :(得分:2)

我找到的解决方案是删除按钮上的onClickListener,而在Button上有一个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函数内)将touch事件传递给ListView并调用:

listView.dispatchTouchEvent(motionEvent)

有用的阅读材料包括this SO questionalso this