草庐IT

android - 如何在自定义日历 View 中选择多个日期?

coder 2023-11-28 原文

我正在 android 中制作自定义日历我的要求是选择多个日期与图像中显示的相同,任何人都有任何建议。直到现在我在 View 上制作日历并尝试根据触摸绘制路径但它对我不起作用.这是我的代码:-

public class CalendarView extends View {

private float width; // width of one tile
private float height; // height of one tile
private int selX; // X index of selection
private int selY; // Y index of selection
private final Rect selRect = new Rect();
private GregorianCalendar month, itemmonth;// calendar instances.
private CalendarAdapter adapter;// adapter instance
private Context mContext ;
private GregorianCalendar pmonthmaxset;
private GregorianCalendar selectedDate;
private ArrayList<String> items;
private  List<String> dayString;
private GregorianCalendar pmonth; // calendar instance for previous month
/**
 * calendar instance for previous month for getting complete view
 */
private int firstDay;
private int maxWeeknumber;
private int maxP;
private int calMaxP;
private int lastWeekDay;
private int leftDays;
private int mnthlength;
private String itemvalue, curentDateString;
private DateFormat df;
private Canvas macanvas;
private Path mpath;
private float cselX; // X index of selection
private float cselY; // Y index of selection

public CalendarView(Context context) {
    super(context);

    mpath = new Path();
    RectF mrectf = new RectF(selRect);
    //mpath.ad

    month = (GregorianCalendar) GregorianCalendar.getInstance();
    itemmonth = (GregorianCalendar) month.clone();
    Locale.setDefault(Locale.US);
    selectedDate = (GregorianCalendar) month.clone();
    mContext = context;
    month.set(GregorianCalendar.DAY_OF_MONTH, 1);
    this.items = new ArrayList<String>();
    df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    curentDateString = df.format(selectedDate.getTime());
    dayString= new ArrayList<String>();
    macanvas = new Canvas();
    refreshDays();


}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    width = w / 7f;
    height = (w)/(7f);
    getRect(selX, selY, selRect);
    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {

    // Draw the background...
      Paint background = new Paint();
      background.setColor( Color.GRAY);
      canvas.drawRect(0, 0, getWidth(), getHeight(), background);


      // Draw the board...

      // Define colors for the grid lines
      Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);
      foreground.setColor(Color.RED);
      Paint dark = new Paint();
      dark.setColor(Color.BLUE);
      Paint hilite = new Paint();
      hilite.setColor(Color.BLUE);
      Paint light = new Paint();
      light.setColor(Color.BLUE);
      // Draw the minor grid lines
      for (int i = 0; i < 6; i++) {
         canvas.drawLine(0, i * height, getWidth(), i * height,
               light);
         canvas.drawLine(0, i * height + 1, getWidth(), i * height
                   + 1, hilite);

      }
      for (int i = 0; i < 8; i++) {

          canvas.drawLine(i * width, 0, i * width,width*5,
                   light);
          canvas.drawLine(i * width+1, 0, i * width+1,width*5,
                   light);
    }

      foreground.setColor(Color.RED);
      foreground.setStyle(Style.FILL);
      foreground.setTextSize(height * 0.75f);
      foreground.setTextScaleX(width / height);
      foreground.setTextAlign(Paint.Align.CENTER);

      // Draw the number in the center of the tile
      FontMetrics fm = foreground.getFontMetrics();
      // Centering in X: use alignment (and X at midpoint)
      float x = width / 2;
      // Centering in Y: measure ascent/descent first
      float y = height / 2 - (fm.ascent + fm.descent) / 2;

    int k =0;
    for (int i = 0; i < 7; i++) {
         for (int j = 0; j < 5; j++) {
             String datevalue = fillDate(k++);
            canvas.drawText(datevalue, i
                  * width + x, j * height + y, foreground);

         }
      }

    if(mpath!=null)
    {
      Paint selected = new Paint();
      selected.setColor(Color.GREEN);
      canvas.drawPath(mpath,selected);
      // canvas.drawCircle(x, y, 25, selected);
    }

    super.onDraw(canvas);
}

