2015-06-19 24 views
7

Listede gezinirken zamanlayıcı titreder Benim app, liste görünümünde her öğe için geri sayım sayacı göstermek zorunda. Bunu CountDownTimer kullanarak yapabildim. Ancak, liste görünümü yukarı veya aşağı kaydırıldığında, zamanlayıcı titremeye başlar. Çok arandı ama bir çözüm bulamadı.ListView with Coundown zamanlayıcısı. Timer

Benim Adaptör sınıfı

public class BuyListingListAdapter extends BaseAdapter { 

private Context mContext; 
private ArrayList<VehicleAttributes> mVehicleList = new ArrayList<VehicleAttributes>(); 
private Date currentDate; 
//Saving position in map to check if timer has been //started for this row 
private HashMap<Integer, Boolean> timerMap = new HashMap<Integer, Boolean>(); 

public BuyListingListAdapter(Context context, 
     ArrayList<VehicleAttributes> vehicleList, boolean showGridView) { 
    this.mContext = context; 
    this.mVehicleList = vehicleList; 
    this.showGridView = showGridView; 
    currentDate = new Date(System.currentTimeMillis()); 

    int listSize = mVehicleList.size(); 
    for (int i = 0; i < listSize; i++) 
     timerMap.put(i, false); 
} 

@Override 
public int getCount() { 
    return mVehicleList.size(); 
} 

@Override 
public Object getItem(int position) { 
    return mVehicleList.get(position); 
} 

@Override 
public long getItemId(int position) { 
    return 0; 
} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    if (convertView == null) { 
     LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
     convertView = inflater.inflate(R.layout.row_buy_listing_grid, 
        parent, false); 
     holder = new ViewHolder(); 
        holder.timer_layout = (LinearLayout) convertView 
       .findViewById(R.id.timer_layout); 
        holder.txt_remaining_days = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_days); 
     holder.txt_remaining_hours = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_hours); 
     holder.txt_remaining_mins = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_mins); 
     holder.txt_remaining_secs = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_secs); 
     holder.listing_status = (ImageView) convertView 
       .findViewById(R.id.listing_status); 

     convertView.setTag(holder); 
    } else 
     holder = (ViewHolder) convertView.getTag(); 

    final VehicleAttributes vehicleAttributes = mVehicleList.get(position); 

    AuctionModel mAuctionModel = vehicleAttributes.getAuctionDetailModel(); 
    if (mAuctionModel != null) { 
     holder.img_auction.setVisibility(View.VISIBLE); 

     Date auctionStartDate = Util 
       .getDateFromString(mAuctionModel.getStarted_at(), 
         "yyyy-MM-dd hh:mm:ss", "GMT"); 
     Date auctionEndDate = Util.getDateFromString(
       mAuctionModel.getEnded_at(), "yyyy-MM-dd hh:mm:ss", "GMT"); 
     long diff = currentDate.getTime() - auctionEndDate.getTime(); 

     if (diff < 0) 
      diff = -diff; 
     else 
      diff = 0; 

     if (timerMap.get(position) == null || !timerMap.get(position)) { 

      timerMap.put(position, true); 
      MyCountDown countDown = new MyCountDown(position, diff, 1000, 
        holder.txt_remaining_days, holder.txt_remaining_hours, 
        holder.txt_remaining_mins, holder.txt_remaining_secs); 
      countDown.start(); 
     } 
    } 
    return convertView; 
} 

private class MyCountDown extends CountDownTimer { 
    RobotoCondensedBoldTextView txt_remaining_days; 
    RobotoCondensedBoldTextView txt_remaining_hours; 
    RobotoCondensedBoldTextView txt_remaining_mins; 
    RobotoCondensedBoldTextView txt_remaining_secs; 
    int position; 

    public MyCountDown(int position, long millisInFuture, long countDownInterval, 
      RobotoCondensedBoldTextView txt_remaining_days, 
      RobotoCondensedBoldTextView txt_remaining_hours, 
      RobotoCondensedBoldTextView txt_remaining_mins, 
      RobotoCondensedBoldTextView txt_remaining_secs) { 
     super(millisInFuture, countDownInterval); 
     this.position = position; 
     this.txt_remaining_days = txt_remaining_days; 
     this.txt_remaining_hours = txt_remaining_hours; 
     this.txt_remaining_mins = txt_remaining_mins; 
     this.txt_remaining_secs = txt_remaining_secs; 
    } 

    @Override 
    public void onFinish() { 

    } 

    @Override 
    public void onTick(long millisUntilFinished) { 
     updateTimerLabel(position, millisUntilFinished, txt_remaining_days, 
       txt_remaining_hours, txt_remaining_mins, txt_remaining_secs); 
    } 
} 

private void updateTimerLabel(int position, long millis, 
     RobotoCondensedBoldTextView txt_remaining_days, 
     RobotoCondensedBoldTextView txt_remaining_hours, 
     RobotoCondensedBoldTextView txt_remaining_mins, 
     RobotoCondensedBoldTextView txt_remaining_secs) { 
    String days = String.format("%02d", 
      TimeUnit.MILLISECONDS.toDays(millis)); 
    String hours = String.format(
      "%02d", 
      TimeUnit.MILLISECONDS.toHours(millis) 
        - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS 
          .toDays(millis))); 
    String mins = String.format(
      "%02d", 
      TimeUnit.MILLISECONDS.toMinutes(millis) 
        - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS 
          .toHours(millis))); 
    String secs = String.format(
      "%02d", 
      TimeUnit.MILLISECONDS.toSeconds(millis) 
        - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS 
          .toMinutes(millis))); 

    txt_remaining_days.setText(days); 
    txt_remaining_hours.setText(hours); 
    txt_remaining_mins.setText(mins); 
    txt_remaining_secs.setText(secs); 
} 

