我有一个 Fragment,它由一个覆盖在 FrameLayout 上的 Button 组成。第二个 ListView fragment 被插入到 FrameLayout 中。 ListView 正确滚动,除非触摸事件在 Button 顶部开始。 Button 的 onClick 监听器似乎拦截了下方 ListView 的滚动。如何让 Button 处理点击事件,但不处理滚动事件。
我有一个基本的解决方案,在 Button 上使用 GestureDetector 并将 onScroll 事件传递给 ListView 的 smoothScrollBy 函数。不过,这对于 fling 事件来说并不容易。
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 并且第二个 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 question和 also this .
关于Android按钮onClick拦截滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22841976/