【问题标题】:How to select one particular view from group of view's?如何从一组视图中选择一个特定视图?
【发布时间】:2012-08-02 17:31:35
【问题描述】:

对于我需要开发的应用程序,当view 上的用户long press 必须弹出一个警报对话框时,我需要能够从ViewGroupselect one view,我将根据该对话框选择选项要求,这些是删除视图并更改该特定视图的背景颜色。我正在创建不同的自定义视图(自定义视图从视图扩展)并且它具有 Touchlistener。将这些视图动态附加到布局(RelativeLayout)。让我们假设我的布局有 3 个视图。

我的问题:

  • 我想从布局上的可用视图列表中选择一个视图。
  • 如何限制自定义视图大小而不是占用整个父视图。

我面临这样的问题:如果我为自定义视图设置背景颜色,请查看此图像,实际上我设置为布局背景颜色白色,此处自定义视图占据全屏。所以,无法看到父背景颜色。这里自定义视图大小的问题,无法限制自定义视图大小而不是占用整个父视图。即使我在自定义视图之外触摸,自定义视图的触摸侦听器也会触发。我想将那些触摸监听器限制在我的自定义视图中。..

主要要求: 最后我想像下图这样实现,现在我可以向布局添加更多自定义视图,但无法删除选定的视图。当我长按布局中的任何一个视图时,它应该会弹出一个带有两个按钮的警报对话框,如果我选择一个选定的视图应该删除另一个选择背景颜色更改。

RelaventCode:我正在向这样的布局添加视图。

findViewById(R.id.line).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        CustomView drawView = new CustomView(context);
        frame.addView(drawView);
   }
});

这是自定义视图:

public class CustomView extends View {

public CustomView (Context context) {
    super(context);
    init();
}
private void init() {

    Paint paint = new Paint();
    Paint pai = new Paint();         
    Path path = new Path();
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(5);
    path.lineTo(50, 100);       
}

@Override
public void onDraw(Canvas canvas) {
    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(Top_Point.x, Top_Point.y);
    path.lineTo(Right_Point.x, Right_Point.y);
    path.lineTo(Left_Point.x, Left_Point.y);
    path.lineTo(Top_Point.x, Top_Point.y);
    path.close();
    canvas.drawPath(path, Inner_Paint);
    canvas.drawLine(Top_Point.x, Top_Point.y, Right_Point.x, Right_Point.y,
            Lines_Paint);
    canvas.drawLine(Right_Point.x, Right_Point.y, Left_Point.x,
            Left_Point.y, Lines_Paint);
    canvas.drawLine(Left_Point.x, Left_Point.y, Top_Point.x, Top_Point.y,
            Lines_Paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {     
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        PointF NewP = new PointF(0, 0);
        NewP.x = event.getX();
        NewP.y = event.getY();
        if (TopTouchArea.contains(event.getX(), event.getY())) {
            currentTouch = TOUCH_TOP;
        } else if (RightTouchArea.contains(event.getX(), event.getY())) {
            currentTouch = TOUCH_RIGHT;
        } else if (LeftTouchArea.contains(event.getX(), event.getY())) {
            currentTouch = TOUCH_LEFT;
        } else if (a) {
            Translate_Point.x = event.getX();
            Translate_Point.y = event.getY();
            currentTouch = Inner_Touch;
            return true; // Return false if user touches none of the
                            // corners
        } else {
            return false;
        }

        return true; 
    case MotionEvent.ACTION_MOVE:
        switch (currentTouch) {
        case TOUCH_TOP:
               /*  ------ */
        case TOUCH_RIGHT:
               /*   ----- */
            invalidate();
            return true;
        case TOUCH_LEFT:
         /* ------ */
            invalidate();
            return true;
        case Inner_Touch:
            /* ------ */
            invalidate();
            return true;
        }           
        return false; 
    case MotionEvent.ACTION_UP:         
        switch (currentTouch) {
        case TOUCH_TOP:
            /* ----- */
            return true;
        case TOUCH_RIGHT:
            /* ----- */
            return true;
        case TOUCH_LEFT:
            /* ----- */
            return true;
        case Inner_Touch:
            /* ----- */
            invalidate();  
        return true;
        }           
        return false;
    }
    return super.onTouchEvent(event);
}

【问题讨论】:

  • 如果没有看到相关代码,我们无法为您提供帮助。也许有人会猜测发生了什么,但也许不会……
  • @Sam 我用相关代码更新了我的问题。如果不清楚,请告诉我。

标签: android ontouchlistener onlongclicklistener custom-view


【解决方案1】:

您应该重写 onSizeChangedonMeasure 方法,让您的 ViewGroup 知道您的视图大小。并确保您的视图的宽度和高度都是WRAP_CONTENT

关于触摸事件 - 这里的问题是您的视图大小与父大小匹配,因此它会拦截所有触摸事件(因为它在 onTouchEvent 中返回 true)。

这里是a great tutorial

【讨论】:

  • 我将通过使用 Touch Listener's 在自定义视图上拉点来动态更改这些自定义视图大小..
  • @RajaReddyP 那么您应该在onMeasure 方法中准确更改视图大小。因此,在您的触摸侦听器中,您正在设置所需的属性并强制视图调用onMeasure(但不要直接调用它)。通过这种方法,您可以告诉布局您的视图有多大。
  • 我不知道如何设置这些功能,我没有Customview的经验。
  • 我在 google 中搜索我发现了这个,由于该视图中的 touch-liseners 无法触发长按,我不确定它是否正确..
  • 请参阅我的回答中的教程。这是关于自定义视图的分步教程。
【解决方案2】:

在将自定义视图添加到视图组之前将其添加到 OnLongClickListener。

为了帮助在更高级别识别视图,您可能希望使用 setTag("id", id); 在视图上设置标识符

【讨论】:

  • 我试过这样,首先无法从视图列表中选择一个特定视图。这是主要问题
  • 您的意思是用户界面有问题,还是您无法确定点击了哪个视图?要确定您点击了哪个视图,您可以从 view.getTag("id"); 中检索标识符
  • 不是 UI 问题,无法从视图组中选择视图。让我们假设我有 3 个自定义视图的布局现在我想在长按视图时选择一个视图。即使我为每个未触发的自定义视图添加了长按代码,它总是只调用触摸监听器。
  • 所以您添加自定义视图的视图组有一个触摸监听器?
  • 如果我将触摸监听器添加到主要活动中,我该如何实现。我尝试在主要活动上添加长按,但没有成功。
【解决方案3】:

如果我理解正确,您添加的视图太大并填充了它的父视图。
做这样的事情还不够

TwoPointsDraw drawView = new TwoPointsDraw(context);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT);
drawView.setLayoutParams(lp)
frame.addView(drawView); 

【讨论】:

    【解决方案4】:

    查看这个项目,它可能会有所帮助 => Android multitouch controller,一个简单的 Android 多点触控缩放库。

    这是另一个example

    【讨论】:

    • 我不是在寻找多点触控,如果我知道如何从中选择一个..
    • 有一个库 MTController 和一个示例 MTPhotoSortr。只需在模拟器中运行此示例并检查。一个视图中有 2-3 个图像,它会在您触摸时选择。所以这个逻辑可能有助于你实现你想要的。
    猜你喜欢
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多