前言
1.之前沒怎麼在ListView的Item條目中嵌套Seekbar, 突然有朋友遇到這樣的情況,於是花點時間解決下
網上找的一些blog基本沒什麼用,可能是我的手法不對,本篇實測有效
解決問題
seekbar在listview的item中時,點擊定時加載進度時,滑動listview,seekbar複用的部分也會被定時器控制進行進度加載
解決後的效果
分析
listview的常規用法,
設置適配器
適配器中四個方法 最重要的getView
convertView複用Item條目
自定義ViewHolder保存控件 避免頻繁查找控件
這裏貼一下getView的代碼
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(mContext, R.layout.item_seekbar, null);
holder.mTextView = convertView.findViewById(R.id.tv_play);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mTextView.setText("播放" + position);
return convertView;
}
class ViewHolder {
private TextView mTextView;
}
}
上面是 listview的convertView複用流程
比如說一個界面最多需要 6個條目覆蓋慢,如果使用了convertView複用,那麼在下滑時第7個條目剛剛出現,但第一個條目完全消失時,getView 會獲取第一個的ItemView 作爲convertView , 我們又convertView帶了當前也就是第7個條目展示的Item
所以第7個的View就是第1個
listview中每個條目的區別不在於控件 而在於數據 數據通過position進行區分,我們只要將position綁定到convertView 實際上就可以了 ,看了幾篇網文,可能是拷錯了
每次getView 表示初始化一個ItemView 我們都需要對其綁定position,可以綁定到某個控件 view.setTag
也可以綁定到ViewHolder
但需要注意的是 不管是否複用View 都需要對於position進行綁定
我這裏會在下面初始化的定時器的回調中對於當前 view中獲取的position和 點擊播放的position進行比較,來判斷當前的條目是否爲複用條目,而不是原本點擊的條目
還是貼出關鍵代碼 getView
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(mContext, R.layout.item_seekbar, null);
holder.mTextView = convertView.findViewById(R.id.tv_play);
holder.mSeekBar = convertView.findViewById(R.id.tv_seekbar);
holder.mTextView.setTag(position);
holder.mSeekBar.setTag(position);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder.mTextView.setTag(position);
holder.mSeekBar.setTag(position);
}
holder.mTextView.setText("播放" + position);
holder.mSeekBar.setMax(100);
holder.mSeekBar.setProgress(0);
holder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
choosePosition =position;
timer = new Timer();
final Handler handler = new Handler();
timer.schedule(new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
currentPlayProgress++;
if ((int)holder.mTextView.getTag() == choosePosition) {
if (currentPlayProgress > 100) {
currentPlayProgress = 0;
holder.mSeekBar.setProgress(currentPlayProgress);
timer.cancel();
} else {
holder.mSeekBar.setProgress(currentPlayProgress);
}
}
}
});
}
}, 100, 1000);
}
});
return convertView;
}
class ViewHolder {
private SeekBar mSeekBar;
private TextView mTextView;
}
實際上 上面的gif圖還有一點點小問題,就是 從下往上滑動時,第一個條目重新出現 一開始顯示進度0
這個在getView 初始化數據時做一點小變動,判斷當前是否爲進行進度加載中的條目,做進度更新就可以了
holder.mSeekBar.setMax(100);
if (choosePosition == position) {
holder.mSeekBar.setProgress(currentPlayProgress);
} else {
holder.mSeekBar.setProgress(0);
}
下面貼一下全部代碼
adapter
package com.example.caixingcun.seekbarlistcontroldemo;
import android.content.Context;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.SeekBar;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by cxc on 2018/3/22.
*/
public class SeekBarAdapter extends BaseAdapter {
private Context mContext;
private Timer timer;
private int currentPlayProgress = 0;
private int choosePosition = -1;
public SeekBarAdapter(Context context) {
mContext = context;
}
@Override
public int getCount() {
return 30;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(mContext, R.layout.item_seekbar, null);
holder.mTextView = convertView.findViewById(R.id.tv_play);
holder.mSeekBar = convertView.findViewById(R.id.tv_seekbar);
holder.mTextView.setTag(position);
holder.mSeekBar.setTag(position);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder.mTextView.setTag(position);
holder.mSeekBar.setTag(position);
}
holder.mTextView.setText("播放" + position);
holder.mSeekBar.setMax(100);
if (choosePosition == position) {
holder.mSeekBar.setProgress(currentPlayProgress);
} else {
holder.mSeekBar.setProgress(0);
}
holder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
choosePosition = position;
timer = new Timer();
final Handler handler = new Handler();
timer.schedule(new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
currentPlayProgress++;
if ((int) holder.mTextView.getTag() == choosePosition) {
if (currentPlayProgress > 100) {
currentPlayProgress = 0;
holder.mSeekBar.setProgress(currentPlayProgress);
timer.cancel();
} else {
holder.mSeekBar.setProgress(currentPlayProgress);
}
}
}
});
}
}, 100, 1000);
}
});
return convertView;
}
class ViewHolder {
private SeekBar mSeekBar;
private TextView mTextView;
}
}
MainActivity
setContentView(R.layout.activity_main);
mListView = findViewById(R.id.lv);
mListView.setAdapter(new SeekBarAdapter(this));
item_seekbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:text="播放"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/tv_play"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="100dp" />
<SeekBar
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/tv_play"
android:id="@+id/tv_seekbar"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp"
android:gravity="center_vertical"
android:layout_height="100dp" />
</android.support.constraint.ConstraintLayout>
靠這篇文章解決問題的,幫忙點個贊! 打字不易