RecyclerView 목록 카운트다운 실현
6753 단어 RecyclerView리스트카운트다운
1.메모리 문제
2.recyclerview 의 item 재 활용 으로 항목 별 시간 착란
일단 실현 의 최종 효 과 를 살 펴 보 겠 습 니 다.
목록 을 어떻게 표시 하 는 지 저 는 모두 가 할 것 이 라 고 믿 습 니 다.여기 에는 카운트다운 기능 이 실 현 된 adapter 류 만 첨부 합 니 다.
public class ClockAdapter extends RecyclerView.Adapter<ClockAdapter.ClockViewHolder> {
private SparseArray<CountDownTimer> countDownMap = new SparseArray<>();
@Override
public ClockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv, parent, false);
return new ClockViewHolder(view);
}
/**
*
*/
public void cancelAllTimers() {
if (countDownMap == null) {
return;
}
for (int i = 0,length = countDownMap.size(); i < length; i++) {
CountDownTimer cdt = countDownMap.get(countDownMap.keyAt(i));
if (cdt != null) {
cdt.cancel();
}
}
}
@Override
public void onBindViewHolder(final ClockViewHolder holder, int position) {
long betweenDate;
if (position == 0) {
betweenDate= DateUtil.getLeftTime("2017-8-8 12:10:10");
} else {
betweenDate= DateUtil.getLeftTime("2017-8-9 15:10:10");
}
if (holder.countDownTimer != null) {
holder.countDownTimer.cancel();
}
if (betweenDate > 0) {
holder.countDownTimer = new CountDownTimer(betweenDate, 1000) {
public void onTick(long millisUntilFinished) {
millisUntilFinished = millisUntilFinished / 1000;
int hours = (int) (millisUntilFinished / (60 * 60));
int leftSeconds = (int) (millisUntilFinished % (60 * 60));
int minutes = leftSeconds / 60;
int seconds = leftSeconds % 60;
final StringBuffer sBuffer = new StringBuffer();
sBuffer.append(addZeroPrefix(hours));
sBuffer.append(":");
sBuffer.append(addZeroPrefix(minutes));
sBuffer.append(":");
sBuffer.append(addZeroPrefix(seconds));
holder.clock.setText(sBuffer.toString());
}
public void onFinish() {
//
}
}.start();
countDownMap.put(holder.clock.hashCode(), holder.countDownTimer);
} else {
//
}
}
@Override
public int getItemCount() {
return 25;
}
class ClockViewHolder extends RecyclerView.ViewHolder {
TextView clock;
CountDownTimer countDownTimer;
public ClockViewHolder(View itemView) {
super(itemView);
clock = (TextView) itemView.findViewById(R.id.clock);
}
}
}
그 중에서 cancelAllTimer()방법 은 메모리 문 제 를 해결 합 니 다.이 줄 코드 를 통 해 item 의 hashcode 를 key 로 SparseArray 에 설정 하면 cancelAllTimer 방법 에서 하나씩 꺼 내 카운트다운 취소 작업 을 할 수 있 습 니 다.
countDownMap.put(holder.clock.hashCode(),holder.countDownTimer);
다음 줄 코드 를 통 해 Countdown Timer 클래스 를 새로 만 듭 니 다.
holder.countDownTimer = new CountDownTimer(betweenDate, 1000) {
public void onTick(long millisUntilFinished) {
millisUntilFinished = millisUntilFinished / 1000;
int hours = (int) (millisUntilFinished / (60 * 60));
int leftSeconds = (int) (millisUntilFinished % (60 * 60));
int minutes = leftSeconds / 60;
int seconds = leftSeconds % 60;
final StringBuffer sBuffer = new StringBuffer();
sBuffer.append(addZeroPrefix(hours));
sBuffer.append(":") sBuffer.append(addZeroPrefix(minutes));
sBuffer.append(":");
sBuffer.append(addZeroPrefix(seconds));
holder.clock.setText(sBuffer.toString());
}
public void onFinish() {
//
}
}.start();
그것 의 소스 코드 를 분석 하 다.
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
이 를 통 해 알 수 있 듯 이 두 개의 값 을 설 치 했 는데 첫 번 째 는 카운트다운 종료 시간 이 고 두 번 째 는 갱신 시간의 간격 이다.그리고 start 방법 으로 시작 하고 start 방법 에서 진행 되 는 처 리 를 살 펴 보 겠 습 니 다.
public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
원본 코드 에 서 는 카운트다운 마감 시간 이 0 보다 적 을 때,즉 카운트다운 이 끝 날 때 onFinish 방법 을 사용 합 니 다.만약 시간 이 끝나 지 않 았 다 면 handler 의 비동기 메시지 체 제 를 통 해 메 시 지 를 보 냅 니 다.전체 절 차 를 통 해 최종 방법 은 handler 의 handleMessage 방법 에 들 어 갑 니 다.이 비동기 절 차 를 잘 모 르 는 파트너 가 있다 면,내 가 이전에 쓴 비동기 메시지 메커니즘 의 문장 을 보 러 갈 수 있다android 비동기 메시지 메커니즘,원본 차원 철저히 분석자,다음은 handler 의 handle Message 방법 을 살 펴 보 겠 습 니 다.
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart=SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
이 소스 코드 는 아직 잘 알 고 있 을 것 이 라 고 믿 습 니 다.먼저 남 은 시간 을 계산 하고 남 은 시간 이 새로 고침 시간 보다 적 으 면 시간 이 끝 날 때 까지 지연 메 시 지 를 보 냅 니 다.남 은 시간 이 새로 고침 시간 보다 많 으 면 onTick(millisLeft)방법 을 호출 합 니 다.이 방법 은 우리 가 CountDownTimer 클래스 를 만 들 때 재 작성 한 적 이 있 습 니 다.그 안에 우리 가 카운트다운 으로 보 여 준 구체 적 인 논 리 를 쓸 수 있다.이로써 전체 절차 가 끝났다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Android】RecyclerView+RadioButton의 작성RadioGroup을 사용하지 않고 작성합니다. RecyclerView 배치 activity_main.xml RadioButton 배치 view_item.xml RecyclerView 용 어댑터 작성. 어느 버튼을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.