我有一個奇怪的問題。 我有一個自定義ListView
與BaseAdapter
。在我的ListView
行佈局中,我有幾個TextView
s,Buttons
和一個SeekBar
。一切都很好,除了回收之外沒有任何問題。ListView回收開關seekbar位置
發生了什麼: 所有的SeekBar
都是隱藏的,除了一個是可見的。正在播放MediaPlayer
行時,SeekBar
可見。這部分工作也很好。
但是,當用戶向上或向下滾動,並可見SeekBar
行是拿出來看,它回收,並SeekBar
被回收也和它不斷更新甚至壽是不可見的,而此行不是打(MP) 。當用戶滾動回到正在播放的視圖時,SeekBar
是可見的,但不是更新,它的位置是0.相反,隨機SeekBar
正在更新,但它不可見(當所有SeekBar
都可見時,我測試了我知道會發生)
當然,我可以做最愚蠢的解決方案,並禁用ListView的回收,但這使得用戶體驗非常糟糕,並可能使應用程序內存不足,並使用LargeHeap
是跛腳。 所以下面的方法是沒有問題的。
@Override
public int getViewTypeCount() {
return getCount();
}
@Override
public int getItemViewType(int position) {
return position;
}
我的問題:有沒有什麼明顯的解決辦法呢? 如何保持只有一行被回收? 我不會發布代碼,直到它真的有必要,代碼太大。相反,我將只是張貼相關的問題最重要的部分:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
holder = null;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.item, parent, false);
holder = new Ids(row);
row.setTag(holder);
} else {
holder = (Ids) row.getTag();
}
rowItemClass = (ListViewRow) getItem(position);
if (Globals.isPlaying && Globals.pos == position) {
holder.seekbar.setVisibility(View.VISIBLE);
} else {
holder.seekbar.setVisibility(View.GONE);
}
holder.seekbar.setTag(position);
final Ids finalHolder = holder;
...
OnClickListener{....
Globals.mp.start();
finalHolder.seekbar.setProgress(0);
finalHolder.seekbar.setMax(Globals.mp.getDuration());
..
updateTimeProgressBar = new Runnable() {
@Override
public void run() {
if (Globals.isPlaying) {
finalHolder.seekbar.setProgress(Globals.mp.getCurrentPosition());
int currentPosition = Globals.mp.getCurrentPosition();
handler.postDelayed(this, 100);
}
}
};
handler.postDelayed(updateTimeProgressBar, 100);
finalHolder.seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateTimeProgressBar);
Globals.mp.seekTo(finalHolder.seekbar.getProgress());
int currentPosition = Globals.mp.getCurrentPosition();
handler.postDelayed(updateTimeProgressBar, 500);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateTimeProgressBar);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// Intentionally left empty
}
});
}
,就是這樣。 這是怎麼回事? 有沒有辦法禁用一行回收? 因爲只有1個mp會被播放,所以更新ListView
中的所有SeekBar
s會不好?性能有多糟糕?
關於保持一個參考它的狀態,並檢查該行是否再次可見什麼。當它可見時,您可以重新分配在視圖本身被回收時不斷更新的狀態。 – abbath
你可以通過notifItemChanged(position)來完成。 –
如何保持有關行狀態的參考? 我曾嘗試檢查'if(holder.seekbar.getVisiblity == View.VISIBLE)',但由於某種原因,這根本不起作用。不知道它是否讀錯了'Seekbar'。 'notifyItemChanged'方法呢?你可以說得更詳細點嗎? –