2015-06-19 18 views
7

Trong ứng dụng của tôi, tôi phải hiển thị đồng hồ đếm ngược cho mọi mục trong chế độ xem danh sách. Tôi đã có thể thực hiện việc này bằng cách sử dụng CountDownTimer. Nhưng, vấn đề là khi di chuyển listview lên hoặc xuống, bộ đếm thời gian bắt đầu nhấp nháy. Đã tìm kiếm rất nhiều nhưng không thể có giải pháp.ListView với bộ hẹn giờ Coundown. Hẹn giờ nhấp nháy khi cuộn danh sách xem

lớp Adaptor My

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

Một vấn đề bạn bỏ lỡ phần khác của điều này nếu (mAuctionModel! = Null) { – Amsheer

+0

@Amsheer Tôi đã điều chỉnh mã của mình và chỉ hiển thị những gì có liên quan. Đồng thời, bộ hẹn giờ sẽ chỉ hiển thị nếu mô hình này có mặt là – Nitish

+0

bạn đã thử nghiệm tính năng này trên nhiều thiết bị/phiên bản Android chưa? – bernlim

Trả lời

1

CẬP NHẬT

tôi cập nhật câu trả lời của tôi ở đây có một cái nhìn: (nó sử dụng của cardview với recyclerview nhưng nguyên tắc tương tự có thể được áp dụng cũng cho listview) How to change text based on time and date?

Bạn phải chăm sóc khi bạn tạo ví dụ countdowntimer và khi bạn hủy nó. Nếu bạn không hủy hẹn giờ, nó sẽ cập nhật các giao diện sai.

2

Bạn nên tách listview và bộ đếm ngược giờ thành hai mảnh để tránh sự can thiệp không chủ ý. Android không được thiết kế để thực hiện như vậy.

Những mảnh vỡ là con đường để đi: http://developer.android.com/guide/components/fragments.html

Edit: Đối với trường hợp của bạn, bạn có thể chạy một cơ sở dữ liệu riêng biệt của tính giờ cho mỗi mục trong danh sách, sau đó chỉ cần liệt kê các mục của bạn trong listview của bạn. Khi người dùng cần biết thời gian, họ bấm vào listitem của bạn, mà gọi cơ sở dữ liệu cho một thời gian hiện tại. Thời gian hiện tại sau đó được hiển thị trên danh sách. Điều này là KHÔNG sống nên thời gian sẽ không thay đổi. Làm như vậy sẽ tránh được vấn đề nhấp nháy.

+0

Tôi phải hiển thị bộ đếm thời gian trong mỗi mục listview. Không có cách giải quyết vấn đề này ? – Nitish

+0

Ok tôi hiểu rồi.Tôi đã xây dựng ở trên cho mối quan tâm cụ thể của bạn – bernlim

3

Ok cho phép nói về vấn đề đầu tiên

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(); 

Đoạn mã trên trong giao diện danh sách sẽ tái sử dụng các mục cho các thành phần, ví dụ như khi chúng ta tải một danh sách chỉ có 6 mặt hàng được xuất hiện trên danh sách, xem danh sách tạo các mục này nhưng khi bạn cuộn lên và xuống thay vì tạo mục mới, nó sẽ sử dụng lại chế độ xem tương tự cho các vị trí tiếp theo, vì vậy khi bạn chuyển chế độ xem của mình sang bộ đếm giờ được đếm để cập nhật thời gian xem cùng cập nhật với bộ đếm ngược khác nhau

Bây giờ, giải pháp là gì, bạn phải tìm ra giải pháp nào có thể nhìn thấy trên màn hình n và dừng đồng hồ đếm ngược cho các chế độ xem khác. hoặc có một cách rất đơn giản nhưng không được khuyến khích vì nó có thể gây ra vấn đề bộ nhớ

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); 

đơn giản loại bỏ if(convertview==null) và cho phép lạm phát một cái nhìn mới cho mỗi hàng.

+1

này decimates toàn bộ vấn đề của 'mẫu ViewHolder' tái chế các quan điểm hạn chế đối với các vùng hiển thị của màn hình của bạn – trpride

+0

Có, tôi biết và chỉ vì điều này tôi đã viết bản Tuyên Bố này "Bây giờ những gì sẽ là giải pháp, bạn phải tìm hiểu xem các mục nhìn thấy được hiển thị trên màn hình và dừng bộ đếm thời gian đếm ngược cho các chế độ xem khác hoặc có một cách rất đơn giản nhưng không được khuyến nghị vì nó có thể gây ra vấn đề về bộ nhớ " –