private void getRect(int x, int y, Rect rect) {
      rect.set((int) (x * width), (int) (y * height), (int) (x
            * width + width), (int) (y * height + height));
   }

public String fillDate(int index)
{
    String date = "";

        // separates daystring into parts.
        String[] separatedTime = dayString.get(index).split("-");
        // taking last part of date. ie; 2 from 2012-12-02
        String gridvalue = separatedTime[2].replaceFirst("^0*", "");
        // checking whether the day is in current month or not.
        if ((Integer.parseInt(gridvalue) > 1) && (index < firstDay)) {
            // setting offdays to white color.
            //dayView.setTextColor(Color.WHITE);
            //dayView.setClickable(false);
            //dayView.setFocusable(false);
        }
        else if ((Integer.parseInt(gridvalue) < 7) && (index > 28)) {
            //dayView.setTextColor(Color.WHITE);
            //dayView.setClickable(false);
            //dayView.setFocusable(false);
        } else {
            // setting curent month's days in blue color.
            //dayView.setTextColor(Color.BLUE);
        }

        if (dayString.get(index).equals(curentDateString)) {
            //setSelected(v);
            //previousView = v;
        } else {
            //v.setBackgroundResource(R.drawable.list_item_background);
        }

    return gridvalue;

}

public void refreshDays() {
    // clear items
    items.clear();
    dayString.clear();
    Locale.setDefault(Locale.US);
    pmonth = (GregorianCalendar) month.clone();
    // month start day. ie; sun, mon, etc
    firstDay = month.get(GregorianCalendar.DAY_OF_WEEK);
    // finding number of weeks in current month.
    maxWeeknumber = month.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH);
    // allocating maximum row number for the gridview.
    mnthlength = maxWeeknumber * 7;
    maxP = getMaxP(); // previous month maximum day 31,30....
    calMaxP = maxP - (firstDay - 1);// calendar offday starting 24,25 ...
    /**
     * Calendar instance for getting a complete gridview including the three
     * month's (previous,current,next) dates.
     */
    pmonthmaxset = (GregorianCalendar) pmonth.clone();
    /**
     * setting the start date as previous month's required date.
     */
    pmonthmaxset.set(GregorianCalendar.DAY_OF_MONTH, calMaxP + 1);

    /**
     * filling calendar gridview.
     */
    for (int n = 0; n < mnthlength; n++) {

        itemvalue = df.format(pmonthmaxset.getTime());
        pmonthmaxset.add(GregorianCalendar.DATE, 1);
        dayString.add(itemvalue);

    }
}

private int getMaxP() {
    int maxP;
    if (month.get(GregorianCalendar.MONTH) == month
            .getActualMinimum(GregorianCalendar.MONTH)) {
        pmonth.set((month.get(GregorianCalendar.YEAR) - 1),
                month.getActualMaximum(GregorianCalendar.MONTH), 1);
    } else {
        pmonth.set(GregorianCalendar.MONTH,
                month.get(GregorianCalendar.MONTH) - 1);
    }
    maxP = pmonth.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);

    return maxP;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    switch(event.getAction())
    {

    case MotionEvent.ACTION_DOWN:
         //select((int) (event.getX() / width),
                   // (int) (event.getY() / height));
          mpath.moveTo(event.getX(), event.getY());
          mpath.lineTo(event.getX(), event.getY());

        break;
    case MotionEvent.ACTION_MOVE:
        invalidate();
         cselX = event.getX();
         cselY = event.getY();
         mpath.lineTo(cselX,cselY);
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        break;

    }
    return true;
}

private void select(int x, int y) {
     selX = Math.min(Math.max(x, 0), 8);
     selY = Math.min(Math.max(y, 0), 8);
     getRect(selX, selY, selRect);

      invalidate(selRect);
   }

最佳答案

您可以取消选择日期,添加到数组,然后用户选择第二个日期...

关于android - 如何在自定义日历 View 中选择多个日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17695520/

有关android - 如何在自定义日历 View 中选择多个日期?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  3. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  4. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  5. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  8. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  10. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

随机推荐