2016-11-28 1 views
0

私はリストビューでカウントダウンタイマーを作ろうとしました。各リスト項目には、開始または停止できる個別のカウントダウンタイマーがあります。しかし、リストに最初のタイマーを追加して時刻を設定すると、気づいたことがあります。タイマーを開始すると、実際の時間より2秒遅れて開始されます。例:12秒のカウントダウンを追加した場合その後、カウントは10からカウントを開始します。しかし、カウントダウンが行われているときに、別の新しいタイマーを追加して時刻を設定すると、正確な時刻に開始されます。新しいカウンタは、リストに他のカウンタがない場合、またはすべてのカウンタがすでに停止していてカウントダウンしていない場合にのみ、間違った時刻に開始されます。同様に、他のタイマーがカウントダウンしている場合にのみ、適切な時刻に開始されます。誰かが問題のどこにいるのかを理解する手助けができたら本当に感謝します。私は数日間コードを見てきました。カウントダウンタイマーは、実際の時刻の2秒前にカウントします。

は、ここに私のアダプタクラス

public class CustomAdapterCounter extends ArrayAdapter<CounterData> { 

private final LayoutInflater mInflater; 
Context context; 
Uri sound = Uri.parse("android.resource://com.tattooalarmclock.free/" + R.raw.counter); 
String counterString = ""; 
private List<ViewHolder> lstHolders; 
private List<CounterData> list = new ArrayList<CounterData>(); 
private Handler mHandler = new Handler(); 
private Runnable updateRemainingTimeRunnable = new Runnable() { 
    @Override 
    public void run() { 
     synchronized (lstHolders) { 
      long currentTime = System.currentTimeMillis(); 
      for (ViewHolder holder : lstHolders) { 
       // if(!holder.counterData.isStopped) 
        holder.updateTimeRemaining(System.currentTimeMillis()); 
      } 
     } 
    } 
}; 

public CustomAdapterCounter(Context context, List<CounterData> l) { 
    super(context, 0, l); 
    this.context = context; 
    lstHolders = new ArrayList<>(); 
    list = l; 
    mInflater = LayoutInflater.from(context); 

    for(int i=0; i<list.size(); i++) { 
     CounterData[] array = list.toArray(new CounterData[list.size()]); 
     if(!array[i].isStopped) 
      startUpdateTimer(); 
    } 
} 

public double getScreenSize() { 
    DisplayMetrics dm = new DisplayMetrics(); 
    WindowManager windowManager = (WindowManager) context 
      .getSystemService(Context.WINDOW_SERVICE); 
    windowManager.getDefaultDisplay().getMetrics(dm); 
    int width = dm.widthPixels; 
    int height = dm.heightPixels; 
    int dens = dm.densityDpi; 
    double wi = (double) width/(double) dens; 
    double hi = (double) height/(double) dens; 
    double x = Math.pow(wi, 2); 
    double y = Math.pow(hi, 2); 
    double screenInches = Math.sqrt(x + y); 

    return screenInches; 
} 


private void startUpdateTimer() { 
    Timer tmr = new Timer(); 
    tmr.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      mHandler.post(updateRemainingTimeRunnable); 
     } 
    }, 1000, 1000); 
} 

public static <T> List<T> stringToArray(String s, Class<T[]> clazz) { 
    T[] arr = new Gson().fromJson(s, clazz); 
    return Arrays.asList(arr); //or return Arrays.asList(new Gson().fromJson(s, clazz)); for a one-liner 
} 


public boolean getListSharedPreferences() { 

    SharedPreferences sharedPreferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); 

    if (sharedPreferences.getString("CL", null) != null) { 
      counterString = sharedPreferences.getString("CL", null); 
      Gson gson = new Gson(); 
      TypeToken<List<CounterData>> token = new TypeToken<List<CounterData>>() {}; 
      list = gson.fromJson(counterString, token.getType()); 
     return true; 
    } 
    else 
     return false; 
} 

