【问题标题】:How do you draw a shape on a ListView in Android如何在 Android 的 ListView 上绘制形状
【发布时间】:2012-03-20 06:11:52
【问题描述】:

我正在构建一个“日视图”日历应用程序。我已经使用列表视图创建了空日历,现在需要添加我的约会。

我的光标已全部设置,我可以检索我的约会,只需在列表视图上绘制它们。棘手的部分是每个列表行是 30 分钟,我的一些约会可能会更长,长达几个小时。所以需要能够指定约会应该在列表视图的哪个位置绘制,即使它目前不在屏幕上。

【问题讨论】:

  • 你想根据一天24小时的预约时间绘制矩形块吗?
  • @Pavandroid 是的,没错。

标签: android calendar


【解决方案1】:

我也有同样的看法。我开发了自己的 CustomView 并将其保存在 ScrollView 中。这个 customView 的高度是 24 * 60 dip。所以视图的高度会随着我们保持 dip 而不是 px 而增加(我希望你知道 px 和 dip 之间的区别)并且宽度将是设备屏幕的宽度。

我无法与您分享完整的代码。但是,可以在这里部分粘贴。这将为您带来处理每件事的清晰画面。

public class CustomDayView extends View implements OnTouchListener{

    private Paint p;
    private Paint textp;
    private Paint roundRectP;
    private int parentWidth = 0;
    private int parentHeight = 0;
    private int X_OFFSET = 5;
    private int Y_OFFSET = 5;
    private int HOUR_BLOCK_HEIGHT = 60;
    private int font_max_width;
    private ScrollView _scrollView;
    private int least_time_in_hours = 24*60;//6 * 60
    private RectF _rects[];
    private int font_height;
    private Context context;


    public CustomDayEmployeeView(Context context) {
        super(context);
        this.context = context;
        init();
    }
    public CustomDayEmployeeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }
    public CustomDayEmployeeView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }
     private void init(){
         //Creating Paint Objects
     //setting color
         //setting Fonts
         this.setOnTouchListener(this);
     calculateRectValues();
     }

    private void calculateRectValues() {
        // Calculating the Rects to draw in the paint this includes x,y points starting of the rect and width and height of the rectangle.
    int font_max_width = calculate the width needed to draw the hours from 0 to 24 hours;
    for(int i=0;i<no of appts;i++)
        _rects[j] = new RectF(font_max_width, convertTimetoSeconds("09:30"), screenwidth-font_max_width , convertTimetoSeconds("11:30");

    }

    private int convertTimetoSeconds(String _startTime) {
        // TODO Auto-generated method stub
        int total = Integer.parseInt(_startTime.substring(0,_startTime.indexOf(":"))) * 60;
        total += Integer.parseInt(_startTime.substring(_startTime.indexOf(":")+1, _startTime.length()));
        return total;
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        calculateRectValues();
        setMeasuredDimension(screenwidth,24 * HOUR_BLOCK_HEIGHT);
    }


    public void draw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.draw(canvas);

        for(int i=0;i<25;i++)
        {
            String preString = "";
            String poststring = "";

            if(i == 12)
            {
                preString = "Noon";
                poststring = "";

            }
            else if(i%12 == 0)
            {
                preString = "12";
                poststring = " AM";
            }
            else if(i<12)
            {
                preString = i+"";
                poststring = " AM";
            }
            else
            {
                preString = i%12+"";
                poststring = " PM";
            }
            canvas.drawText(preString, X_OFFSET+3, i * HOUR_BLOCK_HEIGHT + font_height, p);
            canvas.drawText(poststring, X_OFFSET+p.measureText(preString), i * HOUR_BLOCK_HEIGHT + font_height, p);
            p.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
            p.setColor(Color.parseColor("#cbcaca"));
            p.setStrokeWidth(0.2f);
            p.setPathEffect(new DashPathEffect(new float[] {1,2}, 0));
            canvas.drawLine(font_max_width, i * (HOUR_BLOCK_HEIGHT)+ font_height/2+HOUR_BLOCK_HEIGHT/2, parentWidth-8, i * (HOUR_BLOCK_HEIGHT)+ font_height/2+HOUR_BLOCK_HEIGHT/2, p);
            p.setColor(Color.parseColor("#f1f1f1"));
            p.setPathEffect(new PathEffect());
            p.setStrokeWidth(0.2f);
            canvas.drawLine(font_max_width, i * HOUR_BLOCK_HEIGHT+ font_height/2, parentWidth-8, i * HOUR_BLOCK_HEIGHT+ font_height/2, p);

        }
            for(int j=0;j<no of appts;j++)
            {
                    canvas.drawRoundRect(_rects[j], 3, 3, roundRectP);
                        canvas.drawText(obj._title, _rects[j].left+X_OFFSET,_rects[j].top + font_height + Y_OFFSET, textp);
            }
        }
    }


    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        int x = (int) event.getX();
        int y = (int) event.getY();
        for(int j=0;j<no of appts;j++)
        {
            if(_rects[j].contains(x, y))
            {
        //Selected J appointmrnt
        }
        }
        return true;
    }
}

我认为这会对您有所帮助。只需创建 Object 并将约会传递给 ArrayList 以初始化该对象并对其进行所需的调整。

【讨论】:

  • 非常感谢您提供的代码,它很有帮助。一个问题,我看到你声明了一个ScrollView,但是你什么时候使用呢?
  • 其实我的项目有问题。我需要将视图滚动到此视图上可见的第一个约会。所以,为了滚动,我将滚动视图的对象从 MainActivity 发送到这个 CustomDayView。之后,我将其设为全局以利用它滚动到 CustomView 中的任何 x,y 点。
  • 有什么更新吗?如果正确,请选择此作为正确答案。
  • Pavandroid,这个示例非常有用,我在构建第一个自定义视图时将其用作指南。我现在正在为我的应用程序开发我的第三个自定义视图,并且可能会更频繁地使用自定义视图。更多的灵活性!谢谢!
  • @Pavandroid。我正在寻找同样的东西。我想知道,在哪里可以找到在我用来显示日常事件的列表视图上绘制事件的工作示例。
【解决方案2】:

如果不在屏幕上,则无需绘制任何内容。

我会以这种方式实现列表适配器:getItem(int position) 方法返回每个列表项表示的时间(实际上是时间间隔)。 getView(int position, View convertView, ViewGroup parent) 定义了哪些约会在给定位置对应项目的区间内,并根据此信息更新项目的视图。

您可能还需要an endless adapter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多