0

我正在开发一个转换器,为此我有两个 android wheel 实例。当用户滚动一个轮子时,第二个轮子应该自动计算并将第二个轮子的数据更改为该结果。反之亦然。

这样做的问题是逻辑是循环的,因为当滚轮被滚动和更改时,每次都会调用滚动的侦听器和更改的侦听器,这会导致 StackOverFlowError。

当用户滚动第一个轮子时,如何让第二个轮子转换并设置日期?反之亦然。

代码:

@Override
public void onCreate(Bundle savedInstanceState) {

   ......


   changedlistener = new OnWheelChangedListener() {
       public void onChanged(WheelView wheel, int oldValue, int newValue) {

         if (wheel.getId() == R.id.month || wheel.getId() == R.id.day || wheel.getId() == R.id.year) {
                 updateDays(year, month, day);
         } else if (wheel.getId() == R.id.hijrimonth || wheel.getId() == R.id.hijriday || wheel.getId() == R.id.hijriyear) {
                 hijriDays(hijriyear, hijrimonth, hijriday);
         }


       }
   };

   .....scrolledlistener event......

   // month

   month.addChangingListener(changedlistener);
   month.addScrollingListener(scrolledlistener);

   // year
   year.addChangingListener(changedlistener);
   year.addScrollingListener(scrolledlistener);


   //day
   day.addChangingListener(changedlistener);
   day.addScrollingListener(scrolledlistener);

   hijrimonth.addChangingListener(changedlistener);
   hijrimonth.addScrollingListener(scrolledlistener);

   hijriyear.addChangingListener(changedlistener);
   hijriyear.addScrollingListener(scrolledlistener);

   hijriday.addChangingListener(changedlistener);
   hijriday.addScrollingListener(scrolledlistener);

}

/**
* Updates day wheel. Sets max days according to selected month and year
*/
void updateDays(WheelView year, WheelView month, WheelView day) {
   Calendar calendar = Calendar.getInstance();
   calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + year.getCurrentItem());
   calendar.set(Calendar.MONTH, month.getCurrentItem());

   int maxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
   day.setViewAdapter(new DateNumericAdapter(this, 1, maxDays, calendar.get(Calendar.DAY_OF_MONTH) - 1));
   int curDay = Math.min(maxDays, day.getCurrentItem() + 1);
   day.setCurrentItem(curDay - 1, true);
   int curYear = calendar.get(Calendar.YEAR);
   year.setCurrentItem(curYear);
   text.setText( (day.getCurrentItem()+1) + " " + getMonthAsString(month.getCurrentItem()) + " "  +year.getCurrentItem() );
   //setHijri(year.getCurrentItem(), month.getCurrentItem(), day.getCurrentItem());
} 

void hijriDays(WheelView year, WheelView month, WheelView day) {

   hijritext.setText((day.getCurrentItem()+1) + " " + hijri.getHijriMonthName(month.getCurrentItem()+1) + " "  + year.getCurrentItem());
   setGreg(year.getCurrentItem(), month.getCurrentItem(), day.getCurrentItem());
} 

public void setGreg(int y, int m, int d) {
    hdate = hijri.islToGreg(y, m, d, 0);
    hmonth = hdate[1];
    hyear = hdate[2];
    hday = hdate[0];

    month.setCurrentItem(hmonth);
    day.setCurrentItem(hday);
    year.setCurrentItem(hyear);

}

public void setHijri(int y, int m, int d) {
    hdate = hijri.GregToIsl(y, m, d, 0);
    hmonth = hdate[1];
    hyear = hdate[2];
    hday = hdate[0];

    hijrimonth.setCurrentItem(hmonth);
    hijriday.setCurrentItem(hday);
    hijriyear.setCurrentItem(hyear);
}
4

2 回答 2

2

我认为最好的解决方案是使用标志来跳过轮子上的重复事件;类似下一个:

changedlistener = new OnWheelChangedListener() {
   boolean inProgress = false;

   public void onChanged(WheelView wheel, int oldValue, int newValue) {

     if (!inProgress) {
         return;
     }
     inProgress = true;

     try {
         if (wheel.getId() == R.id.month || wheel.getId() == R.id.day || wheel.getId() == R.id.year) {
             updateDays(year, month, day);
         } else if (wheel.getId() == R.id.hijrimonth || wheel.getId() == R.id.hijriday || wheel.getId() == R.id.hijriyear) {
             hijriDays(hijriyear, hijrimonth, hijriday);
         }
      }
      finally {
          inProgress = false;
      }
   }
};
于 2012-07-24T16:25:34.327 回答
0

当用户开始滚动启动一个倒数计时器。定期进行每次增量所需的计算和调整。换句话说,您不需要捕获每个滚动更改事件。如果倒数计时器尚未开始,只需抓住它即可启动倒数计时器。然后检查滚动位置并进行相应调整。

于 2012-07-20T22:57:11.537 回答