public void saveListSharedPreferences(List counterList) { 

    Gson gson = new Gson(); 
    counterString = gson.toJson(counterList); 
    SharedPreferences sharedPreferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); 
    sharedPreferences.edit().putString("CL", counterString).commit(); 

} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder = null; 

    if (convertView == null) { 
     holder = new ViewHolder(); 
     if(getScreenSize() <= 4) 
     convertView = mInflater.inflate(R.layout.list_view_counter_small, parent, false); 
     else 
     convertView = mInflater.inflate(R.layout.list_view_item_counter, parent, false); 
     holder.counterTextView = (TextView) convertView.findViewById(R.id.counterTextView); 
     holder.stopCounter = (Button) convertView.findViewById(R.id.counterStopInList); 
     holder.startCounter = (Button) convertView.findViewById(R.id.counterStartInList); 
     holder.deleteCounter = (Button) convertView.findViewById(R.id.deleteCounter); 
     convertView.setTag(holder); 
     synchronized (lstHolders) { 
      lstHolders.add(holder); 
     } 

    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.setData2(getItem(position)); 

    final ViewHolder finalHolder = holder; 
    holder.stopCounter.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      long store = finalHolder.counterData.expirationTime - System.currentTimeMillis(); 
      finalHolder.counterData.isStopped = true; 
      finalHolder.counterData.expirationTime = store; 
      finalHolder.stopCounter.setEnabled(false); 
      finalHolder.stopCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
      finalHolder.startCounter.setEnabled(true); 
      finalHolder.startCounter.getBackground().setColorFilter(null); 
      list.set(position, finalHolder.counterData); 
      saveListSharedPreferences(list); 

     /*  if(getListSharedPreferences()) { 
       System.out.println("List before change in stop button " + list.toString()); 
       list = stringToArray(counterString, CounterData[].class); 
       list.set(position, finalHolder.counterData); 
       System.out.println("List before change in stop button " + list.toString()); 
       saveListSharedPreferences(list); 
      } 
      else { 
       System.out.println(list.toString()); 
       list.set(position, finalHolder.counterData); 
       System.out.println(list.toString()); 
       saveListSharedPreferences(list); 
      } 
     */ 
     } 
    }); 

    holder.startCounter.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      finalHolder.counterData.expirationTime = System.currentTimeMillis() + finalHolder.counterData.expirationTime; 
      finalHolder.counterData.isStopped = false; 
      //finalHolder.counterData.expirationTime = System.currentTimeMillis() + finalHolder.counterData.expirationTime; 
      //finalHolder.setData(finalHolder.counterData); 
      finalHolder.startCounter.setEnabled(true); 
      finalHolder.startCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
      finalHolder.stopCounter.setEnabled(true); 
      finalHolder.stopCounter.getBackground().setColorFilter(null); 
      list.set(position, finalHolder.counterData); 
      saveListSharedPreferences(list); 
      startUpdateTimer(); 
     /*  if(getListSharedPreferences()) { 
       list = stringToArray(counterString, CounterData[].class); 
       System.out.println("List before change in start button " + list.toString()); 
       list.set(position, finalHolder.counterData); 
       System.out.println("List after change in start button " + list.toString()); 
       saveListSharedPreferences(list); 
      } 
      else { 
       list.set(position, finalHolder.counterData); 
       saveListSharedPreferences(list); 
      } */ 
     } 
    }); 

    final ViewHolder finalHolder1 = holder; 
    holder.deleteCounter.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
/*   if(finalHolder1.mediaPlayer.isPlaying()) { 
       finalHolder.mediaPlayer.stop(); 
      //  finalHolder.counterData.isSoundPlayedBefore = true; 
      } */ 
      list.remove(position); 
      notifyDataSetChanged(); 
      saveListSharedPreferences(list); 
     } 
    }); 


    return convertView; 
} 
} 

