Android 在视图上拖动时的选择覆盖
我试图构建一个类似日历日程视图(用户可以通过拖动来选择的垂直小时列表)的视图,但我被困在用户开始在屏幕上按并在小时行上拖动手指来选择它们的部分。如何在表示小时数的视图上创建表示选择的am覆盖,并在用户拖动选择时展开/收缩它 我当前的界面由一个垂直的Android 在视图上拖动时的选择覆盖,android,android-layout,Android,Android Layout,我试图构建一个类似日历日程视图(用户可以通过拖动来选择的垂直小时列表)的视图,但我被困在用户开始在屏幕上按并在小时行上拖动手指来选择它们的部分。如何在表示小时数的视图上创建表示选择的am覆盖,并在用户拖动选择时展开/收缩它 我当前的界面由一个垂直的LinearLayout组成,其中包含空的textview占位符,表示一天中的小时数 我的屏幕是这样的: 每个绿色列都是线性布局,其中文本视图表示插槽。我想允许用户开始按下其中一个插槽并向下拖动以进行选择,在拖动过程中,有一个缩小/扩大以反映选择的覆
LinearLayout
组成,其中包含空的textview
占位符,表示一天中的小时数
我的屏幕是这样的:
每个绿色列都是
线性布局
,其中文本视图
表示插槽。我想允许用户开始按下其中一个插槽并向下拖动以进行选择,在拖动过程中,有一个缩小/扩大以反映选择的覆盖。我已通过扩展线性布局
并连接到绘图机制来解决此问题,如下所示:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class AvailabilityCalendarColumnLayout extends LinearLayout{
private Drawable overlay;
public AvailabilityCalendarColumnLayout(Context context) {
super(context);
setWillNotDraw(false);
}
public AvailabilityCalendarColumnLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
setWillNotDraw(false);
}
public AvailabilityCalendarColumnLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setWillNotDraw(false);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if(overlay != null) {
overlay.draw(canvas);
}
}
public boolean startSelectionOverlay(View startingView) {
if(startingView == null) {
return false;
}
overlay = getResources().getDrawable(R.drawable.overlay);
float[] l = new float[2];
l[0] = startingView.getX();
l[1] = startingView.getY();
int w = startingView.getWidth();
int h = startingView.getHeight();
overlay.setBounds((int) l[0], (int) l[1], (int) l[0] + w, (int) l[1] + h);
invalidate();
return true;
}
private void extendSelectionOverlay(View endView) {
if(endView == null) {
return;
}
float[] l = new float[2];
l[0] = endView.getX();
l[1] = endView.getY();
int w = endView.getWidth();
int h = endView.getHeight();
Rect r = overlay.getBounds();
r.bottom = (int)l[1] + h;
overlay.setBounds(r);
invalidate();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
float[] pos = new float[2];
pos[0] = ev.getX();
pos[1] = ev.getY();
if(action == MotionEvent.ACTION_DOWN && overlay == null) {
View view = getChildViewUnderPosition(pos);
if(view != null) {
startSelectionOverlay(view);
}
}
if(action == MotionEvent.ACTION_MOVE && overlay != null) {
View view = getChildViewUnderPosition(pos);
extendSelectionOverlay(view);
}
if(action == MotionEvent.ACTION_UP && overlay != null) {
endSelectionOverlay();
invalidate();
}
return true;
}
private View getChildViewUnderPosition(float[] pos) {
int num = getChildCount();
View v;
for(int x = 0; x < num; x++) {
v = getChildAt(x);
if(v.getX() <= pos[0] && (v.getX() + v.getWidth()) >= pos[0] && v.getY() <= pos[1] && (v.getY() + v.getHeight()) >= pos[1] && !v.isSelected()) {
return v;
}
}
return null;
}
private void endSelectionOverlay() {
overlay = null;
invalidate();
}
}
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Rect;
导入android.graphics.drawable.drawable;
导入android.support.v4.view.MotionEventCompat;
导入android.util.AttributeSet;
导入android.view.MotionEvent;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.LinearLayout;
公共类可用性CalendarColumnLayout扩展了LinearLayout{
专用可拉伸覆盖层;
公共可用性CalendarColumnLayout(上下文){
超级(上下文);
setWillNotDraw(假);
}
公共可用性CalendarColumnLayout(上下文、属性集属性){
这(上下文,属性,0);
setWillNotDraw(假);
}
公共可用性CalendarColumnLayout(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
setWillNotDraw(假);
}
@凌驾
受保护的void dispatchDraw(画布){
super.dispatchDraw(画布);
如果(覆盖!=null){
覆盖。绘制(画布);
}
}
公共布尔开始选择覆盖(视图开始视图){
if(startingView==null){
返回false;
}
overlay=getResources().getDrawable(R.drawable.overlay);
浮动[]l=新浮动[2];
l[0]=startingView.getX();
l[1]=startingView.getY();
int w=startingView.getWidth();
int h=startingView.getHeight();
重叠.立根((int)l[0],(int)l[1],(int)l[0]+w,(int)l[1]+h);
使无效();
返回true;
}
专用无效扩展选择覆盖(视图endView){
if(endView==null){
返回;
}
浮动[]l=新浮动[2];
l[0]=endView.getX();
l[1]=endView.getY();
int w=endView.getWidth();
int h=endView.getHeight();
Rect r=overlay.getBounds();
r、 底部=(int)l[1]+h;
重叠.立根(r);
使无效();
}
@凌驾
公共布尔值onInterceptTouchEvent(MotionEvent ev){
返回true;
}
@凌驾
公共事件(MotionEvent ev){
final int action=MotionEventCompat.getActionMasked(ev);
浮动[]位置=新浮动[2];
pos[0]=ev.getX();
pos[1]=ev.getY();
if(action==MotionEvent.action\u DOWN&&overlay==null){
视图=getChildViewUnderPosition(位置);
如果(视图!=null){
startSelectionOverlay(视图);
}
}
if(action==MotionEvent.action\u MOVE&&overlay!=null){
视图=getChildViewUnderPosition(位置);
扩展选择覆盖(视图);
}
if(action==MotionEvent.action\u UP&&overlay!=null){
endSelectionOverlay();
使无效();
}
返回true;
}
私有视图getChildViewUnderPosition(浮动[]位置){
int num=getChildCount();
观点五;
对于(int x=0;x
我不是在找拾荒者。我在一个拖动选择界面后。类似于谷歌在查看一周时的日历视图。如果你发布一些代码或信息,会更容易理解screenshots@SaiPhani看来这就是我想要的,谢谢。至少它会比我的好看:)