static class ViewHolder { 
    NetworkImageView mVehicleImage; 
    RobotoCondensedBoldTextView txt_remaining_days, txt_remaining_hours, 
      txt_remaining_mins, txt_remaining_secs; 
    LinearLayout timer_layout; 
} 
} 
+0

Bir sorun, bunun bir kısmını özlediyseniz, if (mAuctionModel! = Null) { – Amsheer

+0

@Amsheer Kodumu uyarladım ve yalnızca alakalı olanı gösterdim. Ayrıca, zamanlayıcı sadece bu model mevcutsa görünecektir – Nitish

+0

bunu birden fazla cihazda/Android sürümlerinde test ettiniz mi? – bernlim

cevap

1

GÜNCELLEME bir göz: (o kullandığı recyclerview ile cardview ama aynı prensip liste görünümü için de uygulanabilir) How to change text based on time and date?

Sen oluştururken bakmak zorunda countdowntimer örneği ve bunu iptal ettiğinizde. Zamanlayıcıyı iptal etmezseniz yanlış görünümleri günceller.

2
Sen kasıtsız girişimi engellemek için iki parça halinde sizin listview ve sayaçlar ayıran edilmelidir

. Android böyle bir uygulama için tasarlanmamıştır.

fragmanlar gitmek yoludur: http://developer.android.com/guide/components/fragments.html

Düzenleme: davanızı için, sonra sadece liste görünümü öğeleri listelemek, her liste öğesi için zamanlayıcı ayrı bir veritabanı çalıştırabilirsiniz. Bir kullanıcının zamanlamayı bilmesi gerektiğinde, veritabanını geçerli bir süre için çağıran liste listenizi tıklarlar. Bu güncel saat, liste listesinde gösterilir. Bu canlı değil, bu yüzden zaman değişmeyecek. Bunu yapmak titreklik problemini önleyecektir.

+0

Her bir liste görünümü öğesinde zamanlayıcı göstermem gerekir.Bu nasıl bu sorunu çözdü – Nitish

+0

Tamam.Ben özel bir endişe – bernlim

3

Tamam biz sadece 6 madde listesi liste görünümünde görünür bir liste yüklediğinizde liste görünümünde yukarıdaki kod örneğin bileşenleri için öğeyi yeniden kullanılacaktır

if (convertView == null) { 
     LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
     convertView = inflater.inflate(R.layout.row_buy_listing_grid, 
        parent, false); 
     holder = new ViewHolder(); 
        holder.timer_layout = (LinearLayout) convertView 
       .findViewById(R.id.timer_layout); 
        holder.txt_remaining_days = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_days); 
     holder.txt_remaining_hours = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_hours); 
     holder.txt_remaining_mins = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_mins); 
     holder.txt_remaining_secs = (RobotoCondensedBoldTextView) convertView 
       .findViewById(R.id.txt_remaining_secs); 
     holder.listing_status = (ImageView) convertView 
       .findViewById(R.id.listing_status); 

     convertView.setTag(holder); 
    } else 
     holder = (ViewHolder) convertView.getTag(); 

ilk sorun hakkında konuşalım Bu öğeleri oluşturun, ancak yeni öğe oluşturmak yerine yukarı ve aşağı kaydırdığınızda, sonraki konumlar için aynı görünümü yeniden kullanacaksınız, böylece aynı görünümleri güncellemek için countDown zamanlayıcıya geçiş yaptığınızda farklı geri sayım sayacı

Şimdi çözümün ne olacağı, dağınıklık üzerinde hangi madde görünümlerinin görülebildiğini anlamanız gerekiyor. n ve diğer görünümler için geri sayım zamanlayıcısını durdurun. ya da orada çok basit bir yoludur, ancak hafıza sorunu

LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
    convertView = inflater.inflate(R.layout.row_buy_listing_grid, 
       parent, false); 
    holder = new ViewHolder(); 
       holder.timer_layout = (LinearLayout) convertView 
      .findViewById(R.id.timer_layout); 
       holder.txt_remaining_days = (RobotoCondensedBoldTextView) convertView 
      .findViewById(R.id.txt_remaining_days); 
    holder.txt_remaining_hours = (RobotoCondensedBoldTextView) convertView 
      .findViewById(R.id.txt_remaining_hours); 
    holder.txt_remaining_mins = (RobotoCondensedBoldTextView) convertView 
      .findViewById(R.id.txt_remaining_mins); 
    holder.txt_remaining_secs = (RobotoCondensedBoldTextView) convertView 
      .findViewById(R.id.txt_remaining_secs); 
    holder.listing_status = (ImageView) convertView 
      .findViewById(R.id.listing_status); 

    convertView.setTag(holder); 

Basit kaldır if(convertview==null) neden olabilir ve her satır için yeni bir görünüm şişirme izin verebilir çünkü önerilmez. Burada cevabımı güncellenmiş

+1

bu Şimdi" Ben bu açıklamayı yazdım sadece bu nedenle – trpride

+0

Evet ve know ekranın görüntüleme alanının bakımından sınırlı görüşlerini geri dönüşüm ViewHolder' desen' bütün mesele decimates için yukarıda oluşturulmamıştır var çözüm ne olacağını, sen öğesi görünümlerini ekranda görünür olan onu anlamaya ve diğer görünümler için geri sayım sayacı durdurmak zorundayız. ya da "orada çok basit bir yoludur, ancak hafıza soruna neden olabileceğinden önerilmez –