在列表视图中滚动后,元素将被交换

时间:2015-04-26 08:30:16

标签: java android listview

我编写了时间跟踪应用程序,listview的每一行都有两个按钮(Start和Stop)和一些textView来显示已用时间。

在列表视图中滚动后,元素将被交换。

我在我的解决方案中不确定,但我在模型类中放入了ViewHolder对象,以获取更改视图元素的访问权。

这是代码模型的片段

private String name;
private  Boolean isStart=false;
private  Long elapsedTime=0L,seconds=0L,hours=0L,minutes=0L,lastPause=0L,updateTime=0L,startTime=0L,days=0L;
private Runnable updateTimeThread=new Runnable() {
@Override
public void run() {
    if(isStart && startTime!=0) {
        updateTime = ((System.currentTimeMillis() - startTime) + lastPause);
        seconds = updateTime / 1000;
        minutes = seconds / 60;
        hours = minutes / 60;

        seconds = seconds % 60;
        minutes = minutes % 60;
        hours = hours % 24;

        holder.days.setText(String.format("%04d", days));
        holder.hours.setText(String.format("%02d", hours));
        holder.minutes.setText(String.format("%02d", minutes));
        holder.seconds.setText(String.format("%02d", seconds));
        Log.d("myTag",name+" "+seconds);
        MainActivity.handler.post(this);
    }
}
             };

MyAdapter.ViewHolder holder;

    public MyAdapter.ViewHolder getHolder() {
return holder;
  }

   public void setHolder(MyAdapter.ViewHolder holder) {
    this.holder = holder;
   }

     public Runnable getRunnable() {
return updateTimeThread;
         }

适配器的片段代码

public View getView(final int position, final View convertView, ViewGroup parent) {
View row = convertView;
final Tracker tracker = trackerList.get(position);
final Runnable updateTimeThread=tracker.getRunnable();


View.OnClickListener onClickListener;
ViewHolder holder;

if(row == null){
    holder = new ViewHolder();
    LayoutInflater inflater = ((Activity)context).getLayoutInflater();
    row = inflater.inflate(R.layout.row,parent,false);
    holder.name = (TextView)row.findViewById(R.id.tvName);
    holder.days = (TextView)row.findViewById(R.id.tvDays);
    holder.hours = (TextView)row.findViewById(R.id.tvHours);
    holder.minutes = (TextView)row.findViewById(R.id.tvMinutes);
    holder.seconds = (TextView)row.findViewById(R.id.tvSeconds);
    holder.start = (Button)row.findViewById(R.id.btStart);
    holder.stop = (Button)row.findViewById(R.id.btStop);
    row.setTag(holder);
}else {
    holder = (ViewHolder) row.getTag();
}
    holder.start.setEnabled(true);
    holder.stop.setEnabled(false);
    holder.name.setText(tracker.getName());
    final ViewHolder finalHolder = holder;



if(tracker.getIsStart()){
    holder.start.setEnabled(false);
    holder.stop.setEnabled(true);
}


 onClickListener = new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         switch (v.getId()) {
             case R.id.btStart:
                 tracker.setStartTime(System.currentTimeMillis());
                 tracker.setIsStart(true);
                 tracker.setHolder(finalHolder);
                 MainActivity.handler.post(updateTimeThread);
                 finalHolder.start.setEnabled(false);
                 finalHolder.stop.setEnabled(true);
                 break;
             case R.id.btStop:
                 tracker.setLastPause(tracker.getUpdateTime());
                 MainActivity.handler.removeCallbacks(updateTimeThread);
                 finalHolder.stop.setEnabled(false);
                 finalHolder.start.setEnabled(true);
                 tracker.setIsStart(false);
                 break;
         }
     }
 };
holder.start.setOnClickListener(onClickListener);
holder.stop.setOnClickListener(onClickListener);
return row;
 }

static class ViewHolder{
TextView  name,days,hours,minutes,seconds;
Button start,stop;
}

2 个答案:

答案 0 :(得分:0)

更改此部分

holder.start.setEnabled(true);
holder.stop.setEnabled(false);
holder.name.setText(tracker.getName());
final ViewHolder finalHolder = holder;

if(tracker.getIsStart()){
holder.start.setEnabled(false);
holder.stop.setEnabled(true);
}    

到这个

final ViewHolder finalholfder = holder;

finalholfder.start.setEnabled(true);
finalholfder.stop.setEnabled(false);
finalholfder.name.setText(tracker.getName());


if(tracker.getIsStart()){
finalholfder.start.setEnabled(false);
finalholfder.stop.setEnabled(true);
} else{
finalholfder.start.setEnabled(true);
finalholfder.stop.setEnabled(false);
}

这个

holder.start.setOnClickListener(onClickListener);  
holder.stop.setOnClickListener(onClickListener);

到这个

 finalholfder.start.setOnClickListener(onClickListener);
 finalholfder.stop.setOnClickListener(onClickListener);

答案 1 :(得分:0)

我只是将这两种方法添加到我的适配器中)

<Grid.ColumnDefinitions>
 <ColumnDefinition Width="Auto" />
 <ColumnDefinition Width="*" />
 <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<强>更新 但是与Loader Callback问题仍然是一样的。我按下最后一项的开始并向下滚动,值不可见,向上滚动一点并显示值。可惜。

UPDATE 2 这篇文章解决了我的问题,我只是将layout-height和laoyut-weight从“wrap_content”更改为“fill_parent”,以避免多次调用getView()方法。 http://gmariotti.blogspot.com/2013/06/tips-for-listview-view-recycling-use.html