项目中要实现一个拖拽FM收藏夹的功能。没能力自己实现,只能各种搜索,发现可以采用谷歌原生提供的SlidingDrawer控件。
SlidingDrawer在后面的Android SDK版本中已经不再支持。但是如果apk最小sdk可以向下兼容的话,还是可以使用的。
用这个控件来实现拖拽动画即抽屉视效还是比较方便的。
但是,要满足项目要求,还是需要继承SlidingDrawer类,并修改覆盖一些方法。
目标视效如下:
SlidingDrawer控件,定义布局时必须定义id为handle和content的两个部分,handle部分相应拖拽,content部分则是之前隐藏,拖拽后显示出来的部分。
继承并修改SlidingDrawer类主要是为了实现,只有分割线上方部分可以拖拽,同事分割线下方的按钮控件,可以接收点击事件。
package com.quicinc.fmradio;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.SlidingDrawer;
public class FMSlidingDrawer extends SlidingDrawer {
private int mHandleId = 0; // 抽屉行为控件ID
private int[] mTouchableIds = null; // Handle 部分其他控件ID
private boolean isSlidingLock = false;
public int[] getTouchableIds() {
return mTouchableIds;
}
public void setTouchableIds(int[] mTouchableIds) {
this.mTouchableIds = mTouchableIds;
}
public int getHandleId() {
return mHandleId;
}
public void setHandleId(int mHandleId) {
this.mHandleId = mHandleId;
}
public void setSlidingLock(boolean isSlidingLock) {
this.isSlidingLock = isSlidingLock;
}
public FMSlidingDrawer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FMSlidingDrawer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/*
* 获取控件的屏幕区域
*/
public Rect getRectOnScreen(View view) {
Rect rect = new Rect();
int[] location = new int[2];
View parent = view;
if (view.getParent() instanceof View) {
parent = (View) view.getParent();
}
parent.getLocationOnScreen(location);
view.getHitRect(rect);
rect.offset(location[0], location[1]);
return rect;
}
public boolean onInterceptTouchEvent(MotionEvent event) {
// 触摸位置转换为屏幕坐标
int[] location = new int[2];
int x = (int) event.getX();
int y = (int) event.getY();
this.getLocationOnScreen(location);
x += location[0];
y += location[1];
Log.i("MySlidingDrawer ", "isSlidingLock=" + isSlidingLock);
// handle部分独立按钮
if (mTouchableIds != null) {
for (int id : mTouchableIds) {
View view = findViewById(id);
Rect rect = getRectOnScreen(view);
if (rect.contains(x, y)) {
return false;
}
}
}
// 抽屉行为控件
if (event.getAction() == MotionEvent.ACTION_DOWN && mHandleId != 0) {
View view = findViewById(mHandleId);
Log.i("MySlidingDrawer on touch", String.format("%d,%d", x, y));
Rect rect = getRectOnScreen(view);
Log.i("MySlidingDrawer handle screen rect", String
.format("%d,%d %d,%d", rect.left, rect.top, rect.right,
rect.bottom));
if (rect.contains(x, y)) {// 点击抽屉控件时交由系统处理
Log.i("MySlidingDrawer", "Hit handle");
} else {
return false;
}
}
if(event.getAction()==MotionEvent.ACTION_UP){
View view2 = findViewById(mHandleId);
Rect rect = getRectOnScreen(view2);
if (rect.contains(x, y)) {
Log.i("MySlidingDrawer", "Hit handle");
} else {
return false;
}
}
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int[] location = new int[2];
int x = (int) event.getX();
int y = (int) event.getY();
this.getLocationOnScreen(location);
x += location[0];
y += location[1];
Log.i("MySlidingDrawer on touch", "Action=" + event.getAction());
if((isSlidingLock==true)&&(event.getAction()==MotionEvent.ACTION_MOVE))
{
Log.i("MySlidingDrawer", "ACTION_MOVE");
return true;
}
if((isSlidingLock==true)&&(event.getAction()==MotionEvent.ACTION_UP)){
View view = findViewById(mHandleId);
Rect rect = getRectOnScreen(view);
if (rect.contains(x, y)) {
Log.i("MySlidingDrawer", "ACTION_UP");
return true;
}
}
return super.onTouchEvent(event);
}
}
记录这些,供以后查看。