2013-11-28 49 views
9

Listemde bir sorun var, tüm ListView öğelerine bir geri sayım sayacı ayarlamak istiyorum ve bunun için zaten bir çözüm googledim, ancak doğru çalışmıyor. Sorun, ListView'in bir görünümü yeniden kullanmasıdır (geri dönüşüm) ve her zaman yanlış bir öğe zamanı elde ederim. Görünümüm için bir etiket kullanıyorum, ancak hala çalışmıyor, nerede hata yaptığımı anlayamıyorum, lütfen bana yardım edin. Teşekkürler.ListView ve geri sayım sayacı olan öğeler

Burada sorunumu gösteren bir fotoğraf var: pic1 Yeni bir Faaliyet başlattığım yer; startActivity

ben sadece aşağı kaydırıldığında ettik pic2 ve buraya

listWithError

Ve kodu (bütün sınıf):

public class PromoListActivity extends SherlockActivity { 
private ListView mPromoList; 
private PromoListAdapter mAdapter; 
private ViewFlipper mFlipper; 
private Button mBtnRepeat; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.fragment_news_list); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    setTitle("Сохранённые акции"); 
    mFlipper = (ViewFlipper) findViewById(R.id.flipper); 
    mPromoList = (ListView) findViewById(R.id.newsList); 
    mBtnRepeat = (Button) findViewById(R.id.btnRepeat); 

    //--> 
    final Handler timerHandler = new Handler(); 
    Runnable timerRunnable = new Runnable() { 
     @Override 
     public void run() { 
      mAdapter.notifyDataSetChanged(); 
      timerHandler.postDelayed(this, 1000); // run every minute 
     } 
    }; 
    //<-- 


    mBtnRepeat.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View arg0) { 
      mFlipper.setDisplayedChild(0); 
      getDummyData(); 
     } 
    }); 
    mPromoList.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
      startActivity(new Intent(PromoListActivity.this, PromoActivityDetails.class)); 

     } 
    }); 
    getDummyData(); 
} 

private class PromoListAdapter extends BaseAdapter { 
    private ArrayList<PromoAction> mItems = new ArrayList<PromoAction>(); 
    private LayoutInflater layoutInflater; 

    private PromoListAdapter(Context context, ArrayList<PromoAction> mItems) { 
     layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     this.mItems = mItems; 
    } 

    public int getCount() { 
     return mItems.size(); 
    } 

    public PromoAction getItem(int position) { 
     return mItems.get(position); 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewItem viewItem; 
     PromoAction promoAction = getItem(position); 
     if (convertView == null) { 
      viewItem = new ViewItem(); 
      convertView = layoutInflater.inflate(R.layout.listviewitem_action, null); 
      viewItem.name = (TextView) convertView.findViewById(R.id.promoAction_name); 
      viewItem.desc = (TextView) convertView.findViewById(R.id.promoAction_desc); 
      viewItem.timer = (TextView) convertView.findViewById(R.id.promoAction_timer); 
      viewItem.timer.setTag(position); 
      convertView.setTag(viewItem); 
     } else { 
      viewItem = (ViewItem) convertView.getTag(); 
     } 
     setTime(promoAction,viewItem.timer,viewItem.timer.getTag().toString()); 
     viewItem.name.setText(promoAction.name); 
     viewItem.desc.setText(promoAction.descr); 
     return convertView; 
    } 

    private void setTime(final PromoAction promoAction, final TextView tv, final String tag) { 
     if (tv.getTag().toString().equals(tag)) { 
      long outputTime = Math.abs(promoAction.timer_end 
        - System.currentTimeMillis()); 
      Date date = new java.util.Date(outputTime); 
      String result = new SimpleDateFormat("hh:mm:ss").format(date); 
      tv.setText(result); 
     } 
    } 

    public class ViewItem { 
     TextView name; 
     TextView desc; 
     TextView timer; 
    } 
} 

private void getDummyData() { 
    ArrayList<PromoAction> list = new ArrayList<PromoAction>(); 
    for (int i = 1; i < 10; i++) { 
     PromoAction action = new PromoAction(); 
     action.name = "Lorem ipsum dolor sit amet"; 
     action.descr = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "; 
     switch (i) { 
     case 1: { 
      action.timer_start = 1385971000; 
      action.timer_end = 1386104000; 
     } 
     case 2: { 
      action.timer_start = 1385889000; 
      action.timer_end = 1385812550; 
      break; 
     } 
     case 3: { 
      action.timer_start = 1385884200; 
      action.timer_end = 1385912100; 
      break; 
     } 
     default: { 
      action.timer_start = 1385856000; 
      action.timer_end = 1385892000; 
      break; 
     } 
     } 
     list.add(action); 

    } 
    mAdapter = new PromoListAdapter(PromoListActivity.this, list); 
    mPromoList.setAdapter(mAdapter); 
    mFlipper.setDisplayedChild(1); 
} 