class ViewHolder { 
public TextView counterTextView; 
//public List<Long> l; 
CounterData counterData; 
Button startCounter; 
Button stopCounter; 
Button deleteCounter; 
boolean stop = false; 
long timeDiff; 
// Context context; 
// MediaPlayer mediaPlayer; 
// List<CounterData> counterDataList; 

public void setData(CounterData item) { 
    counterData = item; 
    updateTimeRemaining(System.currentTimeMillis()); 
} 

public void setData2(CounterData item) { 
    counterData = item; 
    updateTimeRemaining(System.currentTimeMillis()); 
} 

public void updateTimeRemaining(long currentTime) { 

    if (!counterData.isStopped) { 
     timeDiff = counterData.expirationTime - currentTime; 
     //System.out.println("Time Diff Inside Method " + timeDiff); 
     if (timeDiff > 0) { 
      int seconds = (int) (timeDiff/1000) % 60; 
      int minutes = (int) ((timeDiff/(1000 * 60)) % 60); 
      int hours = (int) TimeUnit.MILLISECONDS.toHours(timeDiff); 
      counterTextView.setText(hours + "H " + minutes + "M " + seconds + "S"); 
      stopCounter.setEnabled(true); 
      stopCounter.getBackground().setColorFilter(null); 
      startCounter.setEnabled(false); 
      startCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
     } else { 
      counterTextView.setText("Times Up"); 
      startCounter.setEnabled(false); 
      startCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
      stopCounter.setEnabled(false); 
      stopCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
     // Vibrator v = (Vibrator) this.context.getSystemService(Context.VIBRATOR_SERVICE); 
      // Vibrate for 500 milliseconds 
     // v.vibrate(5000); 
    /*  if(!counterData.isSoundPlayedBefore) { 
       mediaPlayer.start(); 
       mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
        @Override 
        public void onCompletion(MediaPlayer mp) { 
         mediaPlayer.stop(); 
        } 
       }); 
       counterData.isSoundPlayedBefore = true; 
       if(findIndex(counterData) != -1) { 
        int index = findIndex(counterData); 
        counterDataList.set(index,counterData); 
        saveListSharedPreferences(counterDataList); 
       } 
      } */ 
     } 
    } 
    else { 
     long store = counterData.expirationTime + System.currentTimeMillis() - currentTime; 
     int seconds = (int) (store/1000) % 60; 
     int minutes = (int) ((store/(1000 * 60)) % 60); 
     int hours = (int) TimeUnit.MILLISECONDS.toHours(store); 
     counterTextView.setText(hours + "H " + minutes + "M " + seconds + "S"); 
     startCounter.setEnabled(true); 
     startCounter.getBackground().setColorFilter(null); 
     stopCounter.setEnabled(false); 
     stopCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
    } 
} 
} 

だとここに私のCounterDataクラス

class CounterData { 
long expirationTime; 
boolean isStopped; 
boolean isSoundPlayedBefore; 
int id; 

public CounterData(long expirationTime, int id) { 
    this.expirationTime = expirationTime; 
    isStopped = true; 
    isSoundPlayedBefore = false; 
    this.id = id; 
} 

public String toString() { 

    return String.valueOf("Remaining Time: " + TimeUnit.MILLISECONDS.toMinutes(this.expirationTime) + ":" + TimeUnit.MILLISECONDS.toSeconds(this.expirationTime)); 
} 

public void setCounterID(int id) { 
    this.id = id; 
} 

public int getCounterID() { 
    return this.id; 
} 

} 

だと私は時、分、秒の数ピッカーから時間を追加します。

case R.id.counterStartStopButton: 
      long hour = TimeUnit.HOURS.toMillis(numberPickerHour.getValue()); 
      long minute = TimeUnit.MINUTES.toMillis(numberPickerMinute.getValue()); 
      long second = TimeUnit.SECONDS.toMillis(numberPickerSecond.getValue()); 
     //  if(getListSharedPreferences()) { 
       if(getCounterIDSharedPreferences()) { 
        counterID = counterID + 1; 
        list.add(new CounterData(hour + minute + second, counterID)); 
        saveCounterIDSharedPreferences(counterID); 
       } 
       else { 
        counterID = 1; 
        list.add(new CounterData(hour + minute + second, counterID)); 
        saveCounterIDSharedPreferences(counterID); 
       } 

UPDATE はここで何を私のために働くことが判明すると、次のようにタイマータスクを変更して共有好みコード

public void saveCounterIDSharedPreferences(int id) { 

    SharedPreferences sharedPreferences = this.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); 
    sharedPreferences.edit().putInt("Counter ID123", id).commit(); 
} 


public boolean getCounterIDSharedPreferences() { 

    SharedPreferences sharedPreferences = this.getSharedPreferences("com.example.app", Context.MODE_PRIVATE); 

    if (sharedPreferences.getInt("Counter ID123", -1) != -1) { 
     counterID = sharedPreferences.getInt("Counter ID123", -1); 
     return true; 
    } 
    else 
     return false; 
} 
+0

だからあなたの最初のタイマーが10で始まっています(2秒遅れ)しかし、その後はすべてが大丈夫ですか? – Hahn

+0

他のタイマーがない場合、またはリスト内の他のタイマーがすべて一時停止している場合は、新しいタイマーを追加すると実際の時刻からカウントが開始されます(-2秒)。リスト内の他のカウンタがカウントダウンして停止していない場合、この場合に新しいカウンタを追加すると正常に開始されます。 –

+0

CounterIdSharedPrefコードを投稿できますか? – Hahn

答えて

0

です:

private void startUpdateTimer() { 
    Timer tmr = new Timer(); 
    tmr.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      mHandler.post(updateRemainingTimeRunnable); 
     } 
    }, 500, 500); 
} 
関連する問題