一、实现的效果:
在滑动(上画、下滑)时不加载控件菜单,或者不滑动是加载!
用到的类:WindowManager界面管理类:
二、案例实现:
1、效果:
2、背景:
scrollview没有像listview的滑动的onscrolllinner的监控,所以就要以handler的异步操作来进行操作!
3、实现:
(1)、listview的滑动监控:
sv.setOnTouchListener(new OnTouchListener() {
private int lastY;
@Override
public boolean onTouch(View v, MotionEvent event) {
float y = event.getY();
switch (event.getAction()) {
// 上滑动
case MotionEvent.ACTION_UP:
lastY = sv.getScrollY();
break;
// 第一次按下时的操作
case MotionEvent.ACTION_DOWN:
fist_down_Y = y;
System.out.println("!!!!第一次按下时的操作"+fist_down_Y);
break;
// 滑动效果
case MotionEvent.ACTION_MOVE:
System.out.println("??????第一次按下时的操作"+fist_down_Y);
// 向上滑动,隐藏搜索栏
if (fist_down_Y - y > 250 && floatlayout.isShown()) {
floatlayout.setVisibility(view.GONE);
}
// 向下滑动,显示搜索栏
if (y - fist_down_Y > 250 && !floatlayout.isShown()) {
floatlayout.setVisibility(view.VISIBLE);
}
break;
}
return false;
}
});
/在scrollview中,MotionEvent.ACTION_DOWN时不执行,导致没法进行操作:
sv.setOnTouchListener(new OnTouchListener() {
private int lastY = 0;
private int touchEventId = -9983761;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
View scroller = (View) msg.obj;
if (msg.what == touchEventId) {
if (lastY == scroller.getScrollY()) {
//停止了,此处你的操作业务
floatlayout.setVisibility(view.VISIBLE);
} else {
//floatlayout.setVisibility(view.GONE);
handler.sendMessageDelayed(handler.obtainMessage(touchEventId, scroller), 1);
lastY = scroller.getScrollY();
}
}
}
};
@Override
public boolean onTouch(View v, MotionEvent event) {
isScoll = false;
int eventAction = event.getAction();
int y = (int) event.getRawY();
switch (eventAction) {
case MotionEvent.ACTION_UP:
handler.sendMessageDelayed(handler.obtainMessage(touchEventId, v), 5);
break;
case MotionEvent.ACTION_MOVE:
floatlayout.setVisibility(view.GONE);
break;
default:
break;
}
return false;
}
});
}
三、悬浮框的实现:windowmanger+view
(1)、权限添加:
(2)、将view引入windowmanger中进行展示(全局变量)
// 悬浮框
view = LayoutInflater.from(this).inflate(R.layout.myindexheadlayout,
null);
mTopLayout = (LinearLayout) view.findViewById(R.id.index_top_layout);
mSearchBox = (EditText) view.findViewById(R.id.index_search_edit);
mCamerButton = (ImageButton) view.findViewById(R.id.index_camer_button);
mTopLayout.setVisibility(View.VISIBLE);
/// 引入:
private void createview() {
// 获取WindowManager
wm = (WindowManager) getApplicationContext().getSystemService("window");
// 设置LayoutParams(全局变量)相关参数
BaseApplication myapplication = (BaseApplication) getApplication();
wmParams = myapplication.getMywmParams();
wmParams.type = 2002;
wmParams.flags |= 8;
wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角
// 以屏幕左上角为原点,设置x、y初始值
wmParams.x = 0;
wmParams.y = 0;
// 设置悬浮窗口长宽数据
wmParams.width = WindowManager.LayoutParams.FILL_PARENT;
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
wmParams.format = 1;
wm.addView(view, wmParams);
}
四、注意点:
(1)、scrollview的ontuch的事件的Movition.Down的事件不起作用?
解决:重写控件的方法:
public void commOnTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
y = ev.getY();
break;
case MotionEvent.ACTION_UP:
if (isNeedAnimation()) {
animation();
}
y = DEFAULT_POSITION;
break;
/**
* 排除第一次移动计算,因为第一次无法得知y左边,在MotionEvent.ACTION_DOWN中获取不到,
* 因为此时是MyScrollView的Tocuh时间传递到了ListView的孩子item上面。所以从第二次开始计算
* 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归零,之后记录准确了就正常执行
*/
case MotionEvent.ACTION_MOVE:
float preY = y;
float nowY = ev.getY();
if (isDefaultPosition(y)) {
preY = nowY;
}
int deltaY = (int) (preY - nowY);
scrollBy(0, deltaY);
y = nowY;
// 当滚动到最上或者最下时就不会再滚动,这时移动布局
if (isNeedMove()) {
if (normal.isEmpty()) {
// 保存正常的布局位置
normal.set(inner.getLeft(), inner.getTop(),
inner.getRight(), inner.getBottom());
}
// 移动布局
inner.layout(inner.getLeft(), inner.getTop() - deltaY,
inner.getRight(), inner.getBottom() - deltaY);
}
break;
default:
break;
}
}
(2)、在java代码中设置控件的布局属性:
报错:java.lang.ClassCastException: android.widget.LinearLayout
LayoutParamscannotbecasttoandroid.widget.RelativeLayout
LayoutParams
解决:你的布局文件头部是啥?
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, mTopLayout.getHeight(), 0, 0);
abscrollview.setLayoutParams(layoutParams);