GÜNCELLEME}

cevap

10

Ben öyle Bunu benim durumumda farklı şekilde yaşadım. getView() içinde ayarlanmış bir zamanlayıcı işleyici yerine, her zaman getView() arandığında, geçerli saat ve istediğiniz zaman arasındaki zaman farkını TextView arasına ayarladım. Yani getView() içeri senin bu kodu taşıyın:

Handler timerHandler = new Handler(); 
Runnable timerRunnable = new Runnable() { 
    @Override 
    public void run() { 
     myAdapter.notifyDataSetChanged(); 
     timerHandler.postDelayed(this, 60000); //run every minute 
    } 
}; 

ben onPause() bu işleyici durdurmak:

long outputTime = Math.abs(promoAction.timer_end 
        - System.currentTimeMillis()); 
Date date = new java.util.Date(outputTime); 
String result = new SimpleDateFormat("hh:mm:ss").format(date); 
tv.setText(result); 

Sonra liste görünümü 's adaptör üzerinde her bir dakika notifyDatasetChanged() aramaya aktivitesinde bir işleyici oluşturmak

@Override 
protected void onPause() { 
    timerHandler.removeCallbacks(timerRunnable); 
    super.onPause(); 
} 

Ve onResume() tekrar başlatın:

Ve işte bu kadar. :)

Yardım edin.

+0

Bir zamanlamamın kendisi yoktu, kodumu gördüğünüz gibi, sadece sizin gibi notifyDataSetChanged() öğesini çağırmak için işleyiciyi kullanıyorum, neden listeview yanlış zamanlayıcıları çocuğuna ayarlamamış, neden olursa olsun teşekkürler Cevap – whizzzkey

+0

@whizzzkey Zamanlayıcı işleyicisini 'getView()' içinde yapıyorsunuz. Bunu yapma. İşe yarayıp yaramadığını görmek istediğim gibi yapmaya çalış. –

+0

Cevabımı güncelledim. Şimdi açık olup olmadığına bakın. –

1

Geridönüşüm görünümünü kullanabilirsiniz. Buradan İndir kaynak kodu()

activity_main.xml

<RelativeLayout android:layout_width="match_parent" 
android:layout_height="match_parent" 
xmlns:android="http://schemas.android.com/apk/res/android"> 

<android.support.v7.widget.RecyclerView 
android:id="@+id/recycler_view" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:scrollbars="vertical" /> 

</RelativeLayout> 

MainActivity.java

package com.androidsolutionworld.multipletimer; 

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.widget.LinearLayout; 

import java.util.ArrayList; 

public class MainActivity extends AppCompatActivity { 
    private RecyclerView recyclerView; 
    private ArrayList al_data = new ArrayList<>(); 
    private Adapter obj_adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     recyclerView = (RecyclerView)findViewById(R.id.recycler_view); 
     al_data.add("1234"); 
     al_data.add("1257"); 
     al_data.add("100"); 
     al_data.add("1547"); 
     al_data.add("200"); 
     al_data.add("500"); 
     al_data.add("2000"); 
     al_data.add("1000"); 

     obj_adapter = new Adapter(al_data); 
     LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.VERTICAL,false); 
     recyclerView.setLayoutManager(layoutManager); 
     recyclerView.setAdapter(obj_adapter); 
    } 
} 

adapter_layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textSize="15dp" 
     android:padding="10dp" 
     android:id="@+id/tv_timer"/> 

</LinearLayout> 

Özel Adaptörü:

package com.androidsolutionworld.multipletimer; 


import android.os.CountDownTimer; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import java.util.ArrayList; 

public class Adapter extends RecyclerView.Adapter{ 

    private ArrayList al_data; 

    public class MyViewHolder extends RecyclerView.ViewHolder{ 
     public TextView tv_timer; 
     CountDownTimer timer; 

     public MyViewHolder (View view){ 
      super(view); 
      tv_timer = (TextView)view.findViewById(R.id.tv_timer); 

     } 


    } 

    public Adapter(ArrayList al_data) { 
     this.al_data = al_data; 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout,parent,false); 


     return new MyViewHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(final MyViewHolder holder, int position) { 

     holder.tv_timer.setText(al_data.get(position)); 

     if (holder.timer != null) { 
      holder.timer.cancel(); 
     } 
     long timer = Long.parseLong(al_data.get(position)); 

     timer = timer*1000; 

     holder.timer = new CountDownTimer(timer, 1000) { 
      public void onTick(long millisUntilFinished) { 
       holder.tv_timer.setText("" + millisUntilFinished/1000 + " Sec"); 
      } 

      public void onFinish() { 
       holder.tv_timer.setText("00:00:00"); 
      } 
     }.start(); 


    } 

    @Override 
    public int getItemCount() { 
     return al_data.size(); 
    } 



} 

teşekkürler!