近期做项目碰到ScrollView与Listview冲突的情况,查看了网上一些解决listview和scollView的冲突的方法,感觉效果不是很好,最终我选择了,自定义scollView的方法,完美解决了滑动冲突的问题:
先看效果图:
其实,实现起来很简单,相信大家都了解Android中事件传递机制了,就是在特定的时候进行拦截,在恰到的时候进行不拦截,就能完美的解决事件滑动冲突问题了。贴上我自定义scollView的代码,大家一看就懂:
/**
* Created by forget on 2017/5/17.
*/
public class ListScrollView extends ScrollView {
private ListView listView;
public ListScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListScrollView(Context context) {
super(context);
}
/**
* 覆写onInterceptTouchEvent方法,点击操作发生在ListView的区域的时候,
* 返回false让ScrollView的onTouchEvent接收不到MotionEvent,而是把Event传到下一级的控件中
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
if (listView != null && checkArea(listView, ev)) {
return false;
}
return super.onInterceptTouchEvent(ev);
}
/**
* 测试view是否在点击范围内
* @param v
* @return
*/
private boolean checkArea(View v, MotionEvent event){
float x = event.getRawX();
float y = event.getRawY();
int[] locate = new int[2];
v.getLocationOnScreen(locate);
int l = locate[0];
int r = l + v.getWidth();
int t = locate[1];
int b = t + v.getHeight();
if (l < x && x < r && t < y && y < b) {
return true;
}
return false;
}
public ListView getListView() {
return listView;
}
public void setListView(ListView listView) {
this.listView = listView;
}
}
(若有需要,可以直接拷贝去用即可)
这是activity中的代码:
public class MainActivity extends AppCompatActivity {
private ListScrollView mys;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mys = (ListScrollView) findViewById(R.id.mys);
listView = (ListView) findViewById(R.id.listView);
mys.setListView(listView);
String string = "ListItem";
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(string + i);
}
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.test_list_item, list);
listView.setAdapter(adapter);
}
}
在了解了Android的事件分发机制情况下,解决起来很简单,大家若有需要可以了解一下,推荐郭神写的博客,大家可以去看看。