Android RecyclerView 조합 카운트다운 목록 인 스 턴 스 코드 구현
8002 단어 android카운트다운recyclerview
최근 수요 에 쫓 겨 나 테스트 를 거 쳐 접속 한 뒤 리 뷰 를 하지 않 는 기능 도 있다.한가 해 지 든 지 오래된 코드 를 다시 최적화 시 키 든 지,옛 것 을 배우 고 새로운 것 을 알 든 지,그래도 약간의 수확 과 발전 이 있다.
수요 TODO
단체 구 매 라 는 판 촉 방식 은 이미 매우 보편적 이 며,특히 모두 가 잘 아 는'그리고 저녁'은 더욱 잘 논다.이제 우 리 는 단체 구 매 카운트다운 목록 을 실현 하고'나머지:09:12:24.8'이라는 스타일 로 이 단체 가 끝 나 는 시간의 카운트다운 을 보 여 줘 야 한다.
기술 초보 분석
우선,시간 변화 에 관 한 것 은 먼저 Timer Task+Timer 라 는 타이머 조합 을 생각 합 니 다.목록 은 RecyclerView 라 고 말 할 필요 가 없습니다.UI 업데이트 와 관련 되 어 있 기 때문에 handler 가 item 을 업데이트 해 야 합 니 다.
초보 적 으로 우 리 는 두 가지 방식 을 생각 할 것 이다.
두 가지 방법 은 각각 장단 점 이 있 습 니 다.그 다음 에 우 리 는 demo 를 통 해 구체 적 으로 비교 합 니 다.
그 다음으로 안 드 로 이 드 시스템 의 시간 이 변 경 될 수 있 기 때문에 백 엔 드 를 통 해 돌아 오 는 groupFinishTime 에서 현재 시스템 시간 System.currentTimeMillis 를 보 여 주 는 남 은 시간 으로 줄 일 수 없습니다.그래서 우 리 는 먼저 인 터 페 이 스 를 할 때 백 엔 드 친구 와 약속 을 하 는 것 을 기억 합 니 다.큰 놈 은 저 에 게 남 은 시간(단 위 는 초 입 니까?밀리초 입 니까?모두 가능 하지만 대부분 초 를 줍 니 다)
또 무슨 구덩이 가 있 을 지 생각 지도 못 했다.
사실 안 드 로 이 드 자체 에 자신의 카운트다운 클래스 가 있 습 니 다.Countdown Timer,내부 실현 도 Handler 를 통 해 이 루어 집 니 다.주석 을 더 하면 모두 157 줄 이 고 프로그램 내부 소모 시간
Coding
1.아 이 템 마다 CountDownTimer 하나씩
키 코드(kotlin)
class GroupListAdapter(private val mContext: Context) : RecyclerView.Adapter<GroupListAdapter.GroupViewHolder>() {
private var rList: List<GroupOrderBean>? = null
private val countDownMap: SparseArray<CountDownTimer>?
private var mPostion: Int = 0
private var timesList: MutableList<Long> = ArrayList()
init {
countDownMap = SparseArray()
}
fun setGroupList(list: List<GroupOrderBean>?) {
this.rList = list
if (rList?.size!! > 0) {
timesList = ArrayList()
for (item in rList!!) {
timesList.add(
item.leftSecond * 1000 + System.currentTimeMillis()
)
}
}
}
//
fun cancelTimers() {
if (countDownMap == null) {
return
}
for (i in 0 until countDownMap.size()) {
val cdt = countDownMap.get(countDownMap.keyAt(i))
cdt?.cancel()
}
}
override fun onBindViewHolder(holder: GroupViewHolder, position: Int) {
if (rList == null ||rList!!.isEmpty()) {
return
}
var countDownTimer: CountDownTimer? = countDownMap?.get(holder.tvLeftSecond.hashCode())
countDownTimer?.cancel()
val groupBean = rList!![position]
if (groupBean.leftMember <= 0) {
holder.tvLeftMember?.visibility = View.GONE
}
holder.tvLeftMember.text = " ${groupBean.leftMember} "
holder.tvLeftSecond.text = formatTime(groupBean.leftSecond * 1000)
val lefttime = timesList[position] - System.currentTimeMillis()
if (groupBean.leftSecond > 0) {
if (lefttime <= 0) {
holder.tvLeftSecond?.text = " 00:00:00.0"
//TODO
} else {
countDownTimer = object : CountDownTimer(lefttime, 100L) {
override fun onTick(millisUntilFinished: Long) {
holder.tvLeftSecond.text = formatTime(millisUntilFinished)
}
override fun onFinish() {
holder.tvLeftSecond.text = " 00:00:00.0"
//TODO
}
}.start()
countDownMap?.put(holder.tvLeftSecond.hashCode(), countDownTimer)
}
}
}
모든 Countdown Timer 를 SpaseArray 에 저장 하여 통일 적 으로 관리 합 니 다.view hodler 가 재 활용 되 는 것 을 피하 기 위해 서 는 timer 를 새로 만 들 었 습 니 다.모든 timer 에 view holder 의 hashcode 에 따라 spaseArray 에 저장 하 는 것 은 예전 에 listview 를 사용 할 때 tag 를 사용 하여 view holder 를 가 져 온 느낌 입 니 다.또 하 나 는 카운트다운 이 0 일 때 인터페이스 새로 고침 목록 을 다시 요청 하고 recyclerView 를 업데이트 하 며 이전의 모든 timer 를 멈 추고 Activity 를 종료 할 때 도 메모리 누 출 을 방지 해 야 합 니 다.
이런 방법 은 데이터 가 비교적 적 을 때 괜 찮 습 니 다.페이지 데이터 가 너무 많 으 면 new 많은 Timer 가 소모 되 고 너무 큽 니 다.
그래서 이 방안 은 조정 해 야 돼 요.
2.모든 아 이 템 공용 타이머
사고방식:하나의 timer 를 통 해 모든 item 데 이 터 를 업데이트 하고 handlerMessage 에서 메 시 지 를 받 아들 이 며 notifyItemChanged 를 통 해 item 을 업데이트 합 니 다
키 코드
handler 코드
여기 서 주의해 야 할 점 이 있 습 니 다.notifyitemChanged(position:Int,payLoad:Any)를 사용 해 야 합 니 다.notifyItemChanged(position:Int)를 직접 사용 하여 레이아웃 을 업데이트 하 는 것 이 아니 라 페이지 가 깜빡 이지 않도록 해 야 합 니 다.
init {
mTask = CountTask()
mHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message?) {
if (msg?.what == 1) {
if (rList?.size!! > 0) {
notifyItemChanged(msg.arg1,rList!![msg.arg1])
}
}
}
}
}
list 데이터 초기 화
fun setGroupList(list: List<GroupOrderBean>?) {
this.rList = list
if (rList?.size!! > 0) {
cancelTimers()
timesList = ArrayList()
for (item in rList!!) {
timesList.add(
item.leftSecond * 1000
)
}
mTimer = Timer()
mTask = CountTask()
mTimer?.schedule(mTask, 0, 100)
}
}
fun cancelTimers() {
mHandler.removeMessages(1)
mTimer?.cancel()
mTimer?.purge()
mTimer = null
}
인 터 페 이 스 는 초 로 되 돌아 가 고 우 리 는 100 밀리초 로 새로 고침 해 야 하기 때문에 timesList 를 다른 시간 으로 저장 해 야 합 니 다.TimerTask 코드
inner class CountTask : TimerTask() {
override fun run() {
if (timesList.isEmpty()) {
return
}
var leftTime:Long
for (i in timesList.indices) {
if (timesList[i] <= 0) {
continue
}
leftTime = timesList[i] - 100L
if (leftTime <= 0) {
timesList[i] = 0
continue
}
timesList[i] = leftTime
val message = Message.obtain()
message.what = 1
message.arg1 = i
mHandler.sendMessage(message)
}
}
}
이전 스타일 그림:이 정도 면 충분 합 니까?
no,no,no,카운트다운 종료 데이터 의 리 셋,드 롭 다운 리 셋,업 로드.이 페이지 는 좀 더 정교 해 야 한다.우리 의 목 표 는 별 바다 다.
총결산
이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.